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