コード例 #1
0
        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);
        }
コード例 #2
0
        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();
        }
コード例 #3
0
    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);
        }
    }
コード例 #4
0
        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();
        }
コード例 #5
0
    public void AddLessThanZeroReagentReturnsZero()
    {
        var solution = new Solution("water", FixedPoint2.New(-1000));
        var quantity = solution.GetReagentQuantity("water");

        Assert.That(quantity.Int(), Is.EqualTo(0));
    }
コード例 #6
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();
    }
コード例 #7
0
    public void ConstructorAddReagent()
    {
        var solution = new Solution("water", FixedPoint2.New(1000));
        var quantity = solution.GetReagentQuantity("water");

        Assert.That(quantity.Int(), Is.EqualTo(1000));
    }
コード例 #8
0
        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();
        }
コード例 #9
0
        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));
        }
コード例 #10
0
    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));
    }
コード例 #11
0
    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));
    }
コード例 #12
0
    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));
    }
コード例 #13
0
    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));
    }
コード例 #14
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));
        }
コード例 #15
0
    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));
    }
コード例 #16
0
        /// <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;
            }
        }
コード例 #17
0
    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));
    }
コード例 #18
0
    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));
    }
コード例 #19
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));
    }
コード例 #20
0
    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));
    }
コード例 #21
0
    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));
    }
コード例 #22
0
    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));
    }
コード例 #23
0
    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));
    }
コード例 #24
0
    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));
    }
コード例 #25
0
    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));
    }
コード例 #26
0
        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();
        }
コード例 #27
0
        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);
            }
        }
コード例 #28
0
 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;
     }
 }
コード例 #29
0
        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);
            }
        }
コード例 #30
0
 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);
     }
 }