public RotateEvent(EntityUid sender, Angle oldRotation, Angle newRotation, Box2?worldAABB = null) { Sender = sender; OldRotation = oldRotation; NewRotation = newRotation; WorldAABB = worldAABB; }
protected virtual void DrawChildren(DrawContext drawContext, float actualOpacity) { if (children.Count == 0) { return; } #if DEBUG Box2?clipRegionDebug = null; #endif using (ClipChildren ? DrawState.Clip(Bounds, Manager.Camera) : null) { foreach (var child in children) { if (child.displayed) { child.Draw(drawContext, actualOpacity); } } #if DEBUG if (ClipChildren) { clipRegionDebug = DrawState.GetClipRegion(Manager.Camera); } #endif } #if DEBUG if (clipRegionDebug.HasValue) { Manager.Skin.GetDrawable("debug_clipregion")?.Draw(drawContext, manager.Camera, clipRegionDebug.Value, 1); } #endif }
public MoveEvent(IEntity sender, EntityCoordinates oldPos, EntityCoordinates newPos, Box2?worldAABB = null) { Sender = sender; OldPosition = oldPos; NewPosition = newPos; WorldAABB = worldAABB; }
public MoveEvent(EntityUid sender, EntityCoordinates oldPos, EntityCoordinates newPos, TransformComponent component, Box2?worldAABB = null) { Sender = sender; OldPosition = oldPos; NewPosition = newPos; Component = component; WorldAABB = worldAABB; }
/// <summary> /// Retrieves a shuttle for delivery. /// </summary> public void CallShuttle(StationCargoOrderDatabaseComponent orderDatabase) { if (!TryComp <CargoShuttleComponent>(orderDatabase.Shuttle, out var shuttle) || !TryComp <TransformComponent>(orderDatabase.Owner, out var xform)) { return; } // Already called / not available if (shuttle.NextCall == null || _timing.CurTime < shuttle.NextCall) { return; } shuttle.NextCall = null; // Find a valid free area nearby to spawn in on // TODO: Make this use hyperspace now. var center = new Vector2(); var minRadius = 0f; Box2?aabb = null; foreach (var grid in _mapManager.GetAllMapGrids(xform.MapID)) { aabb = aabb?.Union(grid.WorldAABB) ?? grid.WorldAABB; } if (aabb != null) { center = aabb.Value.Center; minRadius = MathF.Max(aabb.Value.Width, aabb.Value.Height); } var offset = 0f; if (TryComp <IMapGridComponent>(orderDatabase.Shuttle, out var shuttleGrid)) { var bounds = shuttleGrid.Grid.LocalAABB; offset = MathF.Max(bounds.Width, bounds.Height) / 2f; } Transform(shuttle.Owner).Coordinates = new EntityCoordinates(xform.ParentUid, center + _random.NextVector2(minRadius + offset, minRadius + CallOffset + offset)); DebugTools.Assert(!MetaData(shuttle.Owner).EntityPaused); AddCargoContents(shuttle, orderDatabase); UpdateOrders(orderDatabase); UpdateShuttleCargoConsoles(shuttle); _console.RefreshShuttleConsoles(); _sawmill.Info($"Retrieved cargo shuttle {ToPrettyString(shuttle.Owner)} from {ToPrettyString(orderDatabase.Owner)}"); }
public Sprite( Box2?dest = null, Box2?source = null, Vector2?origin = null, Vector2?scale = null, float rotation = 0, Color4?color = null, Texture texture = null) { _texture = texture ?? throw new ArgumentNullException(nameof(texture)); Dest = dest ?? new Box2(-1, -1, 1, 1); Source = source ?? new Box2(0, 0, 1, 1); Origin = origin ?? Vector2.Zero; Scale = scale ?? Vector2.One; Rotation = rotation; Color = color ?? Color4.White; }
/// <summary> /// Checks if 2 docks can be connected by moving the shuttle directly onto docks. /// </summary> private bool CanDock( DockingComponent shuttleDock, TransformComponent shuttleXform, DockingComponent gridDock, TransformComponent gridXform, Vector2 targetGridRotation, Box2 shuttleAABB, IMapGridComponent grid, [NotNullWhen(true)] out Box2?shuttleDockedAABB, out Matrix3 matty, out Vector2 gridRotation) { gridRotation = Vector2.Zero; matty = Matrix3.Identity; shuttleDockedAABB = null; if (shuttleDock.Docked || gridDock.Docked || !shuttleXform.Anchored || !gridXform.Anchored) { return(false); } // First, get the station dock's position relative to the shuttle, this is where we rotate it around var stationDockPos = shuttleXform.LocalPosition + shuttleXform.LocalRotation.RotateVec(new Vector2(0f, -1f)); var stationDockMatrix = Matrix3.CreateInverseTransform(stationDockPos, -shuttleXform.LocalRotation); var gridXformMatrix = Matrix3.CreateTransform(gridXform.LocalPosition, gridXform.LocalRotation); Matrix3.Multiply(in stationDockMatrix, in gridXformMatrix, out matty); shuttleDockedAABB = matty.TransformBox(shuttleAABB); if (!ValidSpawn(grid, shuttleDockedAABB.Value)) { return(false); } gridRotation = matty.Transform(targetGridRotation); return(true); }
public ClickableComponentState(Box2? localBounds) : base(NetIDs.CLICKABLE) { LocalBounds = localBounds; }
public override void Update(float frameTime) { base.Update(frameTime); if (!Started) { return; } if (_waveCounter <= 0) { Running = false; return; } _cooldown -= frameTime; if (_cooldown > 0f) { return; } _waveCounter--; _cooldown += (MaximumCooldown - MinimumCooldown) * _robustRandom.NextFloat() + MinimumCooldown; Box2?playableArea = null; var mapId = EntitySystem.Get <GameTicker>().DefaultMap; foreach (var grid in _mapManager.GetAllGrids()) { if (grid.ParentMapId != mapId || !_entityManager.TryGetComponent(grid.GridEntityId, out PhysicsComponent? gridBody)) { continue; } var aabb = gridBody.GetWorldAABB(); playableArea = playableArea?.Union(aabb) ?? aabb; } if (playableArea == null) { EndAfter = float.MinValue; return; } var minimumDistance = (playableArea.Value.TopRight - playableArea.Value.Center).Length + 50f; var maximumDistance = minimumDistance + 100f; var center = playableArea.Value.Center; for (var i = 0; i < MeteorsPerWave; i++) { var angle = new Angle(_robustRandom.NextFloat() * MathF.Tau); var offset = angle.RotateVec(new Vector2((maximumDistance - minimumDistance) * _robustRandom.NextFloat() + minimumDistance, 0)); var spawnPosition = new MapCoordinates(center + offset, mapId); var meteor = _entityManager.SpawnEntity("MeteorLarge", spawnPosition); var physics = _entityManager.GetComponent <PhysicsComponent>(meteor.Uid); physics.BodyStatus = BodyStatus.InAir; physics.LinearDamping = 0f; physics.AngularDamping = 0f; physics.ApplyLinearImpulse(-offset.Normalized * MeteorVelocity * physics.Mass); physics.ApplyAngularImpulse( // Get a random angular velocity. physics.Mass * ((MaxAngularVelocity - MinAngularVelocity) * _robustRandom.NextFloat() + MinAngularVelocity)); // TODO: God this disgusts me but projectile needs a refactor. meteor.GetComponent <ProjectileComponent>().TimeLeft = 120f; } }
public ClickableComponentState(Box2?localBounds) { LocalBounds = localBounds; }
private DockingComponent?GetDockable(PhysicsComponent body, TransformComponent dockingXform) { // Did you know Saltern is the most dockable station? // Assume the docking port itself (and its body) is valid if (!_mapManager.TryGetGrid(dockingXform.GridID, out var grid) || !HasComp <ShuttleComponent>(grid.GridEntityId)) { return(null); } var transform = body.GetTransform(); var dockingFixture = _fixtureSystem.GetFixtureOrNull(body, DockingFixture); if (dockingFixture == null) { DebugTools.Assert(false); Logger.ErrorS("docking", $"Found null fixture on {(body).Owner}"); return(null); } Box2?aabb = null; for (var i = 0; i < dockingFixture.Shape.ChildCount; i++) { aabb = aabb?.Union(dockingFixture.Shape.ComputeAABB(transform, i)) ?? dockingFixture.Shape.ComputeAABB(transform, i); } if (aabb == null) { return(null); } var enlargedAABB = aabb.Value.Enlarged(DockingRadius * 1.5f); // Get any docking ports in range on other grids. _mapManager.FindGridsIntersectingEnumerator(dockingXform.MapID, enlargedAABB, out var enumerator); while (enumerator.MoveNext(out var otherGrid)) { if (otherGrid.Index == dockingXform.GridID) { continue; } foreach (var ent in otherGrid.GetAnchoredEntities(enlargedAABB)) { if (!TryComp(ent, out DockingComponent? otherDocking) || !otherDocking.Enabled || !TryComp(ent, out PhysicsComponent? otherBody)) { continue; } var otherTransform = otherBody.GetTransform(); var otherDockingFixture = _fixtureSystem.GetFixtureOrNull(otherBody, DockingFixture); if (otherDockingFixture == null) { DebugTools.Assert(false); Logger.ErrorS("docking", $"Found null docking fixture on {ent}"); continue; } for (var i = 0; i < otherDockingFixture.Shape.ChildCount; i++) { var otherAABB = otherDockingFixture.Shape.ComputeAABB(otherTransform, i); if (!aabb.Value.Intersects(otherAABB)) { continue; } // TODO: Need CollisionManager's GJK for accurate bounds // Realistically I want 2 fixtures anyway but I'll deal with that later. return(otherDocking); } } } return(null); }
/// <summary> /// Tries to arrive nearby without overlapping with other grids. /// </summary> public bool TryFTLProximity(ShuttleComponent component, EntityUid targetUid, TransformComponent?xform = null, TransformComponent?targetXform = null) { if (!Resolve(targetUid, ref targetXform) || targetXform.MapUid == null || !Resolve(component.Owner, ref xform)) { return(false); } var xformQuery = GetEntityQuery <TransformComponent>(); var shuttleAABB = Comp <IMapGridComponent>(component.Owner).Grid.LocalAABB; Box2?aabb = null; // Spawn nearby. // We essentially expand the Box2 of the target area until nothing else is added then we know it's valid. // Can't just get an AABB of every grid as we may spawn very far away. var targetAABB = _transform.GetWorldMatrix(targetXform, xformQuery) .TransformBox(Comp <IMapGridComponent>(targetUid).Grid.LocalAABB).Enlarged(shuttleAABB.Size.Length); var nearbyGrids = new HashSet <EntityUid>(1) { targetUid }; var iteration = 0; var lastCount = 1; var mapId = targetXform.MapID; while (iteration < 3) { foreach (var grid in _mapManager.FindGridsIntersecting(mapId, targetAABB)) { if (!nearbyGrids.Add(grid.GridEntityId)) { continue; } targetAABB = targetAABB.Union(_transform.GetWorldMatrix(grid.GridEntityId, xformQuery) .TransformBox(Comp <IMapGridComponent>(grid.GridEntityId).Grid.LocalAABB)); } // Can do proximity if (nearbyGrids.Count == lastCount) { break; } targetAABB = targetAABB.Enlarged(shuttleAABB.Size.Length / 2f); iteration++; lastCount = nearbyGrids.Count; // Mishap moment, dense asteroid field or whatever if (iteration != 3) { continue; } foreach (var grid in _mapManager.GetAllGrids()) { // Don't add anymore as it is irrelevant, but that doesn't mean we need to re-do existing work. if (nearbyGrids.Contains(grid.GridEntityId)) { continue; } targetAABB = targetAABB.Union(_transform.GetWorldMatrix(grid.GridEntityId, xformQuery) .TransformBox(Comp <IMapGridComponent>(grid.GridEntityId).Grid.LocalAABB)); } break; } var minRadius = (MathF.Max(targetAABB.Width, targetAABB.Height) + MathF.Max(shuttleAABB.Width, shuttleAABB.Height)) / 2f; var spawnPos = targetAABB.Center + _random.NextVector2(minRadius, minRadius + 64f); if (TryComp <PhysicsComponent>(component.Owner, out var shuttleBody)) { shuttleBody.LinearVelocity = Vector2.Zero; shuttleBody.AngularVelocity = 0f; } xform.Coordinates = new EntityCoordinates(targetXform.MapUid.Value, spawnPos); xform.WorldRotation = _random.NextAngle(); return(true); }