diff --git a/Content.Client/Shuttles/UI/ShuttleConsoleWindow.xaml.cs b/Content.Client/Shuttles/UI/ShuttleConsoleWindow.xaml.cs index 2b4684d1136..12153d68413 100644 --- a/Content.Client/Shuttles/UI/ShuttleConsoleWindow.xaml.cs +++ b/Content.Client/Shuttles/UI/ShuttleConsoleWindow.xaml.cs @@ -182,17 +182,18 @@ public enum ShuttleConsoleMode : byte public void UpdateState(EntityUid owner, ShuttleBoundUserInterfaceState cState) { - var coordinates = _entManager.GetCoordinates(cState.NavState.Coordinates); - NavContainer.SetShuttle(coordinates?.EntityId); + //var coordinates = _entManager.GetCoordinates(cState.NavState.Coordinates); // Lua + var shuttle = _entManager.GetEntity(cState.Shuttle); // Lua + NavContainer.SetShuttle(shuttle); // Lua NavContainer.SetConsole(owner); - MapContainer.SetShuttle(coordinates?.EntityId); + MapContainer.SetShuttle(shuttle); // Lua MapContainer.SetConsole(owner); - StarMapContainer.SetShuttle(coordinates?.EntityId); + StarMapContainer.SetShuttle(shuttle); // Lua StarMapContainer.SetConsole(owner); NavContainer.UpdateState(cState.NavState); MapContainer.UpdateState(cState.MapState); StarMapContainer.UpdateState(cState.StarMapState); - DockContainer.UpdateState(coordinates?.EntityId, cState.DockState); + DockContainer.UpdateState(shuttle, cState.DockState); } } diff --git a/Content.Server/PowerCell/PowerCellSystem.cs b/Content.Server/PowerCell/PowerCellSystem.cs index 5a1019f023f..20f2705b6a4 100644 --- a/Content.Server/PowerCell/PowerCellSystem.cs +++ b/Content.Server/PowerCell/PowerCellSystem.cs @@ -252,8 +252,8 @@ private void OnCellEmpAttempt(EntityUid uid, PowerCellComponent component, EmpAt private void OnCellSlotExamined(EntityUid uid, PowerCellSlotComponent component, ExaminedEvent args) { - TryGetBatteryFromSlot(uid, out var battery); - OnBatteryExamined(uid, battery, args); + if (TryGetBatteryFromSlot(uid, out var batteryEnt, out var battery) && batteryEnt != null && battery != null) OnBatteryExamined(batteryEnt.Value, battery, args); + else OnBatteryExamined(uid, null, args); } public void OnBatteryExamined(EntityUid uid, BatteryComponent? component, ExaminedEvent args) // WD EDIT diff --git a/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.cs b/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.cs index 2cbabaa6790..ad6fd8ed293 100644 --- a/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.cs +++ b/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.cs @@ -4,6 +4,10 @@ using Content.Server.Shuttles.Components; using Content.Server.Shuttles.Events; using Content.Server.Station.Systems; +using Content.Server.PowerCell; // Lua +using Content.Server.Power.Components; // Lua +using Content.Shared.Containers.ItemSlots; // Lua +using Content.Shared._Lua.Tools.Components; // Lua using Content.Shared._Lua.Starmap; using Content.Shared._NF.Shipyard.Components; using Content.Shared._NF.Shuttles.Events; // Frontier @@ -55,6 +59,10 @@ public sealed partial class ShuttleConsoleSystem : SharedShuttleConsoleSystem [Dependency] private readonly IConfigurationManager _cfg = default!; // Lua [Dependency] private readonly ILogManager _log = default!; [Dependency] private readonly CrewedShuttleSystem _crewedShuttle = default!; + [Dependency] private readonly PowerCellSystem _cell = default!; // Lua + [Dependency] private readonly ItemSlotsSystem _slots = default!; // Lua + + private const string StructureTag = "Structure"; // Lua private ISawmill _sawmill = default!; @@ -136,6 +144,13 @@ private void OnStarMapVisibilityMessage(EntityUid uid, ShuttleConsoleComponent c private void OnConsoleGetVerbs(EntityUid uid, ShuttleConsoleComponent comp, GetVerbsEvent args) { + // Lua start + if (HasComp(uid)) + { + return; + } + // Lua end + AddPanicButtonVerb(uid, comp, args); AddPreventRemoverVerb(uid, comp, args); } @@ -255,12 +270,43 @@ private bool TryPilot(EntityUid user, EntityUid uid) if (!_tags.HasTag(user, CanPilotTag) || !TryComp(uid, out var component) || !this.IsPowered(uid, EntityManager) || - !Transform(uid).Anchored || + //!Transform(uid).Anchored || // Lua !_blocker.CanInteract(user, uid)) { return false; } + // Lua start + if (_tags.HasTag(uid, StructureTag) + && !Transform(uid).Anchored) + { + return false; + } + + if (!_cell.TryUseActivatableCharge(uid)) + { + return false; + } + + if (TryComp(uid, out var shuttleTabletComp)) + { + var card = _slots.GetItemOrNull(uid, "id_container"); + + if (card == null) + { + _popup.PopupEntity(Loc.GetString("shuttle-tablet-no-id"), uid); + return false; + } + + if (!TryComp(card, out var deedComp) + || deedComp == null) + { + _popup.PopupEntity(Loc.GetString("shuttle-tablet-no-deed"), uid); + return false; + } + } + // Lua end + if (!_access.IsAllowed(user, uid)) // Frontier: check access return false; // Frontier @@ -436,6 +482,33 @@ private void UpdateState(EntityUid consoleUid, ref DockingInterfaceState? dockSt { EntityUid? entity = consoleUid; + // Lua start + if (_cell.HasActivatableCharge(consoleUid) + && !_cell.HasDrawCharge(consoleUid)) + { + _ui.CloseUi(consoleUid, ShuttleConsoleUiKey.Key); + return; + } + + if (TryComp(consoleUid, out var shuttleTabletComp)) + { + var card = _slots.GetItemOrNull(consoleUid, "id_container"); + + if (card == null) + { + _popup.PopupEntity(Loc.GetString("shuttle-tablet-no-id"), consoleUid); + return; + } + + if (!TryComp(card, out var deedComp) + || deedComp == null) + { + _popup.PopupEntity(Loc.GetString("shuttle-tablet-no-deed"), consoleUid); + return; + } + } + // Lua end + var getShuttleEv = new ConsoleShuttleEvent { Console = entity, @@ -470,7 +543,7 @@ private void UpdateState(EntityUid consoleUid, ref DockingInterfaceState? dockSt { var currentMap = consoleXform?.MapID ?? MapId.Nullspace; var starMapState = GetStarMapState(currentMap, shuttleGridUid, consoleUid); - _ui.SetUiState(consoleUid, ShuttleConsoleUiKey.Key, new ShuttleBoundUserInterfaceState(navState, mapState, dockState, starMapState)); + _ui.SetUiState(consoleUid, ShuttleConsoleUiKey.Key, new ShuttleBoundUserInterfaceState(navState, mapState, dockState, starMapState, GetNetEntity(shuttleGridUid))); // Lua } } @@ -527,6 +600,8 @@ public void AddPilot(EntityUid uid, EntityUid entity, ShuttleConsoleComponent co ActionBlockerSystem.UpdateCanMove(entity); pilotComponent.Position = Comp(entity).Coordinates; Dirty(entity, pilotComponent); + DockingInterfaceState? dockState = null; // Lua + UpdateState(uid, ref dockState); // Lua } public void RemovePilot(EntityUid pilotUid, PilotComponent pilotComponent) @@ -584,10 +659,52 @@ public NavInterfaceState GetNavState(Entity(entity.Owner, out _)) + { + var consoleQuery = EntityQueryEnumerator(); + var consoleFound = false; + + while (consoleQuery.MoveNext(out var consoleUid, out _, out var consoleTransform, out var receiverComp)) + { + if (consoleTransform.GridUid == entity.Comp2.GridUid && receiverComp.Powered) + { + consoleFound = true; + + if (!TryComp(consoleUid, out var lockComp) + || !lockComp.EmergencyLocked) + { + coordinates = consoleTransform.Coordinates; + break; + } + + if (consoleComp != null) + { + ClearPilots(consoleComp); + } + + _popup.PopupEntity(Loc.GetString("shuttle-tablet-emergency-locked"), entity); + } + } + + if (!consoleFound) + { + if (consoleComp != null) + { + ClearPilots(consoleComp); + } + + _popup.PopupEntity(Loc.GetString("shuttle-tablet-no-remote-console"), entity); + } + } + // Lua end + return GetNavState( entity, docks, - entity.Comp2.Coordinates, + coordinates, // Lua entity.Comp2.LocalRotation, portNames); } diff --git a/Content.Server/_Lua/Tools/Systems/ShuttleTabletSystem.cs b/Content.Server/_Lua/Tools/Systems/ShuttleTabletSystem.cs new file mode 100644 index 00000000000..9ea17b92b0a --- /dev/null +++ b/Content.Server/_Lua/Tools/Systems/ShuttleTabletSystem.cs @@ -0,0 +1,43 @@ +// LuaWorld - This file is licensed under AGPLv3 +// Copyright (c) 2026 LuaWorld Contributors +// See AGPLv3.txt for details. + +using Robust.Server.GameObjects; +using Content.Shared.Containers.ItemSlots; +using Content.Shared._Lua.Tools.Components; +using Content.Shared._NF.Shipyard.Components; + +namespace Content.Server._Lua.Tools.Systems; + +public sealed class ShuttleTabletSystem : EntitySystem +{ + [Dependency] private readonly TransformSystem _transformSystem = default!; + [Dependency] private readonly ItemSlotsSystem _slots = default!; + + public override void Initialize() + { + base.Initialize(); + } + + public override void Update(float frameTime) + { + var query = EntityQueryEnumerator(); + + while (query.MoveNext(out var entity, out _, out var transformComp)) + { + var card = _slots.GetItemOrNull(entity, "id_container"); + + if (card == null) + { + continue; + } + + if (!TryComp(card, out var deedComp)) + { + continue; + } + + _transformSystem.SetGridId(entity, transformComp, deedComp.ShuttleUid); + } + } +} diff --git a/Content.Shared/Shuttles/BUIStates/ShuttleBoundUserInterfaceState.cs b/Content.Shared/Shuttles/BUIStates/ShuttleBoundUserInterfaceState.cs index b5c83588ed3..ed3bc9a4a41 100644 --- a/Content.Shared/Shuttles/BUIStates/ShuttleBoundUserInterfaceState.cs +++ b/Content.Shared/Shuttles/BUIStates/ShuttleBoundUserInterfaceState.cs @@ -11,12 +11,20 @@ public sealed class ShuttleBoundUserInterfaceState : BoundUserInterfaceState public ShuttleMapInterfaceState MapState; public DockingInterfaceState DockState; public StarmapConsoleBoundUserInterfaceState StarMapState; + public NetEntity? Shuttle; // Lua - public ShuttleBoundUserInterfaceState(NavInterfaceState navState, ShuttleMapInterfaceState mapState, DockingInterfaceState dockState, StarmapConsoleBoundUserInterfaceState starMapState) + public ShuttleBoundUserInterfaceState( + NavInterfaceState navState, + ShuttleMapInterfaceState mapState, + DockingInterfaceState dockState, + StarmapConsoleBoundUserInterfaceState starMapState, + NetEntity? shuttle // Lua + ) { NavState = navState; MapState = mapState; DockState = dockState; StarMapState = starMapState; + Shuttle = shuttle; // Lua } } diff --git a/Content.Shared/_Lua/Tools/Components/ShuttleTabletComponent.cs b/Content.Shared/_Lua/Tools/Components/ShuttleTabletComponent.cs new file mode 100644 index 00000000000..fbdb19cfbe6 --- /dev/null +++ b/Content.Shared/_Lua/Tools/Components/ShuttleTabletComponent.cs @@ -0,0 +1,8 @@ +// LuaWorld - This file is licensed under AGPLv3 +// Copyright (c) 2026 LuaWorld Contributors +// See AGPLv3.txt for details. + +namespace Content.Shared._Lua.Tools.Components; + +[RegisterComponent] +public sealed partial class ShuttleTabletComponent : Component; diff --git a/Resources/Locale/ru-RU/_Lua/entities/Objects/Tools/shuttletablet.ftl b/Resources/Locale/ru-RU/_Lua/entities/Objects/Tools/shuttletablet.ftl new file mode 100644 index 00000000000..6d1cd451e9b --- /dev/null +++ b/Resources/Locale/ru-RU/_Lua/entities/Objects/Tools/shuttletablet.ftl @@ -0,0 +1,30 @@ +ent-ShuttleControlTablet = планшет управления шаттлом + .desc = Портативный планшет для удалённого управления шаттлом. Имеет слот под ID карту. Для функционирования на шаттле должна находится хотя бы одна запитанная консоль. + +ent-ShuttleControlTabletEmpty = {ent-ShuttleControlTablet} + .desc = {ent-ShuttleControlTablet.desc} + .suffix = Без батареи + +ent-ShuttleControlTabletMicroreactor = {ent-ShuttleControlTablet} + .desc = {ent-ShuttleControlTablet.desc} + .suffix = Микрореакторная батарея + +ent-ShuttleControlTabletSalvage = {ent-ShuttleControlTablet} + .desc = {ent-ShuttleControlTablet.desc} + .suffix = Утилизаторский + +ent-ShuttleControlTabletSecurity = {ent-ShuttleControlTablet} + .desc = {ent-ShuttleControlTablet.desc} + .suffix = Служба безопасности + +ent-ShuttleControlTabletSyndicate = {ent-ShuttleControlTablet} + .desc = {ent-ShuttleControlTablet.desc} + .suffix = Синдикат + +shuttle-tablet-id-slot = Слот ID карты + +shuttle-tablet-no-remote-console = На шаттле не найдена запитанная консоль. +shuttle-tablet-no-id = Вставьте ID карту. +shuttle-tablet-no-deed = На карте должен быть судовой акт на шаттл. +shuttle-tablet-no-power = Недостаточно питания. +shuttle-tablet-emergency-locked = Консоль аварийно заблокирована. diff --git a/Resources/Prototypes/_Lua/Entities/Objects/Tools/shuttletablet.yml b/Resources/Prototypes/_Lua/Entities/Objects/Tools/shuttletablet.yml new file mode 100644 index 00000000000..dd9a69e870f --- /dev/null +++ b/Resources/Prototypes/_Lua/Entities/Objects/Tools/shuttletablet.yml @@ -0,0 +1,121 @@ +# LuaWorld - This file is licensed under AGPLv3 +# Copyright (c) 2026 LuaWorld Contributors +# See AGPLv3.txt for details. + +- type: entity + name: shuttle control tablet + parent: BaseHandheldComputer + id: ShuttleControlTablet + description: A portable tablet for shuttle control. Has a slot for ID card. To function at least one powered console must be present at the shuttle. + components: + - type: Item + sprite: _Lua/Objects/Tools/handheldshuttleconsole.rsi + - type: Sprite + sprite: _Lua/Objects/Tools/handheldshuttleconsole.rsi + state: default + - type: ShuttleTablet + - type: ShuttleConsole + zoom: 1.0, 1.0 + - type: ShuttleConsoleLock + locked: false + - type: ActivatableUI + key: enum.ShuttleConsoleUiKey.Key + - type: UserInterface + interfaces: + enum.ShuttleConsoleUiKey.Key: + type: ShuttleConsoleBoundUserInterface + - type: RadarConsole + maxRange: 512 + maxIffRange: 512 + - type: DetectionRangeMultiplier + infraredMultiplier: 2 + visualMultiplier: 16 + infraredOutlinePortion: 1.0 + - type: Appearance + - type: ItemSlots + slots: + id_container: + name: shuttle-tablet-id-slot + priority: 3 + whitelist: + components: + - IdCard + cell_slot: + name: power-cell-slot-component-slot-name-default + startingItem: PowerCellSmall + - type: ContainerContainer + containers: + id_container: !type:ContainerSlot + cell_slot: !type:ContainerSlot + - type: DeviceLinkSource + ports: + - device-button-1 + - device-button-2 + - device-button-3 + - device-button-4 + - device-button-5 + - device-button-6 + - device-button-7 + - device-button-8 + range: 3 + - type: PowerCellDraw + drawRate: 1.5 + - type: StaticPrice + price: 250 + +- type: entity + id: ShuttleControlTabletMicroreactor + parent: ShuttleControlTablet + suffix: Microreactor + components: + - type: ItemSlots + slots: + id_container: + name: shuttle-tablet-id-slot + priority: 3 + whitelist: + components: + - IdCard + cell_slot: + name: power-cell-slot-component-slot-name-default + startingItem: PowerCellMicroreactor + +- type: entity + id: ShuttleControlTabletEmpty + parent: ShuttleControlTablet + suffix: Empty + components: + - type: ItemSlots + slots: + id_container: + name: shuttle-tablet-id-slot + priority: 3 + whitelist: + components: + - IdCard + cell_slot: + name: power-cell-slot-component-slot-name-default + +- type: entity + parent: ShuttleControlTablet + id: ShuttleControlTabletSalvage + suffix: Salvage + components: + - type: Sprite + state: salvage + +- type: entity + parent: ShuttleControlTablet + id: ShuttleControlTabletSecurity + suffix: Security + components: + - type: Sprite + state: security + +- type: entity + parent: ShuttleControlTablet + id: ShuttleControlTabletSyndicate + suffix: Syndicate + components: + - type: Sprite + state: syndicate diff --git a/Resources/Textures/_Lua/Objects/Tools/handheldshuttleconsole.rsi/default.png b/Resources/Textures/_Lua/Objects/Tools/handheldshuttleconsole.rsi/default.png new file mode 100644 index 00000000000..65b7d076116 Binary files /dev/null and b/Resources/Textures/_Lua/Objects/Tools/handheldshuttleconsole.rsi/default.png differ diff --git a/Resources/Textures/_Lua/Objects/Tools/handheldshuttleconsole.rsi/meta.json b/Resources/Textures/_Lua/Objects/Tools/handheldshuttleconsole.rsi/meta.json new file mode 100644 index 00000000000..41048a78d14 --- /dev/null +++ b/Resources/Textures/_Lua/Objects/Tools/handheldshuttleconsole.rsi/meta.json @@ -0,0 +1,23 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Made by discord: not_so_big_chungus", + "states": [ + { + "name": "salvage" + }, + { + "name": "security" + }, + { + "name": "syndicate" + }, + { + "name": "default" + } + ] +} diff --git a/Resources/Textures/_Lua/Objects/Tools/handheldshuttleconsole.rsi/salvage.png b/Resources/Textures/_Lua/Objects/Tools/handheldshuttleconsole.rsi/salvage.png new file mode 100644 index 00000000000..17b97ed4e82 Binary files /dev/null and b/Resources/Textures/_Lua/Objects/Tools/handheldshuttleconsole.rsi/salvage.png differ diff --git a/Resources/Textures/_Lua/Objects/Tools/handheldshuttleconsole.rsi/security.png b/Resources/Textures/_Lua/Objects/Tools/handheldshuttleconsole.rsi/security.png new file mode 100644 index 00000000000..5147f233e28 Binary files /dev/null and b/Resources/Textures/_Lua/Objects/Tools/handheldshuttleconsole.rsi/security.png differ diff --git a/Resources/Textures/_Lua/Objects/Tools/handheldshuttleconsole.rsi/syndicate.png b/Resources/Textures/_Lua/Objects/Tools/handheldshuttleconsole.rsi/syndicate.png new file mode 100644 index 00000000000..7d14f1e28ce Binary files /dev/null and b/Resources/Textures/_Lua/Objects/Tools/handheldshuttleconsole.rsi/syndicate.png differ diff --git a/runall.bat b/runall.bat index 38ea1e598bd..47940b8595a 100644 --- a/runall.bat +++ b/runall.bat @@ -2,6 +2,6 @@ set PDIR=%~dp0 cd %PDIR%Bin\Content.Server start Content.Server.exe cd %PDIR%Bin\Content.Client -start Content.Client.exe +call Content.Client.exe cd %PDIR% set PDIR= \ No newline at end of file