public ReactionResult React(GasMixture mixture, IGasMixtureHolder?holder, AtmosphereSystem atmosphereSystem) { // If any of the prototypes is invalid, we do nothing. if (string.IsNullOrEmpty(Reagent) || string.IsNullOrEmpty(PuddlePrototype)) { return(ReactionResult.NoReaction); } // If we're not reacting on a tile, do nothing. if (holder is not TileAtmosphere tile) { return(ReactionResult.NoReaction); } // If we don't have enough moles of the specified gas, do nothing. if (mixture.GetMoles(GasId) < MolesPerUnit) { return(ReactionResult.NoReaction); } // Remove the moles from the mixture... mixture.AdjustMoles(GasId, -MolesPerUnit); var tileRef = tile.GridIndices.GetTileRef(tile.GridIndex); EntitySystem.Get <SpillableSystem>() .SpillAt(tileRef, new Solution(Reagent, FixedPoint2.New(MolesPerUnit)), PuddlePrototype, sound: false); return(ReactionResult.Reacting); }
public void UpdateReagents() { var solutionSystem = EntitySystem.Get <SolutionContainerSystem>(); if (!solutionSystem.TryGetSolution(Owner, SoilSolutionName, out var solution)) { return; } if (solution.TotalVolume <= 0 || MutationLevel >= 25) { if (MutationLevel >= 0) { Mutate(Math.Min(MutationLevel, 25)); MutationLevel = 0; } } else { var amt = FixedPoint2.New(1); foreach (var reagent in solutionSystem.RemoveEachReagent(Owner, solution, amt)) { var reagentProto = _prototypeManager.Index <ReagentPrototype>(reagent); reagentProto.ReactionPlant(Owner, new Solution.ReagentQuantity(reagent, amt), solution); } } CheckLevelSanity(); }
public void ProduceGrown(EntityUid uid, ProduceComponent produce) { if (!TryGetSeed(produce, out var seed)) { return; } if (TryComp(uid, out SpriteComponent? sprite)) { sprite.LayerSetRSI(0, seed.PlantRsi); sprite.LayerSetState(0, seed.PlantIconState); } var solutionContainer = _solutionContainerSystem.EnsureSolution(uid, produce.SolutionName); solutionContainer.RemoveAllSolution(); foreach (var(chem, quantity) in seed.Chemicals) { var amount = FixedPoint2.New(quantity.Min); if (quantity.PotencyDivisor > 0 && seed.Potency > 0) { amount += FixedPoint2.New(seed.Potency / quantity.PotencyDivisor); } amount = FixedPoint2.New((int)MathHelper.Clamp(amount.Float(), quantity.Min, quantity.Max)); solutionContainer.MaxVolume += amount; solutionContainer.AddReagent(chem, amount); } }
public async Task TilePuddleTest() { await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true }); var server = pairTracker.Pair.Server; var testMap = await PoolManager.CreateTestMap(pairTracker); var entitySystemManager = server.ResolveDependency <IEntitySystemManager>(); var spillSystem = entitySystemManager.GetEntitySystem <SpillableSystem>(); await server.WaitAssertion(() => { var solution = new Solution("Water", FixedPoint2.New(20)); var tile = testMap.Tile; var gridUid = tile.GridUid; var(x, y) = tile.GridIndices; var coordinates = new EntityCoordinates(gridUid, x, y); var puddle = spillSystem.SpillAt(solution, coordinates, "PuddleSmear"); Assert.NotNull(puddle); }); await PoolManager.RunTicksSync(pairTracker.Pair, 5); await pairTracker.CleanReturnAsync(); }
public void AddLessThanZeroReagentReturnsZero() { var solution = new Solution("water", FixedPoint2.New(-1000)); var quantity = solution.GetReagentQuantity("water"); Assert.That(quantity.Int(), Is.EqualTo(0)); }
public async Task TryMixAndOverflowTooBigOverflow() { await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true, ExtraPrototypes = Prototypes }); var server = pairTracker.Pair.Server; var entityManager = server.ResolveDependency <IEntityManager>(); var testMap = await PoolManager.CreateTestMap(pairTracker); var coordinates = testMap.GridCoords; EntityUid beaker; await server.WaitAssertion(() => { int ratio = 9; int threshold = 60; var waterQuantity = FixedPoint2.New(10); var oilQuantity = FixedPoint2.New(ratio *waterQuantity.Int()); var oilAdded = new Solution("Oil", oilQuantity); var originalWater = new Solution("Water", waterQuantity); beaker = entityManager.SpawnEntity("SolutionTarget", coordinates); Assert.That(EntitySystem.Get <SolutionContainerSystem>() .TryGetSolution(beaker, "beaker", out var solution)); solution.AddSolution(originalWater); Assert.That(EntitySystem.Get <SolutionContainerSystem>() .TryMixAndOverflow(beaker, solution, oilAdded, threshold, out _), Is.False); }); await pairTracker.CleanReturnAsync(); }
public void ConstructorAddReagent() { var solution = new Solution("water", FixedPoint2.New(1000)); var quantity = solution.GetReagentQuantity("water"); Assert.That(quantity.Int(), Is.EqualTo(1000)); }
public async Task SpaceNoPuddleTest() { var server = StartServer(); await server.WaitIdleAsync(); var mapManager = server.ResolveDependency <IMapManager>(); var entitySystemManager = server.ResolveDependency <IEntitySystemManager>(); var spillSystem = entitySystemManager.GetEntitySystem <SpillableSystem>(); IMapGrid grid = null; // Remove all tiles server.Post(() => { grid = GetMainGrid(mapManager); foreach (var tile in grid.GetAllTiles()) { grid.SetTile(tile.GridIndices, Tile.Empty); } }); await server.WaitIdleAsync(); server.Assert(() => { var coordinates = grid.ToCoordinates(); var solution = new Solution("Water", FixedPoint2.New(20)); var puddle = spillSystem.SpillAt(solution, coordinates, "PuddleSmear"); Assert.Null(puddle); }); await server.WaitIdleAsync(); }
public void FixedPoint2Equals(int a, int b, bool expected) { var parameter = FixedPoint2.New(a); var comparison = FixedPoint2.New(b); Assert.That(parameter.Equals(comparison), Is.EqualTo(comparison.Equals(parameter))); Assert.That(comparison.Equals(parameter), Is.EqualTo(expected)); }
public void TotalVolumeIsCorrect() { var solution = new Solution(); solution.AddReagent("water", FixedPoint2.New(1000)); solution.AddReagent("fire", FixedPoint2.New(2000)); Assert.That(solution.TotalVolume.Int(), Is.EqualTo(3000)); }
public void RemoveSolutionLessThanOneDoesNothing() { var solution = new Solution("water", FixedPoint2.New(800)); solution.RemoveSolution(FixedPoint2.New(-200)); Assert.That(solution.GetReagentQuantity("water").Int(), Is.EqualTo(800)); Assert.That(solution.TotalVolume.Int(), Is.EqualTo(800)); }
public void RemoveNonExistReagentDoesNothing() { var solution = new Solution("water", FixedPoint2.New(100)); solution.RemoveReagent("fire", FixedPoint2.New(1000)); Assert.That(solution.GetReagentQuantity("water").Int(), Is.EqualTo(100)); Assert.That(solution.TotalVolume.Int(), Is.EqualTo(100)); }
public void RemoveMoreThanTotalRemovesAllReagent() { var solution = new Solution("water", FixedPoint2.New(100)); solution.RemoveReagent("water", FixedPoint2.New(1000)); Assert.That(solution.GetReagentQuantity("water").Int(), Is.EqualTo(0)); Assert.That(solution.TotalVolume.Int(), Is.EqualTo(0)); }
public void CalculusMultiplication(float aFloat, float bFloat, string expected) { var a = FixedPoint2.New(aFloat); var b = FixedPoint2.New(bFloat); var result = a * b; Assert.That($"{result}", Is.EqualTo(expected)); }
public void AddReagentToEmptySolutionSetsTemperature() { const float testTemp = 100.0f; var solution = new Solution(); solution.AddReagent("water", FixedPoint2.New(100), testTemp); Assert.That(solution.Temperature, Is.EqualTo(testTemp)); }
/// <summary> /// Will overflow this entity to neighboring entities if required /// </summary> private void CheckOverflow(PuddleComponent puddleComponent) { if (puddleComponent.CurrentVolume <= puddleComponent.OverflowVolume || puddleComponent.Overflown) { return; } var nextPuddles = new List <PuddleComponent>() { puddleComponent }; var overflownPuddles = new List <PuddleComponent>(); while (puddleComponent.OverflowLeft > FixedPoint2.Zero && nextPuddles.Count > 0) { foreach (var next in nextPuddles.ToArray()) { nextPuddles.Remove(next); next.Overflown = true; overflownPuddles.Add(next); var adjacentPuddles = GetAllAdjacentOverflow(next).ToArray(); if (puddleComponent.OverflowLeft <= FixedPoint2.Epsilon * adjacentPuddles.Length) { break; } if (adjacentPuddles.Length == 0) { continue; } var numberOfAdjacent = FixedPoint2.New(adjacentPuddles.Length); var overflowSplit = puddleComponent.OverflowLeft / numberOfAdjacent; foreach (var adjacent in adjacentPuddles) { var adjacentPuddle = adjacent(); var quantity = FixedPoint2.Min(overflowSplit, adjacentPuddle.OverflowVolume); var puddleSolution = _solutionContainerSystem.EnsureSolution(puddleComponent.Owner, puddleComponent.SolutionName); var spillAmount = _solutionContainerSystem.SplitSolution(puddleComponent.Owner, puddleSolution, quantity); TryAddSolution(adjacentPuddle.Owner, spillAmount, false, false); nextPuddles.Add(adjacentPuddle); } } } foreach (var puddle in overflownPuddles) { puddle.Overflown = false; } }
public void AddingReagentsSumsProperly() { var solution = new Solution(); solution.AddReagent("water", FixedPoint2.New(1000)); solution.AddReagent("water", FixedPoint2.New(2000)); var quantity = solution.GetReagentQuantity("water"); Assert.That(quantity.Int(), Is.EqualTo(3000)); }
public void RemoveSolutionMoreThanTotalRemovesAll() { var solution = new Solution("water", FixedPoint2.New(800)); solution.RemoveSolution(FixedPoint2.New(1000)); //Check that edited solution is correct Assert.That(solution.GetReagentQuantity("water").Int(), Is.EqualTo(0)); Assert.That(solution.TotalVolume.Int(), Is.EqualTo(0)); }
public void ReagentQuantitiesStayUnique() { var solution = new Solution(); solution.AddReagent("water", FixedPoint2.New(1000)); solution.AddReagent("fire", FixedPoint2.New(2000)); Assert.That(solution.GetReagentQuantity("water").Int(), Is.EqualTo(1000)); Assert.That(solution.GetReagentQuantity("fire").Int(), Is.EqualTo(2000)); }
public void SplitSolutionDoesNotEffectTemperature() { const float initialTemp = 100.0f; var solution = new Solution(); solution.AddReagent("water", FixedPoint2.New(100), initialTemp); solution.SplitSolution(FixedPoint2.New(50)); Assert.That(solution.Temperature, Is.EqualTo(initialTemp)); }
public void SplitSolutionMoreThanTotalRemovesAll() { var solution = new Solution("water", FixedPoint2.New(800)); var splitSolution = solution.SplitSolution(FixedPoint2.New(1000)); Assert.That(solution.GetReagentQuantity("water").Int(), Is.EqualTo(0)); Assert.That(solution.TotalVolume.Int(), Is.EqualTo(0)); Assert.That(splitSolution.GetReagentQuantity("water").Int(), Is.EqualTo(800)); Assert.That(splitSolution.TotalVolume.Int(), Is.EqualTo(800)); }
public void RemoveSolutionRecalculatesProperly() { var solution = new Solution(); solution.AddReagent("water", FixedPoint2.New(1000)); solution.AddReagent("fire", FixedPoint2.New(2000)); solution.RemoveReagent("water", FixedPoint2.New(500)); Assert.That(solution.GetReagentQuantity("water").Int(), Is.EqualTo(500)); Assert.That(solution.GetReagentQuantity("fire").Int(), Is.EqualTo(2000)); Assert.That(solution.TotalVolume.Int(), Is.EqualTo(2500)); }
public void RemoveSolutionRatioPreserved() { var solution = new Solution(); solution.AddReagent("water", FixedPoint2.New(1000)); solution.AddReagent("fire", FixedPoint2.New(2000)); solution.RemoveSolution(FixedPoint2.New(1500)); Assert.That(solution.GetReagentQuantity("water").Int(), Is.EqualTo(500)); Assert.That(solution.GetReagentQuantity("fire").Int(), Is.EqualTo(1000)); Assert.That(solution.TotalVolume.Int(), Is.EqualTo(1500)); }
public void SplitRounding(int amount) { var solutionOne = new Solution(); solutionOne.AddReagent("foo", FixedPoint2.New(amount)); solutionOne.AddReagent("bar", FixedPoint2.New(amount)); solutionOne.AddReagent("baz", FixedPoint2.New(amount)); var splitAmount = FixedPoint2.New(5); var split = solutionOne.SplitSolution(splitAmount); Assert.That(split.TotalVolume, Is.EqualTo(splitAmount)); }
public void CloningSolutionIsCorrect() { var solution = new Solution(); solution.AddReagent("water", FixedPoint2.New(1000)); solution.AddReagent("fire", FixedPoint2.New(2000)); var newSolution = solution.Clone(); Assert.That(newSolution.GetReagentQuantity("water").Int(), Is.EqualTo(1000)); Assert.That(newSolution.GetReagentQuantity("fire").Int(), Is.EqualTo(2000)); Assert.That(newSolution.TotalVolume.Int(), Is.EqualTo(3000)); }
public async Task RejuvenateDeadTest() { await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true, ExtraPrototypes = Prototypes }); var server = pairTracker.Pair.Server; var entManager = server.ResolveDependency <IEntityManager>(); var mapManager = server.ResolveDependency <IMapManager>(); var prototypeManager = server.ResolveDependency <IPrototypeManager>(); var mobStateSystem = entManager.EntitySysManager.GetEntitySystem <Server.MobState.MobStateSystem>(); var damSystem = entManager.EntitySysManager.GetEntitySystem <DamageableSystem>(); await server.WaitAssertion(() => { mapManager.CreateNewMapEntity(MapId.Nullspace); var human = entManager.SpawnEntity("DamageableDummy", MapCoordinates.Nullspace); // Sanity check Assert.True(entManager.TryGetComponent(human, out DamageableComponent damageable)); Assert.True(entManager.TryGetComponent(human, out MobStateComponent mobState)); Assert.That(mobStateSystem.IsAlive(human, mobState), Is.True); Assert.That(mobStateSystem.IsCritical(human, mobState), Is.False); Assert.That(mobStateSystem.IsDead(human, mobState), Is.False); Assert.That(mobStateSystem.IsIncapacitated(human, mobState), Is.False); // Kill the entity DamageSpecifier damage = new(prototypeManager.Index <DamageGroupPrototype>("Toxin"), FixedPoint2.New(10000000)); damSystem.TryChangeDamage(human, damage, true); // Check that it is dead Assert.That(mobStateSystem.IsAlive(human, mobState), Is.False); Assert.That(mobStateSystem.IsCritical(human, mobState), Is.False); Assert.That(mobStateSystem.IsDead(human, mobState), Is.True); Assert.That(mobStateSystem.IsIncapacitated(human, mobState), Is.True); // Rejuvenate them RejuvenateCommand.PerformRejuvenate(human); // Check that it is alive and with no damage Assert.That(mobStateSystem.IsAlive(human, mobState), Is.True); Assert.That(mobStateSystem.IsCritical(human, mobState), Is.False); Assert.That(mobStateSystem.IsDead(human, mobState), Is.False); Assert.That(mobStateSystem.IsIncapacitated(human, mobState), Is.False); Assert.That(damageable.TotalDamage, Is.EqualTo(FixedPoint2.Zero)); }); await pairTracker.CleanReturnAsync(); }
public override void Update(float frameTime) { base.Update(frameTime); var queueDelete = new RemQueue <EvaporationComponent>(); foreach (var evaporationComponent in EntityManager.EntityQuery <EvaporationComponent>()) { var uid = evaporationComponent.Owner; evaporationComponent.Accumulator += frameTime; if (!_solutionContainerSystem.TryGetSolution(uid, evaporationComponent.SolutionName, out var solution)) { // If no solution, delete the entity EntityManager.QueueDeleteEntity(uid); continue; } if (evaporationComponent.Accumulator < evaporationComponent.EvaporateTime) { continue; } evaporationComponent.Accumulator -= evaporationComponent.EvaporateTime; if (evaporationComponent.EvaporationToggle == true) { _solutionContainerSystem.SplitSolution(uid, solution, FixedPoint2.Min(FixedPoint2.New(1), solution.CurrentVolume)); // removes 1 unit, or solution current volume, whichever is lower. } if (solution.CurrentVolume <= 0) { EntityManager.QueueDeleteEntity(uid); } else if (solution.CurrentVolume <= evaporationComponent.LowerLimit || // if puddle is too big or too small to evaporate. solution.CurrentVolume >= evaporationComponent.UpperLimit) { evaporationComponent.EvaporationToggle = false; // pause evaporation } else { evaporationComponent.EvaporationToggle = true; // unpause evaporation, e.g. if a puddle previously above evaporation UpperLimit was brought down below evaporation UpperLimit via mopping. } } foreach (var evaporationComponent in queueDelete) { EntityManager.RemoveComponent(evaporationComponent.Owner, evaporationComponent); } }
private void UpdateSlip(EntityUid entityUid, PuddleComponent puddleComponent) { if ((puddleComponent.SlipThreshold == FixedPoint2.New(-1) || puddleComponent.CurrentVolume < puddleComponent.SlipThreshold) && EntityManager.TryGetComponent(entityUid, out SlipperyComponent? oldSlippery)) { oldSlippery.Slippery = false; } else if (puddleComponent.CurrentVolume >= puddleComponent.SlipThreshold) { var newSlippery = EntityManager.EnsureComponent <SlipperyComponent>(entityUid); newSlippery.Slippery = true; } }
public void Execute(IConsoleShell shell, string argStr, string[] args) { if (args.Length < 4) { shell.WriteLine($"Not enough arguments.\n{Help}"); return; } if (!EntityUid.TryParse(args[0], out var uid)) { shell.WriteLine($"Invalid entity id."); return; } if (!IoCManager.Resolve <IEntityManager>().TryGetComponent(uid, out SolutionContainerManagerComponent man)) { shell.WriteLine($"Entity does not have any solutions."); return; } if (!man.Solutions.ContainsKey(args[1])) { var validSolutions = string.Join(", ", man.Solutions.Keys); shell.WriteLine($"Entity does not have a \"{args[1]}\" solution. Valid solutions are:\n{validSolutions}"); return; } var solution = man.Solutions[args[1]]; if (!IoCManager.Resolve <IPrototypeManager>().HasIndex <ReagentPrototype>(args[2])) { shell.WriteLine($"Unknown reagent prototype"); return; } if (!float.TryParse(args[3], out var quantityFloat)) { shell.WriteLine($"Failed to parse quantity"); return; } var quantity = FixedPoint2.New(MathF.Abs(quantityFloat)); if (quantityFloat > 0) { EntitySystem.Get <SolutionContainerSystem>().TryAddReagent(uid, solution, args[2], quantity, out var _); } else { EntitySystem.Get <SolutionContainerSystem>().TryRemoveReagent(uid, solution, args[2], quantity); } }
private void UpdateSlip(EntityUid entityUid, PuddleComponent puddleComponent) { if ((puddleComponent.SlipThreshold == FixedPoint2.New(-1) || puddleComponent.CurrentVolume < puddleComponent.SlipThreshold) && TryComp(entityUid, out StepTriggerComponent? stepTrigger)) { _stepTrigger.SetActive(entityUid, false, stepTrigger); } else if (puddleComponent.CurrentVolume >= puddleComponent.SlipThreshold) { var comp = EnsureComp <StepTriggerComponent>(entityUid); _stepTrigger.SetActive(entityUid, true, comp); } }