예제 #1
0
 public void ClearPilots(ShuttleConsoleComponent component)
 {
     while (component.SubscribedPilots.TryGetValue(0, out var pilot))
     {
         RemovePilot(pilot);
     }
 }
예제 #2
0
        /// <summary>
        /// Sets the shuttle's movement mode. Does minimal revalidation.
        /// </summary>
        private void SetShuttleMode(ShuttleMode mode, ShuttleConsoleComponent consoleComponent,
                                    ShuttleComponent shuttleComponent, TransformComponent?consoleXform = null)
        {
            // Re-validate
            if (!this.IsPowered(consoleComponent.Owner, EntityManager) ||
                !Resolve(consoleComponent.Owner, ref consoleXform) ||
                !consoleXform.Anchored ||
                consoleXform.GridID != Transform(shuttleComponent.Owner).GridID)
            {
                return;
            }

            shuttleComponent.Mode = mode;

            switch (mode)
            {
            case ShuttleMode.Strafing:
                break;

            case ShuttleMode.Cruise:
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
예제 #3
0
        /// <summary>
        /// For now pilots just interact with the console and can start piloting with wasd.
        /// </summary>
        private void HandleConsoleInteract(EntityUid uid, ShuttleConsoleComponent component, ActivateInWorldEvent args)
        {
            if (!_tags.HasTag(args.User, "CanPilot"))
            {
                return;
            }

            var pilotComponent = EntityManager.EnsureComponent <PilotComponent>(args.User);

            if (!component.Enabled)
            {
                args.User.PopupMessage($"Console is not powered.");
                return;
            }

            args.Handled = true;
            var console = pilotComponent.Console;

            if (console != null)
            {
                RemovePilot(pilotComponent);

                if (console == component)
                {
                    return;
                }
            }

            AddPilot(args.User, component);
        }
예제 #4
0
        private void ToggleShuttleMode(EntityUid user, ShuttleConsoleComponent consoleComponent, ShuttleComponent shuttleComponent, TransformComponent?consoleXform = null)
        {
            // Re-validate
            if (EntityManager.TryGetComponent(consoleComponent.Owner, out ApcPowerReceiverComponent? receiver) && !receiver.Powered)
            {
                return;
            }

            if (!Resolve(consoleComponent.Owner, ref consoleXform))
            {
                return;
            }

            if (!consoleXform.Anchored || consoleXform.GridID != EntityManager.GetComponent <TransformComponent>(shuttleComponent.Owner).GridID)
            {
                return;
            }

            switch (shuttleComponent.Mode)
            {
            case ShuttleMode.Cruise:
                shuttleComponent.Mode = ShuttleMode.Docking;
                _popup.PopupEntity(Loc.GetString("shuttle-mode-docking"), consoleComponent.Owner, Filter.Entities(user));
                break;

            case ShuttleMode.Docking:
                shuttleComponent.Mode = ShuttleMode.Cruise;
                _popup.PopupEntity(Loc.GetString("shuttle-mode-cruise"), consoleComponent.Owner, Filter.Entities(user));
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
예제 #5
0
        private void OnConsoleInteract(EntityUid uid, ShuttleConsoleComponent component, GetVerbsEvent <InteractionVerb> args)
        {
            if (!args.CanAccess ||
                !args.CanInteract)
            {
                return;
            }

            var xform = EntityManager.GetComponent <TransformComponent>(uid);

            // Maybe move mode onto the console instead?
            if (!_mapManager.TryGetGrid(xform.GridID, out var grid) ||
                !EntityManager.TryGetComponent(grid.GridEntityId, out ShuttleComponent? shuttle))
            {
                return;
            }

            InteractionVerb verb = new()
            {
                Text     = Loc.GetString("shuttle-mode-toggle"),
                Act      = () => ToggleShuttleMode(args.User, component, shuttle),
                Disabled = !xform.Anchored || EntityManager.TryGetComponent(uid, out ApcPowerReceiverComponent? receiver) && !receiver.Powered,
            };

            args.Verbs.Add(verb);
        }
 private void OnConsoleUIOpenAttempt(EntityUid uid, ShuttleConsoleComponent component, ActivatableUIOpenAttemptEvent args)
 {
     if (!TryPilot(args.User, uid))
     {
         args.Cancel();
     }
 }
예제 #7
0
        private void UpdateState(ShuttleConsoleComponent component, List <DockingInterfaceState>?docks = null)
        {
            EntityUid?entity = component.Owner;

            var getShuttleEv = new ConsoleShuttleEvent
            {
                Console = entity,
            };

            RaiseLocalEvent(entity.Value, ref getShuttleEv, false);
            entity = getShuttleEv.Console;

            TryComp <TransformComponent>(entity, out var consoleXform);
            TryComp <RadarConsoleComponent>(entity, out var radar);
            var range = radar?.MaxRange ?? 0f;

            TryComp <ShuttleComponent>(consoleXform?.GridUid, out var shuttle);
            var mode = shuttle?.Mode ?? ShuttleMode.Cruise;

            docks ??= GetAllDocks();

            _ui.GetUiOrNull(component.Owner, ShuttleConsoleUiKey.Key)
            ?.SetState(new ShuttleConsoleBoundInterfaceState(
                           mode,
                           range,
                           consoleXform?.Coordinates,
                           consoleXform?.LocalRotation,
                           docks));
        }
예제 #8
0
        /// <summary>
        /// Client is requesting a change in the shuttle's driving mode.
        /// </summary>
        private void OnModeRequest(EntityUid uid, ShuttleConsoleComponent component, ShuttleModeRequestMessage args)
        {
            var consoleUid = uid;

            if (TryComp <CargoPilotConsoleComponent>(uid, out var cargoPilot) && cargoPilot.Entity != null)
            {
                consoleUid = cargoPilot.Entity.Value;
            }

            if (args.Session.AttachedEntity is not {
            } player ||
                !TryComp <PilotComponent>(player, out var pilot) ||
                !TryComp <ShuttleConsoleComponent>(consoleUid, out var console) ||
                !TryComp <TransformComponent>(consoleUid, out var consoleXform))
            {
                return;
            }

            // Can't check console pilots as it may be remotely piloted!
            if (!component.SubscribedPilots.Contains(pilot) ||
                !TryComp <ShuttleComponent>(consoleXform.GridUid, out var shuttle))
            {
                return;
            }

            SetShuttleMode(args.Mode, console, shuttle);
            UpdateState(component);

            if (uid != consoleUid)
            {
                UpdateState(console);
            }
        }
        private void OnDestinationMessage(EntityUid uid, ShuttleConsoleComponent component, ShuttleConsoleDestinationMessage args)
        {
            if (!TryComp <FTLDestinationComponent>(args.Destination, out var dest))
            {
                return;
            }

            if (!dest.Enabled)
            {
                return;
            }

            EntityUid?entity = component.Owner;

            var getShuttleEv = new ConsoleShuttleEvent
            {
                Console = uid,
            };

            RaiseLocalEvent(entity.Value, ref getShuttleEv);
            entity = getShuttleEv.Console;

            if (entity == null || dest.Whitelist?.IsValid(entity.Value, EntityManager) == false)
            {
                return;
            }

            if (!TryComp <TransformComponent>(entity, out var xform) ||
                !TryComp <ShuttleComponent>(xform.GridUid, out var shuttle))
            {
                return;
            }

            if (HasComp <FTLComponent>(xform.GridUid))
            {
                if (args.Session.AttachedEntity != null)
                {
                    _popup.PopupCursor(Loc.GetString("shuttle-console-in-ftl"), Filter.Entities(args.Session.AttachedEntity.Value));
                }

                return;
            }

            if (!_shuttle.CanFTL(shuttle.Owner, out var reason))
            {
                if (args.Session.AttachedEntity != null)
                {
                    _popup.PopupCursor(reason, Filter.Entities(args.Session.AttachedEntity.Value));
                }

                return;
            }

            _shuttle.FTLTravel(shuttle, args.Destination, hyperspaceTime: _shuttle.TransitTime);
        }
예제 #10
0
    private void OnRequestUndock(EntityUid uid, ShuttleConsoleComponent component, UndockRequestMessage args)
    {
        _sawmill.Debug($"Received undock request for {ToPrettyString(args.DockEntity)}");

        // TODO: Validation
        if (!TryComp <DockingComponent>(args.DockEntity, out var dock) ||
            !dock.Docked)
        {
            return;
        }

        Undock(dock);
    }
예제 #11
0
        /// <summary>
        /// Console requires power to operate.
        /// </summary>
        private void HandlePowerChange(EntityUid uid, ShuttleConsoleComponent component, PowerChangedEvent args)
        {
            if (!args.Powered)
            {
                component.Enabled = false;

                ClearPilots(component);
            }
            else
            {
                component.Enabled = true;
            }
        }
예제 #12
0
    private void OnRequestAutodock(EntityUid uid, ShuttleConsoleComponent component, AutodockRequestMessage args)
    {
        _sawmill.Debug($"Received autodock request for {ToPrettyString(args.DockEntity)}");
        var player = args.Session.AttachedEntity;

        if (player == null || !HasComp <DockingComponent>(args.DockEntity))
        {
            return;
        }

        // TODO: Validation
        var comp = EnsureComp <AutoDockComponent>(args.DockEntity);

        comp.Requesters.Add(player.Value);
    }
        /// <summary>
        /// Stop piloting if the window is closed.
        /// </summary>
        private void OnConsoleUIClose(EntityUid uid, ShuttleConsoleComponent component, BoundUIClosedEvent args)
        {
            if ((ShuttleConsoleUiKey) args.UiKey != ShuttleConsoleUiKey.Key ||
                args.Session.AttachedEntity is not {
            } user)
            {
                return;
            }

            // In case they D/C should still clean them up.
            foreach (var comp in EntityQuery <AutoDockComponent>(true))
            {
                comp.Requesters.Remove(user);
            }

            RemovePilot(user);
        }
예제 #14
0
    private void OnRequestStopAutodock(EntityUid uid, ShuttleConsoleComponent component, StopAutodockRequestMessage args)
    {
        _sawmill.Debug($"Received stop autodock request for {ToPrettyString(args.DockEntity)}");

        var player = args.Session.AttachedEntity;

        // TODO: Validation
        if (player == null || !TryComp <AutoDockComponent>(args.DockEntity, out var comp))
        {
            return;
        }

        comp.Requesters.Remove(player.Value);

        if (comp.Requesters.Count == 0)
        {
            RemComp <AutoDockComponent>(args.DockEntity);
        }
    }
        public void AddPilot(EntityUid entity, ShuttleConsoleComponent component)
        {
            if (!_blocker.CanInteract(entity) ||
                !EntityManager.TryGetComponent(entity, out PilotComponent? pilotComponent) ||
                component.SubscribedPilots.Contains(pilotComponent))
            {
                return;
            }

            component.SubscribedPilots.Add(pilotComponent);

            if (EntityManager.TryGetComponent(entity, out ServerAlertsComponent? alertsComponent))
            {
                alertsComponent.ShowAlert(AlertType.PilotingShuttle);
            }

            entity.PopupMessage(Loc.GetString("shuttle-pilot-start"));
            pilotComponent.Console  = component;
            pilotComponent.Position = EntityManager.GetComponent <TransformComponent>(entity).Coordinates;
            pilotComponent.Dirty();
        }
예제 #16
0
        public void AddPilot(EntityUid entity, ShuttleConsoleComponent component)
        {
            if (!EntityManager.TryGetComponent(entity, out PilotComponent? pilotComponent) ||
                component.SubscribedPilots.Contains(pilotComponent))
            {
                return;
            }

            if (TryComp <SharedEyeComponent>(entity, out var eye))
            {
                eye.Zoom = component.Zoom;
            }

            component.SubscribedPilots.Add(pilotComponent);

            _alertsSystem.ShowAlert(entity, AlertType.PilotingShuttle);

            entity.PopupMessage(Loc.GetString("shuttle-pilot-start"));
            pilotComponent.Console  = component;
            pilotComponent.Position = EntityManager.GetComponent <TransformComponent>(entity).Coordinates;
            pilotComponent.Dirty();
        }
        public void AddPilot(EntityUid entity, ShuttleConsoleComponent component)
        {
            if (!EntityManager.TryGetComponent(entity, out PilotComponent? pilotComponent) ||
                component.SubscribedPilots.Contains(pilotComponent))
            {
                return;
            }

            if (TryComp <SharedEyeComponent>(entity, out var eye))
            {
                eye.Zoom = component.Zoom;
            }

            component.SubscribedPilots.Add(pilotComponent);

            _alertsSystem.ShowAlert(entity, AlertType.PilotingShuttle);

            pilotComponent.Console = component;
            ActionBlockerSystem.UpdateCanMove(entity);
            pilotComponent.Position = EntityManager.GetComponent <TransformComponent>(entity).Coordinates;
            Dirty(pilotComponent);
        }
 private void OnConsoleAnchorChange(EntityUid uid, ShuttleConsoleComponent component, ref AnchorStateChangedEvent args)
 {
     UpdateState(component);
 }
 private void OnConsolePowerChange(EntityUid uid, ShuttleConsoleComponent component, PowerChangedEvent args)
 {
     UpdateState(component);
 }
        private void UpdateState(ShuttleConsoleComponent component, List <DockingInterfaceState>?docks = null)
        {
            EntityUid?entity = component.Owner;

            var getShuttleEv = new ConsoleShuttleEvent
            {
                Console = entity,
            };

            RaiseLocalEvent(entity.Value, ref getShuttleEv);
            entity = getShuttleEv.Console;

            TryComp <TransformComponent>(entity, out var consoleXform);
            TryComp <RadarConsoleComponent>(entity, out var radar);
            var range = radar?.MaxRange ?? 0f;

            TryComp <ShuttleComponent>(consoleXform?.GridUid, out var shuttle);

            var destinations = new List <(EntityUid, string, bool)>();
            var ftlState     = FTLState.Available;
            var ftlTime      = TimeSpan.Zero;

            if (TryComp <FTLComponent>(shuttle?.Owner, out var shuttleFtl))
            {
                ftlState = shuttleFtl.State;
                ftlTime  = _timing.CurTime + TimeSpan.FromSeconds(shuttleFtl.Accumulator);
            }

            // Mass too large
            if (entity != null && shuttle?.Owner != null && (!TryComp <PhysicsComponent>(shuttle?.Owner, out var shuttleBody) ||
                                                             shuttleBody.Mass < 1000f))
            {
                var metaQuery = GetEntityQuery <MetaDataComponent>();

                // Can't go anywhere when in FTL.
                var locked = shuttleFtl != null || Paused(shuttle !.Owner);

                // Can't cache it because it may have a whitelist for the particular console.
                // Include paused as we still want to show CentCom.
                foreach (var comp in EntityQuery <FTLDestinationComponent>(true))
                {
                    // Can't warp to itself or if it's not on the whitelist.
                    if (comp.Owner == shuttle?.Owner ||
                        comp.Whitelist?.IsValid(entity.Value) == false)
                    {
                        continue;
                    }

                    var meta = metaQuery.GetComponent(comp.Owner);
                    var name = meta.EntityName;

                    if (string.IsNullOrEmpty(name))
                    {
                        name = Loc.GetString("shuttle-console-unknown");
                    }

                    var canTravel = !locked &&
                                    comp.Enabled &&
                                    !Paused(comp.Owner, meta) &&
                                    (!TryComp <FTLComponent>(comp.Owner, out var ftl) || ftl.State == FTLState.Cooldown);

                    // Can't travel to same map.
                    if (canTravel && consoleXform?.MapUid == Transform(comp.Owner).MapUid)
                    {
                        canTravel = false;
                    }

                    destinations.Add((comp.Owner, name, canTravel));
                }
            }

            docks ??= GetAllDocks();

            _ui.GetUiOrNull(component.Owner, ShuttleConsoleUiKey.Key)
            ?.SetState(new ShuttleConsoleBoundInterfaceState(
                           ftlState,
                           ftlTime,
                           destinations,
                           range,
                           consoleXform?.Coordinates,
                           consoleXform?.LocalRotation,
                           docks));
        }
예제 #21
0
 private void HandleConsoleShutdown(EntityUid uid, ShuttleConsoleComponent component, ComponentShutdown args)
 {
     ClearPilots(component);
 }