示例#1
0
        private void OnDoAfterHandleState(EntityUid uid, DoAfterComponent component, ref ComponentHandleState args)
        {
            if (args.Current is not DoAfterComponentState state)
            {
                return;
            }

            var toRemove = new RemQueue <ClientDoAfter>();

            foreach (var(id, doAfter) in component.DoAfters)
            {
                var found = false;

                foreach (var clientdoAfter in state.DoAfters)
                {
                    if (clientdoAfter.ID == id)
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    toRemove.Add(doAfter);
                }
            }

            foreach (var doAfter in toRemove)
            {
                Remove(component, doAfter);
            }

            foreach (var doAfter in state.DoAfters)
            {
                if (component.DoAfters.ContainsKey(doAfter.ID))
                {
                    continue;
                }

                component.DoAfters.Add(doAfter.ID, doAfter);
            }

            if (component.Gui == null || component.Gui.Disposed)
            {
                return;
            }

            foreach (var(_, doAfter) in component.DoAfters)
            {
                component.Gui.AddDoAfter(doAfter);
            }
        }
        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);
            }
        }
示例#3
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
                    queueDelete.Add(evaporationComponent);
                    continue;
                }

                if (evaporationComponent.Accumulator < evaporationComponent.EvaporateTime)
                {
                    continue;
                }

                evaporationComponent.Accumulator -= evaporationComponent.EvaporateTime;


                _solutionContainerSystem.SplitSolution(uid, solution,
                                                       FixedPoint2.Min(FixedPoint2.New(1), solution.CurrentVolume));

                if (solution.CurrentVolume == 0)
                {
                    EntityManager.QueueDeleteEntity(uid);
                }
                else if (solution.CurrentVolume <= evaporationComponent.LowerLimit ||
                         solution.CurrentVolume >= evaporationComponent.UpperLimit)
                {
                    queueDelete.Add(evaporationComponent);
                }
            }

            foreach (var evaporationComponent in queueDelete)
            {
                EntityManager.RemoveComponent(evaporationComponent.Owner, evaporationComponent);
            }
        }
        public override void Update(float frameTime) //Responsible for actually playing the ringtone
        {
            var remove = new RemQueue <EntityUid>();

            foreach (var(_, ringer) in EntityManager.EntityQuery <ActiveRingerComponent, RingerComponent>())
            {
                ringer.TimeElapsed += frameTime;

                if (ringer.TimeElapsed < NoteDelay)
                {
                    continue;
                }

                ringer.TimeElapsed -= NoteDelay;
                var ringerXform = Transform(ringer.Owner);

                SoundSystem.Play(GetSound(ringer.Ringtone[ringer.NoteCount]),
                                 Filter.Empty().AddInRange(ringerXform.MapPosition, ringer.Range),
                                 ringer.Owner, AudioParams.Default.WithMaxDistance(ringer.Range).WithVolume(ringer.Volume));

                ringer.NoteCount++;

                if (ringer.NoteCount > 3)
                {
                    remove.Add(ringer.Owner);
                    UpdateRingerUserInterface(ringer);
                    ringer.TimeElapsed = 0;
                    ringer.NoteCount   = 0;
                    break;
                }
            }

            foreach (var ent in remove)
            {
                RemComp <ActiveRingerComponent>(ent);
            }
        }
示例#5
0
        public override void Update(float frameTime)
        {
            base.Update(frameTime);

            var toRemove = new RemQueue <PilotComponent>();

            foreach (var comp in EntityManager.EntityQuery <PilotComponent>())
            {
                if (comp.Console == null)
                {
                    continue;
                }

                if (!_blocker.CanInteract(comp.Owner, comp.Console.Owner))
                {
                    toRemove.Add(comp);
                }
            }

            foreach (var comp in toRemove)
            {
                RemovePilot(comp);
            }
        }
