Ejemplo n.º 1
0
 public RotateEvent(EntityUid sender, Angle oldRotation, Angle newRotation, Box2?worldAABB = null)
 {
     Sender      = sender;
     OldRotation = oldRotation;
     NewRotation = newRotation;
     WorldAABB   = worldAABB;
 }
Ejemplo n.º 2
0
        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
        }
Ejemplo n.º 3
0
 public MoveEvent(IEntity sender, EntityCoordinates oldPos, EntityCoordinates newPos, Box2?worldAABB = null)
 {
     Sender      = sender;
     OldPosition = oldPos;
     NewPosition = newPos;
     WorldAABB   = worldAABB;
 }
Ejemplo n.º 4
0
 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)}");
    }
Ejemplo n.º 6
0
 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;
 }
Ejemplo n.º 7
0
    /// <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;
 }
Ejemplo n.º 9
0
        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;
            }
        }
Ejemplo n.º 10
0
 public ClickableComponentState(Box2?localBounds)
 {
     LocalBounds = localBounds;
 }
Ejemplo n.º 11
0
        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);
        }
Ejemplo n.º 12
0
    /// <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);
    }