Skip to content

Commit

Permalink
РРТ + лицензия (#166)
Browse files Browse the repository at this point in the history
<!-- ЭТО ШАБЛОН ВАШЕГО PULL REQUEST. Текст между стрелками - это
комментарии - они не будут видны в PR. -->

## Описание PR
По просьбе Швондера и Петра добавил лицензию с фронтира. Она начинает
действовать после этого пулла. Также добавил РРТ - аналог РСУ для
атмосов.
<!-- Ниже опишите ваш Pull Request. Что он изменяет? На что еще это
может повлиять? Постарайтесь описать все внесённые вами изменения! -->

<!-- Если приемлемо, добавьте скриншоты для демонстрации вашего PR. Если
ваш PR представляет собой визуальное изменение, добавьте
скриншоты, иначе он может быть закрыт. -->

**Проверки**
<!-- Выполнение всех следующих действий, если это приемлемо для вида
изменений сильно ускорит разбор вашего PR -->
- [x] PR полностью завершён и мне не нужна помощь чтобы его закончить.
- [x] Я внимательно просмотрел все свои изменения и багов в них не
нашёл.
- [x] Я запускал локальный сервер со своими изменениями и всё
протестировал.
- [ ] Я добавил скриншот/видео демонстрации PR в игре, **или** этот PR
этого не требует.

**Изменения**
:cl: KashRas2
- add: Добавлен РРТ. Теперь атмосы стали намного лучше.
<!--
Здесь вы можете написать список изменений, который будет автоматически
добавлен в игру, когда ваш PR будет принят.

В журнал изменений следует помещать только то, что действительно важно
игрокам.

В списке изменений тип значка не является часть предложения, поэтому
явно указывайте - Добавлен, Удалён, Изменён.
плохо: - add: Новый инструмент для инженеров
хорошо: - add: Добавлен новый инструмент для инженеров

Вы можете указать своё имя после символа :cl: именно оно будет
отображаться в журнале изменений (иначе будет использоваться ваше имя на
GitHub)
Например: :cl: Ian

-->

---------

Co-authored-by: KashRas2 <[email protected]>
  • Loading branch information
KashRas2 and KashRas authored Aug 2, 2024
1 parent 11e041d commit 8bc6168
Show file tree
Hide file tree
Showing 95 changed files with 3,023 additions and 40 deletions.
117 changes: 117 additions & 0 deletions Content.Client/ADT/RPD/AlignRPDConstruction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using System.Numerics;
using Content.Client.Gameplay;
using Content.Shared.Hands.Components;
using Content.Shared.Interaction;
using Content.Shared.ADT.RPD.Components;
using Content.Shared.ADT.RPD.Systems;
using Robust.Client.Placement;
using Robust.Client.Player;
using Robust.Client.State;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;

namespace Content.Client.ADT.RPD;

public sealed class AlignRPDConstruction : PlacementMode
{
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
private readonly SharedMapSystem _mapSystem;
private readonly RPDSystem _rpdSystem;
private readonly SharedTransformSystem _transformSystem;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IStateManager _stateManager = default!;

private const float SearchBoxSize = 2f;
private const float PlaceColorBaseAlpha = 0.5f;

private EntityCoordinates _unalignedMouseCoords = default;

/// <summary>
/// This placement mode is not on the engine because it is content specific (i.e., for the RPD)
/// </summary>
public AlignRPDConstruction(PlacementManager pMan) : base(pMan)
{
IoCManager.InjectDependencies(this);
_mapSystem = _entityManager.System<SharedMapSystem>();
_rpdSystem = _entityManager.System<RPDSystem>();
_transformSystem = _entityManager.System<SharedTransformSystem>();

ValidPlaceColor = ValidPlaceColor.WithAlpha(PlaceColorBaseAlpha);
}

public override void AlignPlacementMode(ScreenCoordinates mouseScreen)
{
_unalignedMouseCoords = ScreenToCursorGrid(mouseScreen);
MouseCoords = _unalignedMouseCoords.AlignWithClosestGridTile(SearchBoxSize, _entityManager, _mapManager);

var gridId = MouseCoords.GetGridUid(_entityManager);

if (!_entityManager.TryGetComponent<MapGridComponent>(gridId, out var mapGrid))
return;

CurrentTile = _mapSystem.GetTileRef(gridId.Value, mapGrid, MouseCoords);

float tileSize = mapGrid.TileSize;
GridDistancing = tileSize;

if (pManager.CurrentPermission!.IsTile)
{
MouseCoords = new EntityCoordinates(MouseCoords.EntityId, new Vector2(CurrentTile.X + tileSize / 2,
CurrentTile.Y + tileSize / 2));
}
else
{
MouseCoords = new EntityCoordinates(MouseCoords.EntityId, new Vector2(CurrentTile.X + tileSize / 2 + pManager.PlacementOffset.X,
CurrentTile.Y + tileSize / 2 + pManager.PlacementOffset.Y));
}
}

public override bool IsValidPosition(EntityCoordinates position)
{
var player = _playerManager.LocalSession?.AttachedEntity;

// If the destination is out of interaction range, set the placer alpha to zero
if (!_entityManager.TryGetComponent<TransformComponent>(player, out var xform))
return false;

if (!xform.Coordinates.InRange(_entityManager, _transformSystem, position, SharedInteractionSystem.InteractionRange))
{
InvalidPlaceColor = InvalidPlaceColor.WithAlpha(0);
return false;
}

// Otherwise restore the alpha value
else
{
InvalidPlaceColor = InvalidPlaceColor.WithAlpha(PlaceColorBaseAlpha);
}

// Determine if player is carrying an RPD in their active hand
if (!_entityManager.TryGetComponent<HandsComponent>(player, out var hands))
return false;

var heldEntity = hands.ActiveHand?.HeldEntity;

if (!_entityManager.TryGetComponent<RPDComponent>(heldEntity, out var rpd))
return false;

// Retrieve the map grid data for the position
if (!_rpdSystem.TryGetMapGridData(position, out var mapGridData))
return false;

// Determine if the user is hovering over a target
var currentState = _stateManager.CurrentState;

if (currentState is not GameplayStateBase screen)
return false;

var target = screen.GetClickedEntity(_unalignedMouseCoords.ToMap(_entityManager, _transformSystem));

// Determine if the RPD operation is valid or not
if (!_rpdSystem.IsRPDOperationStillValid(heldEntity.Value, rpd, mapGridData.Value, target, player.Value, false))
return false;

return true;
}
}
77 changes: 77 additions & 0 deletions Content.Client/ADT/RPD/RPDConstructionGhostSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using Content.Shared.Hands.Components;
using Content.Shared.Interaction;
using Content.Shared.ADT.RPD;
using Content.Shared.ADT.RPD.Components;
using Content.Shared.ADT.RPD.Systems;
using Robust.Client.Placement;
using Robust.Client.Player;
using Robust.Shared.Enums;

namespace Content.Client.ADT.RPD;

public sealed class RPDConstructionGhostSystem : EntitySystem
{
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly RPDSystem _rpdSystem = default!;
[Dependency] private readonly IPlacementManager _placementManager = default!;

private string _placementMode = typeof(AlignRPDConstruction).Name;
private Direction _placementDirection = default;

public override void Update(float frameTime)
{
base.Update(frameTime);

// Get current placer data
var placerEntity = _placementManager.CurrentPermission?.MobUid;
var placerProto = _placementManager.CurrentPermission?.EntityType;
var placerIsRPD = HasComp<RPDComponent>(placerEntity);

// Exit if erasing or the current placer is not an RPD (build mode is active)
if (_placementManager.Eraser || (placerEntity != null && !placerIsRPD))
return;

// Determine if player is carrying an RPD in their active hand
var player = _playerManager.LocalSession?.AttachedEntity;

if (!TryComp<HandsComponent>(player, out var hands))
return;

var heldEntity = hands.ActiveHand?.HeldEntity;

if (!TryComp<RPDComponent>(heldEntity, out var rpd))
{
// If the player was holding an RPD, but is no longer, cancel placement
if (placerIsRPD)
_placementManager.Clear();

return;
}

// Update the direction the RPD prototype based on the placer direction
if (_placementDirection != _placementManager.Direction)
{
_placementDirection = _placementManager.Direction;
RaiseNetworkEvent(new RPDConstructionGhostRotationEvent(GetNetEntity(heldEntity.Value), _placementDirection));
}

// If the placer has not changed, exit
_rpdSystem.UpdateCachedPrototype(heldEntity.Value, rpd);

if (heldEntity == placerEntity && rpd.CachedPrototype.Prototype == placerProto)
return;

// Create a new placer
var newObjInfo = new PlacementInformation
{
MobUid = heldEntity.Value,
PlacementOption = _placementMode,
EntityType = rpd.CachedPrototype.Prototype,
Range = (int) Math.Ceiling(SharedInteractionSystem.InteractionRange),
UseEditorContext = false,
};

_placementManager.Clear();
_placementManager.BeginPlacing(newObjInfo);
}
}
35 changes: 35 additions & 0 deletions Content.Client/ADT/RPD/RPDMenu.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<ui:RadialMenu xmlns="https://spacestation14.io"
xmlns:ui="clr-namespace:Content.Client.UserInterface.Controls"
xmlns:rpd="clr-namespace:Content.Client.RPD"
BackButtonStyleClass="RadialMenuBackButton"
CloseButtonStyleClass="RadialMenuCloseButton"
VerticalExpand="True"
HorizontalExpand="True"
MinSize="450 450">

<!-- Note: The min size of the window just determine how close to the edge of the screen the center of the radial menu can be placed -->
<!-- The radial menu will try to open so that its center is located where the player's cursor is currently -->

<!-- Entry layer (shows main categories) -->
<ui:RadialContainer Name="Main" VerticalExpand="True" HorizontalExpand="True" Radius="64" ReserveSpaceForHiddenChildren="False">
<ui:RadialMenuTextureButton StyleClasses="RadialMenuButton" SetSize="64 64" ToolTip="{Loc 'rpd-component-DisposalPipe'}" TargetLayer="DisposalPipe" Visible="False">
<TextureRect VerticalAlignment="Center" HorizontalAlignment="Center" TextureScale="2 2" TexturePath="/Textures/ADT/Interface/Radial/RPD/DisposalPipe.png"/>
</ui:RadialMenuTextureButton>
<ui:RadialMenuTextureButton StyleClasses="RadialMenuButton" SetSize="64 64" ToolTip="{Loc 'rpd-component-Gaspipes'}" TargetLayer="Gaspipes" Visible="False">
<TextureRect VerticalAlignment="Center" HorizontalAlignment="Center" TextureScale="2 2" TexturePath="/Textures/ADT/Interface/Radial/RPD/Gaspipes.png"/>
</ui:RadialMenuTextureButton>
<ui:RadialMenuTextureButton StyleClasses="RadialMenuButton" SetSize="64 64" ToolTip="{Loc 'rpd-component-Devices'}" TargetLayer="Devices" Visible="False">
<TextureRect VerticalAlignment="Center" HorizontalAlignment="Center" TextureScale="2 2" TexturePath="/Textures/ADT/Interface/Radial/RPD/Devices.png"/>
</ui:RadialMenuTextureButton>
</ui:RadialContainer>

<!-- DisposalPipe -->
<ui:RadialContainer Name="DisposalPipe" VerticalExpand="True" HorizontalExpand="True" Radius="64"/>

<!-- Gaspipes -->
<ui:RadialContainer Name="Gaspipes" VerticalExpand="True" HorizontalExpand="True" Radius="64"/>

<!-- Devices -->
<ui:RadialContainer Name="Devices" VerticalExpand="True" HorizontalExpand="True" Radius="64"/>

</ui:RadialMenu>
167 changes: 167 additions & 0 deletions Content.Client/ADT/RPD/RPDMenu.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
using Content.Client.UserInterface.Controls;
using Content.Shared.Popups;
using Content.Shared.ADT.RPD;
using Content.Shared.ADT.RPD.Components;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using System.Numerics;

namespace Content.Client.ADT.RPD;

[GenerateTypedNameReferences]
public sealed partial class RPDMenu : RadialMenu
{
[Dependency] private readonly EntityManager _entManager = default!;
[Dependency] private readonly IPrototypeManager _protoManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;

private readonly SpriteSystem _spriteSystem;
private readonly SharedPopupSystem _popup;

public event Action<ProtoId<RPDPrototype>>? SendRPDSystemMessageAction;

private EntityUid _owner;

public RPDMenu(EntityUid owner, RPDMenuBoundUserInterface bui)
{
IoCManager.InjectDependencies(this);
RobustXamlLoader.Load(this);

_spriteSystem = _entManager.System<SpriteSystem>();
_popup = _entManager.System<SharedPopupSystem>();

_owner = owner;

var main = FindControl<RadialContainer>("Main");

if (main == null)
return;

if (!_entManager.TryGetComponent<RPDComponent>(owner, out var rpd))
return;

foreach (var protoId in rpd.AvailablePrototypes)
{
if (!_protoManager.TryIndex(protoId, out var proto))
continue;

if (proto.Mode == RpdMode.Invalid)
continue;

var parent = FindControl<RadialContainer>(proto.Category);

if (parent == null)
continue;

var tooltip = Loc.GetString(proto.SetName);

tooltip = OopsConcat(char.ToUpper(tooltip[0]).ToString(), tooltip.Remove(0, 1));

var button = new RPDMenuButton()
{
StyleClasses = { "RadialMenuButton" },
SetSize = new Vector2(64f, 64f),
ToolTip = tooltip,
ProtoId = protoId,
};

if (proto.Sprite != null)
{
var tex = new TextureRect()
{
VerticalAlignment = VAlignment.Center,
HorizontalAlignment = HAlignment.Center,
Texture = _spriteSystem.Frame0(proto.Sprite),
TextureScale = new Vector2(2f, 2f),
};

button.AddChild(tex);
}

parent.AddChild(button);

foreach (var child in main.Children)
{
var castChild = child as RadialMenuTextureButton;

if (castChild is not RadialMenuTextureButton)
continue;

if (castChild.TargetLayer == proto.Category)
{
castChild.Visible = true;
break;
}
}
}

foreach (var child in Children)
AddRPDMenuButtonOnClickActions(child);

OnChildAdded += AddRPDMenuButtonOnClickActions;

SendRPDSystemMessageAction += bui.SendRPDSystemMessage;
}

private static string OopsConcat(string a, string b)
{
return a + b;
}

private void AddRPDMenuButtonOnClickActions(Control control)
{
var radialContainer = control as RadialContainer;

if (radialContainer == null)
return;

foreach (var child in radialContainer.Children)
{
var castChild = child as RPDMenuButton;

if (castChild == null)
continue;

castChild.OnButtonUp += _ =>
{
SendRPDSystemMessageAction?.Invoke(castChild.ProtoId);

if (_playerManager.LocalSession?.AttachedEntity != null &&
_protoManager.TryIndex(castChild.ProtoId, out var proto))
{
var msg = Loc.GetString("rpd-component-change-mode", ("mode", Loc.GetString(proto.SetName)));

if (proto.Mode == RpdMode.ConstructObject)
{
var name = Loc.GetString(proto.SetName);

if (proto.Prototype != null &&
_protoManager.TryIndex(proto.Prototype, out var entProto))
name = entProto.Name;

msg = Loc.GetString("rpd-component-change-build-mode", ("name", name));
}

_popup.PopupClient(msg, _owner, _playerManager.LocalSession.AttachedEntity);
}

Close();
};
}
}
}

public sealed class RPDMenuButton : RadialMenuTextureButton
{
public ProtoId<RPDPrototype> ProtoId { get; set; }

public RPDMenuButton()
{

}
}
Loading

0 comments on commit 8bc6168

Please sign in to comment.