示例#6
0
        internal void RegenerateCollision(EntityUid gridEuid, MapChunk chunk, List <Box2i> rectangles)
        {
            if (!_enabled)
            {
                return;
            }

            DebugTools.Assert(chunk.FilledTiles > 0);

            if (!EntityManager.TryGetComponent(gridEuid, out PhysicsComponent? physicsComponent))
            {
                Logger.ErrorS("physics", $"Trying to regenerate collision for {gridEuid} that doesn't have {nameof(physicsComponent)}");
                return;
            }

            if (!EntityManager.TryGetComponent(gridEuid, out FixturesComponent? fixturesComponent))
            {
                Logger.ErrorS("physics", $"Trying to regenerate collision for {gridEuid} that doesn't have {nameof(fixturesComponent)}");
                return;
            }

            var origin = chunk.Indices * chunk.ChunkSize;

            // So we store a reference to the fixture on the chunk because it's easier to cross-reference it.
            // This is because when we get multiple fixtures per chunk there's no easy way to tell which the old one
            // corresponds with.
            // We also ideally want to avoid re-creating the fixture every time a tile changes and pushing that data
            // to the client hence we diff it.

            // Additionally, we need to handle map deserialization where content may have stored its own data
            // on the grid (e.g. mass) which we want to preserve.
            var newFixtures = new List <Fixture>();

            Span <Vector2> vertices = stackalloc Vector2[4];

            foreach (var rectangle in rectangles)
            {
                var bounds = ((Box2)rectangle.Translated(origin)).Enlarged(_fixtureEnlargement);
                var poly   = new PolygonShape();

                vertices[0] = bounds.BottomLeft;
                vertices[1] = bounds.BottomRight;
                vertices[2] = bounds.TopRight;
                vertices[3] = bounds.TopLeft;

                poly.SetVertices(vertices);

                var newFixture = new Fixture(
                    poly,
                    MapGridHelpers.CollisionGroup,
                    MapGridHelpers.CollisionGroup,
                    true)
                {
                    ID   = $"grid_chunk-{bounds.Left}-{bounds.Bottom}",
                    Body = physicsComponent
                };

                newFixtures.Add(newFixture);
            }

            var toRemove = new RemQueue <Fixture>();
            // Check if we even need to issue an eventbus event
            var updated = false;

            foreach (var oldFixture in chunk.Fixtures)
            {
                var existing = false;

                // Handle deleted / updated fixtures
                // (TODO: Check IDs and cross-reference for updates?)
                for (var i = newFixtures.Count - 1; i >= 0; i--)
                {
                    var fixture = newFixtures[i];
                    if (!oldFixture.Equals(fixture))
                    {
                        continue;
                    }
                    existing = true;
                    newFixtures.RemoveSwap(i);
                    break;
                }

                // Doesn't align with any new fixtures so delete
                if (existing)
                {
                    continue;
                }

                toRemove.Add(oldFixture);
            }

            foreach (var fixture in toRemove)
            {
                chunk.Fixtures.Remove(fixture);
                _fixtures.DestroyFixture(fixture, false, fixturesComponent);
            }

            if (newFixtures.Count > 0 || toRemove.List?.Count > 0)
            {
                updated = true;
            }

            // Anything remaining is a new fixture (or at least, may have not serialized onto the chunk yet).
            foreach (var fixture in newFixtures)
            {
                var existingFixture = _fixtures.GetFixtureOrNull(physicsComponent, fixture.ID);
                // Check if it's the same (otherwise remove anyway).
                if (existingFixture?.Shape is PolygonShape poly &&
                    poly.EqualsApprox((PolygonShape)fixture.Shape))
                {
                    chunk.Fixtures.Add(existingFixture);
                    continue;
                }

                chunk.Fixtures.Add(fixture);
                _fixtures.CreateFixture(physicsComponent, fixture, false, fixturesComponent);
            }

            if (updated)
            {
                _fixtures.FixtureUpdate(fixturesComponent, physicsComponent);
                EntityManager.EventBus.RaiseLocalEvent(gridEuid, new GridFixtureChangeEvent {
                    NewFixtures = chunk.Fixtures
                });
            }
        }
示例#7
0
        public override void Update(float frameTime)
        {
            foreach (var(stomach, mech, sol)
                     in EntityManager.EntityQuery <StomachComponent, MechanismComponent, SolutionContainerManagerComponent>(false))
            {
                if (mech.Body == null)
                {
                    continue;
                }

                stomach.AccumulatedFrameTime += frameTime;

                if (stomach.AccumulatedFrameTime < stomach.UpdateInterval)
                {
                    continue;
                }

                stomach.AccumulatedFrameTime -= stomach.UpdateInterval;

                // Get our solutions
                if (!_solutionContainerSystem.TryGetSolution((stomach).Owner, DefaultSolutionName,
                                                             out var stomachSolution, sol))
                {
                    continue;
                }

                if (!_solutionContainerSystem.TryGetSolution((mech.Body).Owner, stomach.BodySolutionName,
                                                             out var bodySolution))
                {
                    continue;
                }

                var transferSolution = new Solution();

                var queue = new RemQueue <StomachComponent.ReagentDelta>();
                foreach (var delta in stomach.ReagentDeltas)
                {
                    delta.Increment(stomach.UpdateInterval);
                    if (delta.Lifetime > stomach.DigestionDelay)
                    {
                        if (stomachSolution.ContainsReagent(delta.ReagentId, out var quant))
                        {
                            if (quant > delta.Quantity)
                            {
                                quant = delta.Quantity;
                            }

                            _solutionContainerSystem.TryRemoveReagent((stomach).Owner, stomachSolution,
                                                                      delta.ReagentId, quant);
                            transferSolution.AddReagent(delta.ReagentId, quant);
                        }

                        queue.Add(delta);
                    }
                }

                foreach (var item in queue)
                {
                    stomach.ReagentDeltas.Remove(item);
                }

                // Transfer everything to the body solution!
                _solutionContainerSystem.TryAddSolution((mech.Body).Owner, bodySolution, transferSolution);
            }
        }