private void AddCargoContents(CargoShuttleComponent component, StationCargoOrderDatabaseComponent orderDatabase)
    {
        var xformQuery = GetEntityQuery <TransformComponent>();
        var orders     = GetProjectedOrders(orderDatabase, component);

        var pads = GetCargoPallets(component);

        DebugTools.Assert(orders.Sum(o => o.Amount) <= pads.Count);

        for (var i = 0; i < orders.Count; i++)
        {
            var order = orders[i];

            Spawn(_protoMan.Index <CargoProductPrototype>(order.ProductId).Product,
                  new EntityCoordinates(component.Owner, xformQuery.GetComponent(_random.PickAndTake(pads).Owner).LocalPosition));
            order.Amount--;

            if (order.Amount == 0)
            {
                orders.RemoveSwap(i);
                orderDatabase.Orders.Remove(order.OrderNumber);
                i--;
            }
            else
            {
                orderDatabase.Orders[order.OrderNumber] = order;
            }
        }
    }
    /// <summary>
    ///
    /// </summary>
    /// <param name="component"></param>
    private bool IsBlocked(CargoShuttleComponent component)
    {
        // TODO: Would be good to rate-limit this on the console.
        var mobQuery   = GetEntityQuery <MobStateComponent>();
        var xformQuery = GetEntityQuery <TransformComponent>();

        return(FoundOrganics(component.Owner, mobQuery, xformQuery));
    }
 private void UpdateShuttleCargoConsoles(CargoShuttleComponent component)
 {
     foreach (var console in EntityQuery <CargoShuttleConsoleComponent>(true))
     {
         var stationUid = _station.GetOwningStation(console.Owner);
         if (stationUid != component.Station)
         {
             continue;
         }
         UpdateShuttleState(console, stationUid);
     }
 }
    public EntityUid?GetShuttleConsole(CargoShuttleComponent component)
    {
        foreach (var(comp, xform) in EntityQuery <ShuttleConsoleComponent, TransformComponent>(true))
        {
            if (xform.ParentUid != component.Owner)
            {
                continue;
            }
            return(comp.Owner);
        }

        return(null);
    }
    private List <CargoPalletComponent> GetCargoPallets(CargoShuttleComponent component)
    {
        var pads = new List <CargoPalletComponent>();

        foreach (var(comp, compXform) in EntityQuery <CargoPalletComponent, TransformComponent>(true))
        {
            if (compXform.ParentUid != component.Owner ||
                !compXform.Anchored)
            {
                continue;
            }

            pads.Add(comp);
        }

        return(pads);
    }
    private void OnCargoShuttleMove(EntityUid uid, CargoShuttleComponent component, ref MoveEvent args)
    {
        if (component.Station == null)
        {
            return;
        }

        var oldCanRecall = component.CanRecall;

        // Check if we can update the recall status.
        var canRecall = CanRecallShuttle(uid, out _, args.Component);

        if (oldCanRecall == canRecall)
        {
            return;
        }

        component.CanRecall = canRecall;
        _sawmill.Debug($"Updated CanRecall for {ToPrettyString(uid)}");
        UpdateShuttleCargoConsoles(component);
    }
    private void SellPallets(CargoShuttleComponent component, StationBankAccountComponent bank)
    {
        double amount     = 0;
        var    toSell     = new HashSet <EntityUid>();
        var    xformQuery = GetEntityQuery <TransformComponent>();

        foreach (var pallet in GetCargoPallets(component))
        {
            // Containers should already get the sell price of their children so can skip those.
            foreach (var ent in _lookup.GetEntitiesIntersecting(pallet.Owner, LookupFlags.Anchored))
            {
                // Don't re-sell anything, sell anything anchored (e.g. light fixtures), or anything blacklisted
                // (e.g. players).
                if (toSell.Contains(ent) ||
                    (xformQuery.TryGetComponent(ent, out var xform) && xform.Anchored))
                {
                    continue;
                }

                var price = _pricing.GetPrice(ent);
                if (price == 0)
                {
                    continue;
                }
                toSell.Add(ent);
                amount += price;
            }
        }

        bank.Balance += (int)amount;
        _sawmill.Debug($"Cargo sold {toSell.Count} entities for {amount}");

        foreach (var ent in toSell)
        {
            Del(ent);
        }
    }
    /// <summary>
    /// Get the amount of space the cargo shuttle can fit for orders.
    /// </summary>
    private int GetCargoSpace(CargoShuttleComponent component)
    {
        var space = GetCargoPallets(component).Count;

        return(space);
    }
    /// <summary>
    /// In this method we are printing and attaching order manifests to the orders.
    /// </summary>
    private void SpawnAndAttachOrderManifest(EntityUid item, CargoOrderData order, EntityCoordinates coordinates, CargoShuttleComponent component)
    {
        if (!_protoMan.TryIndex(order.ProductId, out CargoProductPrototype? prototype))
        {
            return;
        }

        // spawn a piece of paper.
        var printed = EntityManager.SpawnEntity("Paper", coordinates);

        if (!TryComp <PaperComponent>(printed, out var paper))
        {
            return;
        }

        // fill in the order data
        var val = Loc.GetString("cargo-console-paper-print-name", ("orderNumber", order.OrderNumber));

        MetaData(printed).EntityName = val;

        _paperSystem.SetContent(printed, Loc.GetString(
                                    "cargo-console-paper-print-text",
                                    ("orderNumber", order.OrderNumber),
                                    ("itemName", prototype.Name),
                                    ("requester", order.Requester),
                                    ("reason", order.Reason),
                                    ("approver", order.Approver ?? string.Empty)),
                                paper);

        // attempt to attach the label
        if (TryComp <PaperLabelComponent>(item, out var label))
        {
            _slots.TryInsert(item, label.LabelSlot, printed, null);
        }
    }