Merge branch 'master' into ed-10-06-2025-upstream-sync
This commit is contained in:
7
.github/ISSUE_TEMPLATE/config.yml
vendored
7
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,7 +0,0 @@
|
||||
contact_links:
|
||||
- name: Report a Security Vulnerability
|
||||
url: https://github.com/space-wizards/space-station-14/blob/master/SECURITY.md
|
||||
about: Please report security vulnerabilities privately so we can fix them before they are publicly disclosed.
|
||||
- name: Request a Feature
|
||||
url: https://discord.gg/rGvu9hKffJ
|
||||
about: Submit feature requests on our Discord server (https://discord.gg/rGvu9hKffJ).
|
||||
20
.github/ISSUE_TEMPLATE/issue_report.md
vendored
20
.github/ISSUE_TEMPLATE/issue_report.md
vendored
@@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Report an Issue
|
||||
about: "..."
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Description
|
||||
<!-- Explain your issue in detail. Issues without proper explanation are liable to be closed by maintainers. -->
|
||||
|
||||
**Reproduction**
|
||||
<!-- Include the steps to reproduce if applicable. -->
|
||||
|
||||
**Screenshots**
|
||||
<!-- If applicable, add screenshots to help explain your problem. -->
|
||||
|
||||
**Additional context**
|
||||
<!-- Add any other context about the problem here. Anything you think is related to the issue. -->
|
||||
@@ -1,18 +0,0 @@
|
||||
---
|
||||
name: Toolshed feature request
|
||||
about: Suggest a feature for Toolshed (for game admins/developers)
|
||||
title: "[TOOLSHED REQUEST]"
|
||||
labels: Toolshed
|
||||
assignees: moonheart08
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem/bug? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the command you'd like**
|
||||
A clear and concise description of what you want and what it should do.
|
||||
If you're a technical user (i.e. programmer) including type signatures is helpful.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
83
Content.Client/_CP14/Religion/CP14ClientReligionGodSystem.cs
Normal file
83
Content.Client/_CP14/Religion/CP14ClientReligionGodSystem.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
using Content.Shared._CP14.Religion.Components;
|
||||
using Content.Shared._CP14.Religion.Prototypes;
|
||||
using Content.Shared._CP14.Religion.Systems;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client._CP14.Religion;
|
||||
|
||||
public sealed partial class CP14ClientReligionGodSystem : CP14SharedReligionGodSystem
|
||||
{
|
||||
[Dependency] private readonly IOverlayManager _overlayMgr = default!;
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
|
||||
private CP14ReligionVisionOverlay? _overlay;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<CP14ReligionVisionComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
|
||||
SubscribeLocalEvent<CP14ReligionVisionComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
|
||||
SubscribeLocalEvent<CP14ReligionVisionComponent, ComponentInit>(OnOverlayInit);
|
||||
SubscribeLocalEvent<CP14ReligionVisionComponent, ComponentRemove>(OnOverlayRemove);
|
||||
}
|
||||
|
||||
public override void SendMessageToGods(ProtoId<CP14ReligionPrototype> religion, string msg, EntityUid source) { }
|
||||
|
||||
public override void Shutdown()
|
||||
{
|
||||
base.Shutdown();
|
||||
_overlayMgr.RemoveOverlay<CP14ReligionVisionOverlay>();
|
||||
}
|
||||
|
||||
private void OnPlayerAttached(Entity<CP14ReligionVisionComponent> ent, ref LocalPlayerAttachedEvent args)
|
||||
{
|
||||
AddOverlay();
|
||||
}
|
||||
|
||||
private void OnPlayerDetached(Entity<CP14ReligionVisionComponent> ent, ref LocalPlayerDetachedEvent args)
|
||||
{
|
||||
RemoveOverlay();
|
||||
}
|
||||
|
||||
private void OnOverlayInit(Entity<CP14ReligionVisionComponent> ent, ref ComponentInit args)
|
||||
{
|
||||
var attachedEnt = _player.LocalEntity;
|
||||
|
||||
if (attachedEnt != ent.Owner)
|
||||
return;
|
||||
|
||||
AddOverlay();
|
||||
}
|
||||
|
||||
private void OnOverlayRemove(Entity<CP14ReligionVisionComponent> ent, ref ComponentRemove args)
|
||||
{
|
||||
var attachedEnt = _player.LocalEntity;
|
||||
|
||||
if (attachedEnt != ent.Owner)
|
||||
return;
|
||||
|
||||
RemoveOverlay();
|
||||
}
|
||||
|
||||
private void AddOverlay()
|
||||
{
|
||||
if (_overlay != null)
|
||||
return;
|
||||
|
||||
_overlay = new CP14ReligionVisionOverlay();
|
||||
_overlayMgr.AddOverlay(_overlay);
|
||||
}
|
||||
|
||||
private void RemoveOverlay()
|
||||
{
|
||||
if (_overlay == null)
|
||||
return;
|
||||
|
||||
_overlayMgr.RemoveOverlay(_overlay);
|
||||
_overlay = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using Content.Client._CP14.DemiplaneTraveling;
|
||||
using Content.Shared._CP14.DemiplaneTraveling;
|
||||
using Content.Shared._CP14.Religion.Systems;
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
namespace Content.Client._CP14.Religion;
|
||||
|
||||
public sealed class CP14ReligionEntityBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
private CP14ReligionEntityWindow? _window;
|
||||
|
||||
public CP14ReligionEntityBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_window = this.CreateWindow<CP14ReligionEntityWindow>();
|
||||
|
||||
_window.OnTeleportAttempt += netId => SendMessage(new CP14ReligionEntityTeleportAttempt(netId));
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
if (_window == null || state is not CP14ReligionEntityUiState mapState)
|
||||
return;
|
||||
|
||||
_window?.UpdateState(mapState);
|
||||
}
|
||||
}
|
||||
28
Content.Client/_CP14/Religion/CP14ReligionEntityWindow.xaml
Normal file
28
Content.Client/_CP14/Religion/CP14ReligionEntityWindow.xaml
Normal file
@@ -0,0 +1,28 @@
|
||||
<religion:CP14ReligionEntityWindow
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:religion="clr-namespace:Content.Client._CP14.Religion"
|
||||
Title="{Loc 'cp14-god-ui-title'}"
|
||||
SetSize="600 500"
|
||||
MinSize="600 100">
|
||||
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" VerticalExpand="True">
|
||||
<ScrollContainer HorizontalExpand="True" VerticalExpand="True">
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True">
|
||||
<Label Name="Altars" Text="{Loc 'cp14-god-ui-altars'}" Access="Public" StyleClasses="LabelHeadingBigger" VAlign="Center" HorizontalExpand="True" HorizontalAlignment="Center"/>
|
||||
<BoxContainer
|
||||
Name="AltarsContainer"
|
||||
Orientation="Vertical"
|
||||
HorizontalExpand="True" />
|
||||
|
||||
<Label Name="Followers" Text="{Loc 'cp14-god-ui-follower'}" Access="Public" StyleClasses="LabelHeadingBigger" VAlign="Center" HorizontalExpand="True" HorizontalAlignment="Center" Margin="0, 30, 0, 0"/>
|
||||
<BoxContainer
|
||||
Name="FollowersContainer"
|
||||
Orientation="Vertical"
|
||||
HorizontalExpand="True" />
|
||||
</BoxContainer>
|
||||
</ScrollContainer>
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True">
|
||||
<RichTextLabel Name="Status"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</religion:CP14ReligionEntityWindow>
|
||||
@@ -0,0 +1,74 @@
|
||||
using System.Text;
|
||||
using Content.Shared._CP14.Religion.Systems;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client._CP14.Religion;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class CP14ReligionEntityWindow : DefaultWindow
|
||||
{
|
||||
[Dependency] private readonly ILogManager _log = default!;
|
||||
|
||||
private ISawmill Sawmill { get; init; }
|
||||
|
||||
public event Action<NetEntity>? OnTeleportAttempt;
|
||||
|
||||
public CP14ReligionEntityWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
Sawmill = _log.GetSawmill("cp14_religion_entity_window");
|
||||
}
|
||||
|
||||
public void UpdateState(CP14ReligionEntityUiState state)
|
||||
{
|
||||
AltarsContainer.RemoveAllChildren();
|
||||
FollowersContainer.RemoveAllChildren();
|
||||
|
||||
Altars.Visible = state.Altars.Count > 0;
|
||||
Followers.Visible = state.Followers.Count > 0;
|
||||
|
||||
foreach (var (netId, name) in state.Altars)
|
||||
{
|
||||
var btn = new Button
|
||||
{
|
||||
Text = name,
|
||||
HorizontalAlignment = HAlignment.Center
|
||||
};
|
||||
|
||||
btn.OnPressed += _ =>
|
||||
{
|
||||
OnTeleportAttempt?.Invoke(netId);
|
||||
};
|
||||
AltarsContainer.AddChild(btn);
|
||||
}
|
||||
|
||||
foreach (var (netId, name) in state.Followers)
|
||||
{
|
||||
var btn = new Button
|
||||
{
|
||||
Text = name,
|
||||
HorizontalAlignment = HAlignment.Center
|
||||
};
|
||||
|
||||
btn.OnPressed += _ =>
|
||||
{
|
||||
OnTeleportAttempt?.Invoke(netId);
|
||||
};
|
||||
FollowersContainer.AddChild(btn);
|
||||
}
|
||||
Status.Text = GetStatusText(state);
|
||||
}
|
||||
|
||||
private string GetStatusText(CP14ReligionEntityUiState state)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.Append(Loc.GetString("cp14-god-ui-follower-percentage", ("count", state.FollowerPercentage * 100)) + "\n");
|
||||
sb.Append(Loc.GetString("cp14-god-ui-mana-percentage", ("count", state.ManaPercentage * 100)) + "\n");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
146
Content.Client/_CP14/Religion/CP14ReligionVisionOverlay.cs
Normal file
146
Content.Client/_CP14/Religion/CP14ReligionVisionOverlay.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared._CP14.Religion.Components;
|
||||
using Content.Shared._CP14.Religion.Prototypes;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client._CP14.Religion;
|
||||
|
||||
public sealed class CP14ReligionVisionOverlay : Overlay
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
|
||||
private readonly SharedTransformSystem _transform;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum number of observers zones that can be shown on screen at a time.
|
||||
/// If this value is changed, the shader itself also needs to be updated.
|
||||
/// </summary>
|
||||
public const int MaxCount = 64;
|
||||
|
||||
public override bool RequestScreenTexture => true;
|
||||
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
||||
|
||||
private readonly ProtoId<CP14ReligionPrototype>? _religion = null;
|
||||
|
||||
private readonly ShaderInstance _religionShader;
|
||||
private readonly Vector2[] _positions = new Vector2[MaxCount];
|
||||
private readonly float[] _radii = new float[MaxCount];
|
||||
private int _count = 0;
|
||||
|
||||
public CP14ReligionVisionOverlay()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
_religionShader = _proto.Index<ShaderPrototype>("CP14ReligionVision").InstanceUnique();
|
||||
|
||||
_transform = _entManager.System<SharedTransformSystem>();
|
||||
|
||||
if (_entManager.TryGetComponent<CP14ReligionEntityComponent>(_player.LocalEntity, out var vision))
|
||||
_religion = vision.Religion;
|
||||
}
|
||||
|
||||
protected override bool BeforeDraw(in OverlayDrawArgs args)
|
||||
{
|
||||
if (args.Viewport.Eye == null)
|
||||
return false;
|
||||
|
||||
_count = 0;
|
||||
|
||||
var clusters = new List<Cluster>();
|
||||
var religionQuery = _entManager.AllEntityQueryEnumerator<CP14ReligionObserverComponent, TransformComponent>();
|
||||
while (religionQuery.MoveNext(out var uid, out var rel, out var xform))
|
||||
{
|
||||
if (_religion is null)
|
||||
continue;
|
||||
|
||||
var observation = rel.Observation;
|
||||
if (!observation.ContainsKey(_religion.Value))
|
||||
continue;
|
||||
|
||||
if (!rel.Active || xform.MapID != args.MapId)
|
||||
continue;
|
||||
|
||||
var mapPos = _transform.GetWorldPosition(uid);
|
||||
|
||||
// To be clear, this needs to use "inside-viewport" pixels.
|
||||
// In other words, specifically NOT IViewportControl.WorldToScreen (which uses outer coordinates).
|
||||
var tempCoords = args.Viewport.WorldToLocal(mapPos);
|
||||
tempCoords.Y = args.Viewport.Size.Y - tempCoords.Y; // Local space to fragment space.
|
||||
|
||||
// try find cluster to merge with
|
||||
bool merged = false;
|
||||
foreach (var cluster in clusters)
|
||||
{
|
||||
if ((cluster.Position - tempCoords).Length() < 150f)
|
||||
{
|
||||
cluster.Add(tempCoords, rel.Observation[_religion.Value]);
|
||||
merged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!merged)
|
||||
clusters.Add(new Cluster(tempCoords, rel.Observation[_religion.Value]));
|
||||
|
||||
if (clusters.Count >= MaxCount)
|
||||
break;
|
||||
}
|
||||
|
||||
_count = 0;
|
||||
foreach (var cluster in clusters)
|
||||
{
|
||||
_positions[_count] = cluster.Position;
|
||||
_radii[_count] = cluster.Radius;
|
||||
_count++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void Draw(in OverlayDrawArgs args)
|
||||
{
|
||||
if (ScreenTexture == null || args.Viewport.Eye == null)
|
||||
return;
|
||||
|
||||
if (!_entManager.TryGetComponent<CP14ReligionVisionComponent>(_player.LocalEntity, out var visionComponent))
|
||||
return;
|
||||
|
||||
_religionShader?.SetParameter("shaderColor", visionComponent.ShaderColor);
|
||||
_religionShader?.SetParameter("renderScale", args.Viewport.RenderScale * args.Viewport.Eye.Scale);
|
||||
_religionShader?.SetParameter("count", _count);
|
||||
_religionShader?.SetParameter("position", _positions);
|
||||
_religionShader?.SetParameter("radius", _radii);
|
||||
_religionShader?.SetParameter("SCREEN_TEXTURE", ScreenTexture);
|
||||
|
||||
var worldHandle = args.WorldHandle;
|
||||
worldHandle.UseShader(_religionShader);
|
||||
worldHandle.DrawRect(args.WorldAABB, Color.White);
|
||||
worldHandle.UseShader(null);
|
||||
}
|
||||
|
||||
private sealed class Cluster
|
||||
{
|
||||
public Vector2 Position;
|
||||
public float Radius;
|
||||
public int Count;
|
||||
|
||||
public Cluster(Vector2 pos, float radius)
|
||||
{
|
||||
Position = pos;
|
||||
Radius = radius;
|
||||
Count = 1;
|
||||
}
|
||||
|
||||
public void Add(Vector2 pos, float radius)
|
||||
{
|
||||
Position = (Position * Count + pos) / (Count + 1);
|
||||
Radius = Math.Max(Radius, radius);
|
||||
Count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,9 @@ namespace Content.Client._CP14.UserInterface.Systems.NodeTree;
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class CP14NodeTreeGraphControl : BoxContainer
|
||||
{
|
||||
private const float LocalUIScaleMax = 4f;
|
||||
private const float LocalUIScaleMin = 1f;
|
||||
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
|
||||
private CP14NodeTreeUiState? _state;
|
||||
@@ -25,6 +28,9 @@ public sealed partial class CP14NodeTreeGraphControl : BoxContainer
|
||||
private bool _dragging = false;
|
||||
private Vector2 _previousMousePosition = Vector2.Zero;
|
||||
private Vector2 _globalOffset = new (60,60);
|
||||
private float _localUIScale = LocalUIScaleMin;
|
||||
|
||||
private float Scale => UIScale * _localUIScale;
|
||||
|
||||
public event Action<CP14NodeTreeElement?>? OnNodeSelected;
|
||||
public event Action<Vector2>? OnOffsetChanged;
|
||||
@@ -50,6 +56,16 @@ public sealed partial class CP14NodeTreeGraphControl : BoxContainer
|
||||
OnOffsetChanged?.Invoke(_globalOffset);
|
||||
}
|
||||
|
||||
protected override void MouseWheel(GUIMouseWheelEventArgs args)
|
||||
{
|
||||
base.MouseWheel(args);
|
||||
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
_localUIScale = MathHelper.Clamp(_localUIScale + 0.1f * args.Delta.Y, LocalUIScaleMin, LocalUIScaleMax);
|
||||
}
|
||||
|
||||
protected override void KeyBindDown(GUIBoundKeyEventArgs args)
|
||||
{
|
||||
base.KeyBindDown(args);
|
||||
@@ -72,6 +88,7 @@ public sealed partial class CP14NodeTreeGraphControl : BoxContainer
|
||||
if (args.Function == EngineKeyFunctions.UIRightClick)
|
||||
{
|
||||
_globalOffset = new Vector2(60, 60); // Reset offset on right click
|
||||
_localUIScale = LocalUIScaleMin;
|
||||
OnOffsetChanged?.Invoke(_globalOffset);
|
||||
}
|
||||
}
|
||||
@@ -107,7 +124,7 @@ public sealed partial class CP14NodeTreeGraphControl : BoxContainer
|
||||
if (_dragging)
|
||||
{
|
||||
var delta = cursor - _previousMousePosition;
|
||||
_globalOffset += delta;
|
||||
_globalOffset += delta;
|
||||
OnOffsetChanged?.Invoke(_globalOffset);
|
||||
}
|
||||
|
||||
@@ -118,8 +135,8 @@ public sealed partial class CP14NodeTreeGraphControl : BoxContainer
|
||||
{
|
||||
var node1 = _nodeDict[edge.Item1];
|
||||
var node2 = _nodeDict[edge.Item2];
|
||||
var fromPos = node1.UiPosition * UIScale + _globalOffset;
|
||||
var toPos = node2.UiPosition * UIScale + _globalOffset;
|
||||
var fromPos = node1.UiPosition * Scale + _globalOffset;
|
||||
var toPos = node2.UiPosition * Scale + _globalOffset;
|
||||
|
||||
var lineColor = node1.Gained || node2.Gained ? _state.ActiveLineColor : _state.LineColor;
|
||||
handle.DrawLine(fromPos, toPos, lineColor);
|
||||
@@ -128,11 +145,11 @@ public sealed partial class CP14NodeTreeGraphControl : BoxContainer
|
||||
//Draw Node icons over lines
|
||||
foreach (var node in _state.Nodes)
|
||||
{
|
||||
var pos = node.UiPosition * UIScale + _globalOffset;
|
||||
var pos = node.UiPosition * Scale + _globalOffset;
|
||||
|
||||
// Frame
|
||||
var frameTexture = _state.FrameIcon.Frame0();
|
||||
var frameSize = new Vector2(frameTexture.Width, frameTexture.Height) * 1.5f * UIScale;
|
||||
var frameSize = new Vector2(frameTexture.Width, frameTexture.Height) * 1.5f * Scale;
|
||||
var frameQuad = new UIBox2(pos - frameSize / 2, pos + frameSize / 2);
|
||||
handle.DrawTextureRect(frameTexture, frameQuad);
|
||||
|
||||
@@ -140,7 +157,7 @@ public sealed partial class CP14NodeTreeGraphControl : BoxContainer
|
||||
if (_selectedNode == node)
|
||||
{
|
||||
var selectedTexture = _state.SelectedIcon.Frame0();
|
||||
var selectedSize = new Vector2(selectedTexture.Width, selectedTexture.Height) * 1.5f * UIScale;
|
||||
var selectedSize = new Vector2(selectedTexture.Width, selectedTexture.Height) * 1.5f * Scale;
|
||||
var selectedQuad = new UIBox2(pos - selectedSize / 2, pos + selectedSize / 2);
|
||||
handle.DrawTextureRect(selectedTexture, selectedQuad);
|
||||
}
|
||||
@@ -151,7 +168,7 @@ public sealed partial class CP14NodeTreeGraphControl : BoxContainer
|
||||
{
|
||||
_hoveredNode = node;
|
||||
var hoveredTexture = _state.HoveredIcon.Frame0();
|
||||
var hoveredSize = new Vector2(hoveredTexture.Width, hoveredTexture.Height) * 1.5f * UIScale;
|
||||
var hoveredSize = new Vector2(hoveredTexture.Width, hoveredTexture.Height) * 1.5f * Scale;
|
||||
var hoveredQuad = new UIBox2(pos - hoveredSize / 2, pos + hoveredSize / 2);
|
||||
handle.DrawTextureRect(hoveredTexture, hoveredQuad);
|
||||
}
|
||||
@@ -160,7 +177,7 @@ public sealed partial class CP14NodeTreeGraphControl : BoxContainer
|
||||
if (node.Gained)
|
||||
{
|
||||
var learnedTexture = _state.LearnedIcon.Frame0();
|
||||
var learnedSize = new Vector2(learnedTexture.Width, learnedTexture.Height) * 1.5f * UIScale;
|
||||
var learnedSize = new Vector2(learnedTexture.Width, learnedTexture.Height) * 1.5f * Scale;
|
||||
var learnedQuad = new UIBox2(pos - learnedSize / 2, pos + learnedSize / 2);
|
||||
handle.DrawTextureRect(learnedTexture, learnedQuad);
|
||||
}
|
||||
@@ -169,7 +186,7 @@ public sealed partial class CP14NodeTreeGraphControl : BoxContainer
|
||||
if (node.Icon is not null)
|
||||
{
|
||||
var baseTexture = node.Icon.Frame0();
|
||||
var baseSize = new Vector2(baseTexture.Width, baseTexture.Height) * 1.5f * UIScale;
|
||||
var baseSize = new Vector2(baseTexture.Width, baseTexture.Height) * 1.5f * Scale;
|
||||
var baseQuad = new UIBox2(pos - baseSize / 2, pos + baseSize / 2);
|
||||
var tint = node.Gained || node.Active ? Color.White : Color.FromSrgb(new Color(0.6f, 0.6f, 0.6f));
|
||||
handle.DrawTextureRect(baseTexture, baseQuad, tint);
|
||||
|
||||
@@ -37,7 +37,6 @@ public sealed class CP14SkillUIController : UIController, IOnStateEntered<Gamepl
|
||||
private EntityUid? _targetPlayer;
|
||||
|
||||
private IEnumerable<CP14SkillPrototype> _allSkills = [];
|
||||
private IEnumerable<CP14SkillTreePrototype> _allTrees = [];
|
||||
|
||||
private CP14SkillPrototype? _selectedSkill;
|
||||
private CP14SkillTreePrototype? _selectedSkillTree;
|
||||
@@ -72,7 +71,6 @@ public sealed class CP14SkillUIController : UIController, IOnStateEntered<Gamepl
|
||||
private void CacheSkillProto()
|
||||
{
|
||||
_allSkills = _proto.EnumeratePrototypes<CP14SkillPrototype>();
|
||||
_allTrees = _proto.EnumeratePrototypes<CP14SkillTreePrototype>().OrderBy(tree => Loc.GetString(tree.Name));
|
||||
}
|
||||
|
||||
public void OnStateExited(GameplayState state)
|
||||
@@ -293,9 +291,9 @@ public sealed class CP14SkillUIController : UIController, IOnStateEntered<Gamepl
|
||||
//If tree not selected, select the first one
|
||||
if (_selectedSkillTree == null)
|
||||
{
|
||||
var firstTree = _allTrees.First();
|
||||
var firstTree = storage.AvailableSkillTrees.First();
|
||||
|
||||
SelectTree(firstTree, storage); // Set the first tree from the player's progress
|
||||
SelectTree(firstTree); // Set the first tree from the player's progress
|
||||
}
|
||||
|
||||
if (_selectedSkillTree == null)
|
||||
@@ -308,8 +306,11 @@ public sealed class CP14SkillUIController : UIController, IOnStateEntered<Gamepl
|
||||
_window.LevelLabel.Text = $"{storage.SkillsSumExperience}/{storage.ExperienceMaxCap}";
|
||||
|
||||
_window.TreeTabsContainer.RemoveAllChildren();
|
||||
foreach (var tree in _allTrees)
|
||||
foreach (var tree in storage.AvailableSkillTrees)
|
||||
{
|
||||
if (!_proto.TryIndex(tree, out var indexedTree))
|
||||
return;
|
||||
|
||||
float learnedPoints = 0;
|
||||
foreach (var skillId in storage.LearnedSkills)
|
||||
{
|
||||
@@ -322,25 +323,28 @@ public sealed class CP14SkillUIController : UIController, IOnStateEntered<Gamepl
|
||||
}
|
||||
}
|
||||
|
||||
var treeButton2 = new CP14SkillTreeButtonControl(tree.Color, Loc.GetString(tree.Name), learnedPoints);
|
||||
treeButton2.ToolTip = Loc.GetString(tree.Desc ?? string.Empty);
|
||||
var treeButton2 = new CP14SkillTreeButtonControl(indexedTree.Color, Loc.GetString(indexedTree.Name), learnedPoints);
|
||||
treeButton2.ToolTip = Loc.GetString(indexedTree.Desc ?? string.Empty);
|
||||
treeButton2.OnPressed += () =>
|
||||
{
|
||||
SelectTree(tree, storage);
|
||||
SelectTree(indexedTree);
|
||||
};
|
||||
|
||||
_window.TreeTabsContainer.AddChild(treeButton2);
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectTree(CP14SkillTreePrototype tree, CP14SkillStorageComponent storage)
|
||||
private void SelectTree(ProtoId<CP14SkillTreePrototype> tree)
|
||||
{
|
||||
if (_window == null)
|
||||
return;
|
||||
|
||||
_selectedSkillTree = tree;
|
||||
_window.ParallaxBackground.ParallaxPrototype = tree.Parallax;
|
||||
_window.TreeName.Text = Loc.GetString(tree.Name);
|
||||
if (!_proto.TryIndex(tree, out var indexedTree))
|
||||
return;
|
||||
|
||||
_selectedSkillTree = indexedTree;
|
||||
_window.ParallaxBackground.ParallaxPrototype = indexedTree.Parallax;
|
||||
_window.TreeName.Text = Loc.GetString(indexedTree.Name);
|
||||
|
||||
UpdateGraphControl();
|
||||
}
|
||||
|
||||
@@ -401,7 +401,7 @@ namespace Content.IntegrationTests.Tests
|
||||
var jobs = new HashSet<ProtoId<JobPrototype>>(comp.SetupAvailableJobs.Keys);
|
||||
|
||||
var spawnPoints = entManager.EntityQuery<SpawnPointComponent>()
|
||||
.Where(x => x.SpawnType == SpawnPointType.Job && x.Job != null)
|
||||
.Where(x => x.SpawnType is SpawnPointType.Job or SpawnPointType.Unset && x.Job != null) //CP14 Job or Unset (only Job in upstream)
|
||||
.Select(x => x.Job.Value);
|
||||
|
||||
jobs.ExceptWith(spawnPoints);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Content.Server._CP14.Religion;
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.Administration.Managers;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.Players.RateLimiting;
|
||||
using Content.Server.Speech.Prototypes;
|
||||
using Content.Server.Speech.EntitySystems;
|
||||
using Content.Server.Station.Components;
|
||||
@@ -193,6 +193,13 @@ public sealed partial class ChatSystem : SharedChatSystem
|
||||
if (!CanSendInGame(message, shell, player))
|
||||
return;
|
||||
|
||||
//CP14 Prevent god from default speaking. In waiting of chatcode refactor
|
||||
var ev = new CP14SpokeAttemptEvent(message, desiredType, player);
|
||||
RaiseLocalEvent(source, ev);
|
||||
if (ev.Cancelled)
|
||||
return;
|
||||
//CP14 end
|
||||
|
||||
ignoreActionBlocker = CheckIgnoreSpeechBlocker(source, ignoreActionBlocker);
|
||||
|
||||
// this method is a disaster
|
||||
|
||||
@@ -32,6 +32,15 @@ public sealed class SpawnPointSystem : EntitySystem
|
||||
if (args.Station != null && _stationSystem.GetOwningStation(uid, xform) != args.Station)
|
||||
continue;
|
||||
|
||||
//CP14 always spawn gods on gods spawnpoints
|
||||
if (spawnPoint.SpawnType == SpawnPointType.Unset && (args.Job == null || spawnPoint.Job == args.Job))
|
||||
{
|
||||
possiblePositions.Clear();
|
||||
possiblePositions.Add(xform.Coordinates);
|
||||
break;
|
||||
}
|
||||
//CP14end
|
||||
|
||||
if (_gameTicker.RunLevel == GameRunLevel.InRound && spawnPoint.SpawnType == SpawnPointType.LateJoin)
|
||||
{
|
||||
possiblePositions.Add(xform.Coordinates);
|
||||
|
||||
@@ -83,26 +83,13 @@ public sealed partial class CP14DemiplaneSystem
|
||||
|
||||
while (query.MoveNext(out var uid, out var stabilizer, out var xform))
|
||||
{
|
||||
if (!stabilizer.Enabled)
|
||||
continue;
|
||||
|
||||
if (TryTeleportOutDemiplane(demiplane, uid))
|
||||
{
|
||||
if (!safe)
|
||||
{
|
||||
var ev = new CP14DemiplaneUnsafeExit();
|
||||
RaiseLocalEvent(uid, ev);
|
||||
|
||||
_body.GibBody(uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QueueDel(demiplane);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CP14DemiplaneUnsafeExit : EntityEventArgs
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using Content.Server.Popups;
|
||||
using Content.Shared._CP14.Demiplane;
|
||||
using Content.Shared._CP14.Demiplane.Components;
|
||||
using Content.Shared._CP14.DemiplaneTraveling;
|
||||
using Content.Shared._CP14.Religion.Components;
|
||||
using Content.Shared.Ghost;
|
||||
using Content.Shared.Item;
|
||||
using Content.Shared.Movement.Pulling.Components;
|
||||
@@ -58,6 +59,8 @@ public sealed partial class CP14DemiplaneTravelingSystem : EntitySystem
|
||||
{
|
||||
if (HasComp<GhostComponent>(ent))
|
||||
continue;
|
||||
if (HasComp<CP14ReligionEntityComponent>(ent)) //TODO: make some generic way to whitelist entities from teleporting
|
||||
continue;
|
||||
|
||||
if (!_mind.TryGetMind(ent, out var mindId, out var mind))
|
||||
continue;
|
||||
@@ -114,6 +117,8 @@ public sealed partial class CP14DemiplaneTravelingSystem : EntitySystem
|
||||
{
|
||||
if (HasComp<GhostComponent>(ent))
|
||||
continue;
|
||||
if (HasComp<CP14ReligionEntityComponent>(ent)) //TODO: make some generic way to whitelist entities from teleporting
|
||||
continue;
|
||||
|
||||
if (!_mind.TryGetMind(ent, out var mindId, out var mind))
|
||||
continue;
|
||||
|
||||
@@ -25,6 +25,9 @@ public sealed partial class CP14PassportSystem : EntitySystem
|
||||
|
||||
private void OnPlayerSpawning(PlayerSpawnCompleteEvent ev)
|
||||
{
|
||||
if (!TryComp<InventoryComponent>(ev.Mob, out var inventory))
|
||||
return;
|
||||
|
||||
var passport = Spawn(PassportProto, Transform(ev.Mob).Coordinates);
|
||||
|
||||
if (!TryComp<PaperComponent>(passport, out var paper))
|
||||
@@ -39,7 +42,7 @@ public sealed partial class CP14PassportSystem : EntitySystem
|
||||
StampedName = Loc.GetString("cp14-passport-stamp")
|
||||
},
|
||||
"");
|
||||
_inventory.TryEquip(ev.Mob, passport, "pocket1");
|
||||
_inventory.TryEquip(ev.Mob, passport, "pocket1", inventory: inventory);
|
||||
}
|
||||
|
||||
private string GeneratePassportText(PlayerSpawnCompleteEvent ev)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
using Content.Shared.Destructible.Thresholds;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._CP14.RandomJobs;
|
||||
|
||||
[RegisterComponent, Access(typeof(CP14StationRandomJobsSystem))]
|
||||
public sealed partial class CP14StationRandomJobsComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public List<CP14RandomJobEntry> Entries = new();
|
||||
}
|
||||
|
||||
[Serializable, DataDefinition]
|
||||
public sealed partial class CP14RandomJobEntry
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public List<ProtoId<JobPrototype>> Jobs = new();
|
||||
|
||||
[DataField(required: true)]
|
||||
public MinMax Count = new(1, 1);
|
||||
|
||||
[DataField]
|
||||
public float Prob = 1f;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
|
||||
using Content.Server.Station.Events;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server._CP14.RandomJobs;
|
||||
|
||||
public sealed partial class CP14StationRandomJobsSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly StationJobsSystem _jobs = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<StationInitializedEvent>(OnInit, after: new[] { typeof(StationJobsSystem) });
|
||||
}
|
||||
|
||||
private void OnInit(StationInitializedEvent args)
|
||||
{
|
||||
if (!TryComp<CP14StationRandomJobsComponent>(args.Station, out var randomJobs))
|
||||
return;
|
||||
|
||||
foreach (var entry in randomJobs.Entries)
|
||||
{
|
||||
if (!_random.Prob(entry.Prob))
|
||||
continue;
|
||||
|
||||
var count = entry.Count.Next(_random);
|
||||
|
||||
var tempList = new List<ProtoId<JobPrototype>>(entry.Jobs);
|
||||
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
if (tempList.Count == 0)
|
||||
break;
|
||||
|
||||
var job = _random.Pick(tempList);
|
||||
tempList.Remove(job);
|
||||
|
||||
if (!_proto.TryIndex(job, out var jobProto))
|
||||
continue;
|
||||
|
||||
_jobs.TryAdjustJobSlot(args.Station, jobProto, 1, createSlot: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
79
Content.Server/_CP14/Religion/CP14ReligionSystem.UI.cs
Normal file
79
Content.Server/_CP14/Religion/CP14ReligionSystem.UI.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using Content.Shared._CP14.MagicEnergy.Components;
|
||||
using Content.Shared._CP14.Religion.Components;
|
||||
using Content.Shared._CP14.Religion.Systems;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Follower;
|
||||
using Robust.Server.GameObjects;
|
||||
|
||||
namespace Content.Server._CP14.Religion;
|
||||
|
||||
public sealed partial class CP14ReligionGodSystem
|
||||
{
|
||||
[Dependency] private readonly UserInterfaceSystem _userInterface = default!;
|
||||
[Dependency] private readonly FollowerSystem _follower = default!;
|
||||
private void InitializeUI()
|
||||
{
|
||||
SubscribeLocalEvent<CP14ReligionEntityComponent, OpenBoundInterfaceMessage>(OnOpenInterface);
|
||||
SubscribeLocalEvent<CP14ReligionEntityComponent, CP14ReligionEntityTeleportAttempt>(OnTeleportAttempt);
|
||||
}
|
||||
|
||||
private void OnTeleportAttempt(Entity<CP14ReligionEntityComponent> ent, ref CP14ReligionEntityTeleportAttempt args)
|
||||
{
|
||||
var target = GetEntity(args.Entity);
|
||||
|
||||
var canTeleport = false;
|
||||
if (TryComp<CP14ReligionAltarComponent>(target, out var altar))
|
||||
{
|
||||
if (altar.Religion == ent.Comp.Religion)
|
||||
canTeleport = true;
|
||||
}
|
||||
else if (TryComp<CP14ReligionFollowerComponent>(target, out var follower))
|
||||
{
|
||||
if (follower.Religion == ent.Comp.Religion)
|
||||
canTeleport = true;
|
||||
}
|
||||
|
||||
if (!canTeleport)
|
||||
return;
|
||||
|
||||
_follower.StartFollowingEntity(ent, target);
|
||||
}
|
||||
|
||||
private void OnOpenInterface(Entity<CP14ReligionEntityComponent> ent, ref OpenBoundInterfaceMessage args)
|
||||
{
|
||||
if (ent.Comp.Religion is null)
|
||||
return;
|
||||
|
||||
var altars = new Dictionary<NetEntity, string>();
|
||||
var queryAltars = EntityQueryEnumerator<CP14ReligionAltarComponent, MetaDataComponent>();
|
||||
while (queryAltars.MoveNext(out var uid, out var altar, out var meta))
|
||||
{
|
||||
if (altar.Religion != ent.Comp.Religion)
|
||||
continue;
|
||||
|
||||
altars.TryAdd(GetNetEntity(uid), meta.EntityName);
|
||||
}
|
||||
|
||||
var followers = new Dictionary<NetEntity, string>();
|
||||
var queryFollowers = EntityQueryEnumerator<CP14ReligionFollowerComponent, MetaDataComponent>();
|
||||
while (queryFollowers.MoveNext(out var uid, out var follower, out var meta))
|
||||
{
|
||||
if (follower.Religion != ent.Comp.Religion)
|
||||
continue;
|
||||
|
||||
followers.TryAdd(GetNetEntity(uid), meta.EntityName);
|
||||
}
|
||||
|
||||
var followerPercentage = GetFollowerPercentage(ent);
|
||||
ent.Comp.FollowerPercentage = followerPercentage;
|
||||
Dirty(ent);
|
||||
|
||||
FixedPoint2 manaPercentage = 0f;
|
||||
if (TryComp<CP14MagicEnergyContainerComponent>(ent, out var manaContainerComponent))
|
||||
{
|
||||
manaPercentage = manaContainerComponent.Energy / manaContainerComponent.MaxEnergy;
|
||||
}
|
||||
|
||||
_userInterface.SetUiState(ent.Owner, CP14ReligionEntityUiKey.Key, new CP14ReligionEntityUiState(altars, followers, followerPercentage, manaPercentage));
|
||||
}
|
||||
}
|
||||
247
Content.Server/_CP14/Religion/CP14ReligionSystem.cs
Normal file
247
Content.Server/_CP14/Religion/CP14ReligionSystem.cs
Normal file
@@ -0,0 +1,247 @@
|
||||
using Content.Server._CP14.MagicEnergy;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.Speech;
|
||||
using Content.Shared._CP14.MagicEnergy.Components;
|
||||
using Content.Shared._CP14.Religion.Components;
|
||||
using Content.Shared._CP14.Religion.Prototypes;
|
||||
using Content.Shared._CP14.Religion.Systems;
|
||||
using Content.Shared.Chat;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Server.GameStates;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server._CP14.Religion;
|
||||
|
||||
public sealed partial class CP14ReligionGodSystem : CP14SharedReligionGodSystem
|
||||
{
|
||||
[Dependency] private readonly IChatManager _chat = default!;
|
||||
[Dependency] private readonly ChatSystem _chatSys = default!;
|
||||
[Dependency] private readonly PvsOverrideSystem _pvs = default!;
|
||||
[Dependency] private readonly CP14MagicEnergySystem _magicEnergy = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
|
||||
/// <summary>
|
||||
/// If ReligionObserver receives a radius higher than this value, this entity will automatically be placed in PvsOverride for the god in order to function correctly outside of the player's PVS.
|
||||
/// </summary>
|
||||
/// <remarks> Maybe there is a variable for the distance outside the screen in PVS, I don't know. This number works best</remarks>
|
||||
private const float ObservationOverrideRadius = 6.5f;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
InitializeUI();
|
||||
|
||||
SubscribeLocalEvent<CP14ReligionObserverComponent, ComponentInit>(OnObserverInit);
|
||||
SubscribeLocalEvent<CP14ReligionObserverComponent, AfterAutoHandleStateEvent>(OnObserverHandleState);
|
||||
|
||||
SubscribeLocalEvent<CP14ReligionEntityComponent, ComponentInit>(OnGodInit);
|
||||
SubscribeLocalEvent<CP14ReligionEntityComponent, ComponentShutdown>(OnGodShutdown);
|
||||
SubscribeLocalEvent<CP14ReligionEntityComponent, PlayerAttachedEvent>(OnPlayerAttached);
|
||||
SubscribeLocalEvent<CP14ReligionEntityComponent, PlayerDetachedEvent>(OnPlayerDetached);
|
||||
SubscribeLocalEvent<CP14ReligionSpeakerComponent, CP14SpokeAttemptEvent>(OnSpokeAttempt);
|
||||
|
||||
SubscribeLocalEvent<CP14ReligionAltarComponent, ListenEvent>(OnListen);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
var query = EntityQueryEnumerator<CP14ReligionFollowerComponent, CP14MagicEnergyContainerComponent>();
|
||||
while (query.MoveNext(out var uid, out var follower, out var energy))
|
||||
{
|
||||
if (follower.NextUpdateTime >= _gameTiming.CurTime)
|
||||
continue;
|
||||
|
||||
if (follower.Religion is null)
|
||||
continue;
|
||||
|
||||
follower.NextUpdateTime = _gameTiming.CurTime + TimeSpan.FromSeconds(follower.ManaTransferDelay);
|
||||
|
||||
foreach (var god in GetGods(follower.Religion.Value))
|
||||
{
|
||||
_magicEnergy.TransferEnergy((uid, energy), god.Owner, follower.EnergyToGodTransfer, out _, out _, safe: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSpokeAttempt(Entity<CP14ReligionSpeakerComponent> ent, ref CP14SpokeAttemptEvent args)
|
||||
{
|
||||
args.Cancel();
|
||||
|
||||
if (!TryComp<CP14ReligionEntityComponent>(ent, out var god) || god.Religion is null)
|
||||
return;
|
||||
|
||||
if (ent.Comp.RestrictedReligionZone && !InVision(ent, (ent, god)))
|
||||
return;
|
||||
|
||||
_magicEnergy.ChangeEnergy(ent.Owner, -ent.Comp.ManaCost, out _, out _);
|
||||
|
||||
var speaker = Spawn(ent.Comp.Speaker);
|
||||
_transform.DropNextTo(speaker, ent.Owner);
|
||||
|
||||
var message = args.Message;
|
||||
var type = args.Type;
|
||||
Timer.Spawn(333,
|
||||
() =>
|
||||
{
|
||||
_chatSys.TrySendInGameICMessage(speaker, message, type, ChatTransmitRange.Normal, nameOverride: MetaData(ent).EntityName, ignoreActionBlocker: true);
|
||||
});
|
||||
}
|
||||
|
||||
private void OnObserverHandleState(Entity<CP14ReligionObserverComponent> ent, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
var query = EntityQueryEnumerator<CP14ReligionEntityComponent>();
|
||||
while (query.MoveNext(out var uid, out var god))
|
||||
{
|
||||
UpdatePvsOverrides(new Entity<CP14ReligionEntityComponent>(uid, god));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnObserverInit(Entity<CP14ReligionObserverComponent> ent, ref ComponentInit args)
|
||||
{
|
||||
foreach (var (religion, _) in ent.Comp.Observation)
|
||||
{
|
||||
var gods = GetGods(religion);
|
||||
|
||||
foreach (var god in gods)
|
||||
{
|
||||
UpdatePvsOverrides(god);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGodInit(Entity<CP14ReligionEntityComponent> ent, ref ComponentInit args)
|
||||
{
|
||||
AddPvsOverrides(ent);
|
||||
}
|
||||
|
||||
private void OnGodShutdown(Entity<CP14ReligionEntityComponent> ent, ref ComponentShutdown args)
|
||||
{
|
||||
RemovePvsOverrides(ent);
|
||||
}
|
||||
|
||||
private void OnPlayerAttached(Entity<CP14ReligionEntityComponent> ent, ref PlayerAttachedEvent args)
|
||||
{
|
||||
AddPvsOverrides(ent);
|
||||
}
|
||||
|
||||
private void OnPlayerDetached(Entity<CP14ReligionEntityComponent> ent, ref PlayerDetachedEvent args)
|
||||
{
|
||||
RemovePvsOverrides(ent);
|
||||
}
|
||||
|
||||
private void OnListen(Entity<CP14ReligionAltarComponent> ent, ref ListenEvent args)
|
||||
{
|
||||
if (ent.Comp.Religion is null)
|
||||
return;
|
||||
|
||||
var wrappedMessage =
|
||||
Loc.GetString("cp14-altar-wrapped-message", ("name", MetaData(args.Source).EntityName), ("msg", args.Message));
|
||||
|
||||
SendMessageToGods(ent.Comp.Religion.Value, wrappedMessage, args.Source);
|
||||
}
|
||||
|
||||
public override void SendMessageToGods(ProtoId<CP14ReligionPrototype> religion, string msg, EntityUid source)
|
||||
{
|
||||
var gods = GetGods(religion);
|
||||
|
||||
HashSet<INetChannel> channels = new();
|
||||
foreach (var god in gods)
|
||||
{
|
||||
if (!TryComp<ActorComponent>(god, out var godActor))
|
||||
continue;
|
||||
|
||||
channels.Add(godActor.PlayerSession.Channel);
|
||||
}
|
||||
|
||||
_chat.ChatMessageToMany(ChatChannel.Notifications, msg, msg, source, false, true, channels, colorOverride: Color.Aqua);
|
||||
}
|
||||
|
||||
public FixedPoint2 GetFollowerPercentage(Entity<CP14ReligionEntityComponent> god)
|
||||
{
|
||||
FixedPoint2 total = 0;
|
||||
FixedPoint2 followers = 0;
|
||||
|
||||
var allHumans = Mind.GetAliveHumans();
|
||||
foreach (var human in allHumans)
|
||||
{
|
||||
total += 1;
|
||||
|
||||
if (!TryComp<CP14ReligionFollowerComponent>(human.Comp.CurrentEntity, out var relFollower))
|
||||
continue;
|
||||
if (relFollower.Religion != god.Comp.Religion)
|
||||
continue;
|
||||
|
||||
followers += 1;
|
||||
}
|
||||
|
||||
if (total == 0)
|
||||
return 0f;
|
||||
|
||||
return followers / total;
|
||||
}
|
||||
|
||||
private void AddPvsOverrides(Entity<CP14ReligionEntityComponent> ent)
|
||||
{
|
||||
if (ent.Comp.Religion is null)
|
||||
return;
|
||||
|
||||
if (!TryComp<ActorComponent>(ent, out var actor))
|
||||
return;
|
||||
|
||||
ent.Comp.Session = actor.PlayerSession;
|
||||
|
||||
var query = EntityQueryEnumerator<CP14ReligionObserverComponent>();
|
||||
while (query.MoveNext(out var uid, out var observer))
|
||||
{
|
||||
if (!observer.Observation.ContainsKey(ent.Comp.Religion.Value))
|
||||
continue;
|
||||
|
||||
if (observer.Observation[ent.Comp.Religion.Value] <= ObservationOverrideRadius)
|
||||
continue;
|
||||
|
||||
ent.Comp.PvsOverridedObservers.Add(uid);
|
||||
_pvs.AddSessionOverride(uid, actor.PlayerSession);
|
||||
}
|
||||
}
|
||||
|
||||
private void RemovePvsOverrides(Entity<CP14ReligionEntityComponent> ent)
|
||||
{
|
||||
if (ent.Comp.Religion is null)
|
||||
return;
|
||||
|
||||
if (ent.Comp.Session is null)
|
||||
return;
|
||||
|
||||
foreach (var altar in ent.Comp.PvsOverridedObservers)
|
||||
{
|
||||
_pvs.RemoveSessionOverride(altar, ent.Comp.Session);
|
||||
}
|
||||
|
||||
ent.Comp.Session = null;
|
||||
ent.Comp.PvsOverridedObservers.Clear();
|
||||
}
|
||||
|
||||
private void UpdatePvsOverrides(Entity<CP14ReligionEntityComponent> ent)
|
||||
{
|
||||
if (ent.Comp.Session is null)
|
||||
return;
|
||||
|
||||
RemovePvsOverrides(ent);
|
||||
AddPvsOverrides(ent);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CP14SpokeAttemptEvent(string message, InGameICChatType type, ICommonSession? player) : CancellableEntityEventArgs
|
||||
{
|
||||
public string Message = message;
|
||||
public InGameICChatType Type = type;
|
||||
public ICommonSession? Player = player;
|
||||
}
|
||||
|
||||
63
Content.Server/_CP14/Trading/CP14PriceScannerSystem.cs
Normal file
63
Content.Server/_CP14/Trading/CP14PriceScannerSystem.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System.Text;
|
||||
using Content.Server.Cargo.Systems;
|
||||
using Content.Shared._CP14.Currency;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Tag;
|
||||
using Content.Shared._CP14.Trading.Components;
|
||||
|
||||
|
||||
namespace Content.Server._CP14.Trading;
|
||||
|
||||
public sealed class CP14PriceScannerSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly PricingSystem _price = default!;
|
||||
[Dependency] private readonly TagSystem _tag = default!;
|
||||
[Dependency] private readonly InventorySystem _invSystem = default!;
|
||||
[Dependency] private readonly CP14SharedCurrencySystem _currency = default!;
|
||||
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<MetaDataComponent, ExaminedEvent>(OnExamined);
|
||||
}
|
||||
|
||||
private bool IsAbleExamine(EntityUid uid)
|
||||
{
|
||||
if (_invSystem.TryGetSlotEntity(uid, "eyes", out var huds)
|
||||
&& HasComp<CP14PriceScannerComponent>(huds))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (HasComp<CP14PriceScannerComponent>(uid))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void OnExamined(EntityUid eid, MetaDataComponent component, ExaminedEvent args)
|
||||
{
|
||||
if (!IsAbleExamine(args.Examiner))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (_tag.HasTag(args.Examined, "CP14Coin"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var getPrice = _price.GetPrice(args.Examined);
|
||||
|
||||
var price = Math.Round(getPrice);
|
||||
|
||||
var priceMsg = Loc.GetString("cp14-currency-examine-title");
|
||||
|
||||
priceMsg += _currency.GetCurrencyPrettyString((int)price);
|
||||
|
||||
args.PushMarkup(priceMsg);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using Content.Server._CP14.GameTicking.Rules;
|
||||
using Content.Shared._CP14.WeatherControl;
|
||||
using Content.Shared.Destructible.Thresholds;
|
||||
|
||||
namespace Content.Server._CP14.WeatherControl;
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared._CP14.ZLevel;
|
||||
using Content.Shared.Ghost;
|
||||
using Robust.Shared.Map;
|
||||
@@ -9,11 +8,13 @@ public sealed partial class CP14StationZLevelsSystem
|
||||
{
|
||||
private void InitActions()
|
||||
{
|
||||
SubscribeLocalEvent<GhostComponent, CP14ZLevelActionUp>(OnZLevelUp);
|
||||
SubscribeLocalEvent<GhostComponent, CP14ZLevelActionDown>(OnZLevelDown);
|
||||
SubscribeLocalEvent<GhostComponent, CP14ZLevelActionUp>(OnZLevelUpGhost);
|
||||
SubscribeLocalEvent<GhostComponent, CP14ZLevelActionDown>(OnZLevelDownGhost);
|
||||
SubscribeLocalEvent<SpectralComponent, CP14ZLevelActionUp>(OnZLevelUp);
|
||||
SubscribeLocalEvent<SpectralComponent, CP14ZLevelActionDown>(OnZLevelDown);
|
||||
}
|
||||
|
||||
private void OnZLevelDown(Entity<GhostComponent> ent, ref CP14ZLevelActionDown args)
|
||||
private void OnZLevelDownGhost(Entity<GhostComponent> ent, ref CP14ZLevelActionDown args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
@@ -23,7 +24,27 @@ public sealed partial class CP14StationZLevelsSystem
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnZLevelUp(Entity<GhostComponent> ent, ref CP14ZLevelActionUp args)
|
||||
private void OnZLevelUpGhost(Entity<GhostComponent> ent, ref CP14ZLevelActionUp args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
ZLevelMove(ent, 1);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnZLevelDown(Entity<SpectralComponent> ent, ref CP14ZLevelActionDown args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
ZLevelMove(ent, -1);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnZLevelUp(Entity<SpectralComponent> ent, ref CP14ZLevelActionUp args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Shared._CP14.MagicEssence;
|
||||
using Content.Shared._CP14.MagicSpell.Events;
|
||||
using Content.Shared._CP14.Skill;
|
||||
using Content.Shared.Armor;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Chat;
|
||||
@@ -39,6 +40,7 @@ public partial class InventorySystem
|
||||
//CP14 Relayed events
|
||||
SubscribeLocalEvent<InventoryComponent, CP14MagicEssenceScanEvent>(RelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, CP14CalculateManacostEvent>(RelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, CP14SkillScanEvent>(RelayInventoryEvent);
|
||||
//CP14 End
|
||||
|
||||
SubscribeLocalEvent<InventoryComponent, DamageModifyEvent>(RelayInventoryEvent);
|
||||
|
||||
@@ -49,12 +49,6 @@ namespace Content.Shared.Verbs
|
||||
public static readonly VerbCategory CP14RitualBook = new("cp14-verb-categories-ritual-book", null);
|
||||
|
||||
public static readonly VerbCategory CP14CurrencyConvert = new("cp14-verb-categories-currency-converter", null); //CP14
|
||||
|
||||
public static readonly VerbCategory CP14AdminSkillAdd =
|
||||
new ("cp14-verb-categories-admin-skill-add", null, iconsOnly: true) { Columns = 6 };
|
||||
|
||||
public static readonly VerbCategory CP14AdminSkillRemove =
|
||||
new ("cp14-verb-categories-admin-skill-remove", null, iconsOnly: true) { Columns = 6 };
|
||||
//CP14 verbs
|
||||
|
||||
public static readonly VerbCategory Admin =
|
||||
|
||||
@@ -14,8 +14,7 @@ public partial class CP14SharedCurrencySystem : EntitySystem
|
||||
{
|
||||
var total = currency;
|
||||
|
||||
if (total <= 0)
|
||||
return string.Empty;
|
||||
var sb = new StringBuilder();
|
||||
|
||||
var gp = total / 100;
|
||||
total %= 100;
|
||||
@@ -25,14 +24,15 @@ public partial class CP14SharedCurrencySystem : EntitySystem
|
||||
|
||||
var cp = total;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
if (gp > 0)
|
||||
sb.Append( " " + Loc.GetString("cp14-currency-examine-gp", ("coin", gp)));
|
||||
sb.Append(" " + Loc.GetString("cp14-currency-examine-gp", ("coin", gp)));
|
||||
if (sp > 0)
|
||||
sb.Append( " " + Loc.GetString("cp14-currency-examine-sp", ("coin", sp)));
|
||||
sb.Append(" " + Loc.GetString("cp14-currency-examine-sp", ("coin", sp)));
|
||||
if (cp > 0)
|
||||
sb.Append( " " + Loc.GetString("cp14-currency-examine-cp", ("coin", cp)));
|
||||
sb.Append(" " + Loc.GetString("cp14-currency-examine-cp", ("coin", cp)));
|
||||
if (gp <= 0 && sp <= 0 && cp <= 0)
|
||||
sb.Append(" " + Loc.GetString("cp14-trading-empty-price"));
|
||||
return sb.ToString();
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
using Content.Shared._CP14.MagicSpell.Components;
|
||||
using Content.Shared._CP14.MagicSpell.Events;
|
||||
using Content.Shared._CP14.Religion.Components;
|
||||
using Content.Shared._CP14.Religion.Prototypes;
|
||||
using Content.Shared._CP14.Religion.Systems;
|
||||
using Content.Shared.CombatMode.Pacification;
|
||||
using Content.Shared.Damage.Components;
|
||||
using Content.Shared.Hands.Components;
|
||||
@@ -7,12 +10,14 @@ using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Speech.Muting;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpell;
|
||||
|
||||
public abstract partial class CP14SharedMagicSystem
|
||||
{
|
||||
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||
[Dependency] private readonly CP14SharedReligionGodSystem _god = default!;
|
||||
|
||||
private void InitializeChecks()
|
||||
{
|
||||
@@ -22,12 +27,14 @@ public abstract partial class CP14SharedMagicSystem
|
||||
SubscribeLocalEvent<CP14MagicEffectStaminaCostComponent, CP14CastMagicEffectAttemptEvent>(OnStaminaCheck);
|
||||
SubscribeLocalEvent<CP14MagicEffectPacifiedBlockComponent, CP14CastMagicEffectAttemptEvent>(OnPacifiedCheck);
|
||||
SubscribeLocalEvent<CP14MagicEffectAliveTargetRequiredComponent, CP14CastMagicEffectAttemptEvent>(OnMobStateCheck);
|
||||
SubscribeLocalEvent<CP14MagicEffectReligionRestrictedComponent, CP14CastMagicEffectAttemptEvent>(OnReligionRestrictedCheck);
|
||||
|
||||
//Verbal speaking
|
||||
SubscribeLocalEvent<CP14MagicEffectVerbalAspectComponent, CP14StartCastMagicEffectEvent>(OnVerbalAspectStartCast);
|
||||
SubscribeLocalEvent<CP14MagicEffectVerbalAspectComponent, CP14MagicEffectConsumeResourceEvent>(OnVerbalAspectAfterCast);
|
||||
SubscribeLocalEvent<CP14MagicEffectEmotingComponent, CP14StartCastMagicEffectEvent>(OnEmoteStartCast);
|
||||
SubscribeLocalEvent<CP14MagicEffectEmotingComponent, CP14MagicEffectConsumeResourceEvent>(OnEmoteEndCast);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -148,6 +155,35 @@ public abstract partial class CP14SharedMagicSystem
|
||||
}
|
||||
}
|
||||
|
||||
private void OnReligionRestrictedCheck(Entity<CP14MagicEffectReligionRestrictedComponent> ent,
|
||||
ref CP14CastMagicEffectAttemptEvent args)
|
||||
{
|
||||
if (!TryComp<CP14ReligionEntityComponent>(args.Performer, out var religionComp))
|
||||
return;
|
||||
|
||||
var position = args.Position;
|
||||
|
||||
if (args.Target is not null)
|
||||
position ??= Transform(args.Target.Value).Coordinates;
|
||||
|
||||
if (ent.Comp.OnlyInReligionZone)
|
||||
{
|
||||
if (position is null || !_god.InVision(position.Value, (args.Performer, religionComp)))
|
||||
{
|
||||
args.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
if (ent.Comp.OnlyOnFollowers)
|
||||
{
|
||||
if (args.Target is null || !TryComp<CP14ReligionFollowerComponent>(args.Target, out var follower) || follower.Religion != religionComp.Religion)
|
||||
{
|
||||
args.PushReason(Loc.GetString("cp14-magic-spell-target-god-follower"));
|
||||
args.Cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnVerbalAspectStartCast(Entity<CP14MagicEffectVerbalAspectComponent> ent,
|
||||
ref CP14StartCastMagicEffectEvent args)
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@ public abstract partial class CP14SharedMagicSystem
|
||||
{
|
||||
SubscribeLocalEvent<CP14InstantActionEvent>(OnMagicInstantAction);
|
||||
SubscribeLocalEvent<CP14EntityWorldTargetActionEvent>(OnMagicEntityWorldTargetAction);
|
||||
SubscribeLocalEvent<CP14WorldTargetActionEvent>(OnMagicWorldTargetAction);
|
||||
SubscribeLocalEvent<CP14EntityTargetActionEvent>(OnMagicEntityTargetAction);
|
||||
}
|
||||
|
||||
@@ -47,6 +48,23 @@ public abstract partial class CP14SharedMagicSystem
|
||||
_action.SetCooldown(args.Action.Owner, args.Cooldown);
|
||||
}
|
||||
|
||||
private void OnMagicWorldTargetAction(CP14WorldTargetActionEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (!TryComp<CP14MagicEffectComponent>(args.Action, out var magicEffect))
|
||||
return;
|
||||
|
||||
var spellArgs = new CP14SpellEffectBaseArgs(args.Performer, magicEffect.SpellStorage, null, args.Target);
|
||||
|
||||
if (!CanCastSpell((args.Action, magicEffect), spellArgs))
|
||||
return;
|
||||
|
||||
CastSpell((args.Action, magicEffect), spellArgs);
|
||||
_action.CP14StartCustomDelay(args.Action, args.Cooldown);
|
||||
}
|
||||
|
||||
private void OnMagicEntityTargetAction(CP14EntityTargetActionEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
namespace Content.Shared._CP14.MagicSpell.Components;
|
||||
|
||||
/// <summary>
|
||||
/// If the user belongs to a religion, this spell can only be used within the area of influence of that religion
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicSystem))]
|
||||
public sealed partial class CP14MagicEffectReligionRestrictedComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// does not allow the spell to be used outside the god's area of influence
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool OnlyInReligionZone = true;
|
||||
|
||||
/// <summary>
|
||||
/// allows the spell to be used only on followers
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool OnlyOnFollowers = false;
|
||||
}
|
||||
@@ -13,6 +13,12 @@ public sealed partial class CP14EntityWorldTargetActionEvent : WorldTargetAction
|
||||
public TimeSpan Cooldown { get; private set; } = TimeSpan.FromSeconds(1f);
|
||||
}
|
||||
|
||||
public sealed partial class CP14WorldTargetActionEvent : WorldTargetActionEvent, ICP14MagicEffect
|
||||
{
|
||||
[DataField]
|
||||
public TimeSpan Cooldown { get; private set; } = TimeSpan.FromSeconds(1f);
|
||||
}
|
||||
|
||||
public sealed partial class CP14EntityTargetActionEvent : EntityTargetActionEvent, ICP14MagicEffect
|
||||
{
|
||||
[DataField]
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
using Content.Shared._CP14.Skill;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpell.Spells;
|
||||
|
||||
public sealed partial class CP14SpellAddMemoryPoint : CP14SpellEffect
|
||||
{
|
||||
[DataField]
|
||||
public float AddedPoints = 0.5f;
|
||||
|
||||
[DataField]
|
||||
public float Limit = 6.5f;
|
||||
|
||||
public override void Effect(EntityManager entManager, CP14SpellEffectBaseArgs args)
|
||||
{
|
||||
if (args.Target is null)
|
||||
return;
|
||||
|
||||
var skillSys = entManager.System<CP14SharedSkillSystem>();
|
||||
|
||||
skillSys.AddMemoryPoints(args.Target.Value, AddedPoints, Limit);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using Content.Shared._CP14.Religion.Components;
|
||||
using Content.Shared._CP14.Religion.Systems;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpell.Spells;
|
||||
|
||||
public sealed partial class CP14SpellGodRenounce : CP14SpellEffect
|
||||
{
|
||||
public override void Effect(EntityManager entManager, CP14SpellEffectBaseArgs args)
|
||||
{
|
||||
if (args.Target is null)
|
||||
return;
|
||||
|
||||
if (!entManager.TryGetComponent<CP14ReligionEntityComponent>(args.User, out var god) || god.Religion is null)
|
||||
return;
|
||||
|
||||
if (!entManager.TryGetComponent<CP14ReligionFollowerComponent>(args.Target.Value, out var follower) || follower.Religion != god.Religion)
|
||||
return;
|
||||
|
||||
var religionSys = entManager.System<CP14SharedReligionGodSystem>();
|
||||
|
||||
religionSys.ToDisbelieve(args.Target.Value);
|
||||
}
|
||||
}
|
||||
25
Content.Shared/_CP14/MagicSpell/Spells/CP14SpellGodTouch.cs
Normal file
25
Content.Shared/_CP14/MagicSpell/Spells/CP14SpellGodTouch.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using Content.Shared._CP14.Religion.Components;
|
||||
using Content.Shared._CP14.Religion.Prototypes;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpell.Spells;
|
||||
|
||||
public sealed partial class CP14SpellGodTouch : CP14SpellEffect
|
||||
{
|
||||
public override void Effect(EntityManager entManager, CP14SpellEffectBaseArgs args)
|
||||
{
|
||||
if (args.Target is null)
|
||||
return;
|
||||
|
||||
if (!entManager.TryGetComponent<CP14ReligionEntityComponent>(args.User, out var god) || god.Religion is null)
|
||||
return;
|
||||
|
||||
var ev = new CP14GodTouchEvent(god.Religion.Value);
|
||||
entManager.EventBus.RaiseLocalEvent(args.Target.Value, ev);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CP14GodTouchEvent(ProtoId<CP14ReligionPrototype> religion) : EntityEventArgs
|
||||
{
|
||||
public ProtoId<CP14ReligionPrototype> Religion = religion;
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared.Weapons.Ranged.Systems;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Physics.Systems;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpell.Spells;
|
||||
|
||||
@@ -10,6 +12,15 @@ public sealed partial class CP14SpellProjectile : CP14SpellEffect
|
||||
[DataField(required: true)]
|
||||
public EntProtoId Prototype;
|
||||
|
||||
[DataField]
|
||||
public float ProjectileSpeed = 20f;
|
||||
|
||||
[DataField]
|
||||
public float Spread = 0f;
|
||||
|
||||
[DataField]
|
||||
public int ProjectileCount = 1;
|
||||
|
||||
public override void Effect(EntityManager entManager, CP14SpellEffectBaseArgs args)
|
||||
{
|
||||
EntityCoordinates? targetPoint = null;
|
||||
@@ -27,6 +38,7 @@ public sealed partial class CP14SpellProjectile : CP14SpellEffect
|
||||
var physics = entManager.System<SharedPhysicsSystem>();
|
||||
var gunSystem = entManager.System<SharedGunSystem>();
|
||||
var mapManager = IoCManager.Resolve<IMapManager>();
|
||||
var random = IoCManager.Resolve<IRobustRandom>();
|
||||
|
||||
if (!entManager.TryGetComponent<TransformComponent>(args.User, out var xform))
|
||||
return;
|
||||
@@ -40,14 +52,24 @@ public sealed partial class CP14SpellProjectile : CP14SpellEffect
|
||||
|
||||
// If applicable, this ensures the projectile is parented to grid on spawn, instead of the map.
|
||||
var fromMap = transform.ToMapCoordinates(fromCoords);
|
||||
|
||||
var spawnCoords = mapManager.TryFindGridAt(fromMap, out var gridUid, out _)
|
||||
? transform.WithEntityId(fromCoords, gridUid)
|
||||
: new(mapManager.GetMapEntityId(fromMap.MapId), fromMap.Position);
|
||||
|
||||
for (var i = 0; i < ProjectileCount; i++)
|
||||
{
|
||||
//Apply spread to target point
|
||||
var offsetedTargetPoint = targetPoint.Value.Offset(new Vector2(
|
||||
(float) (random.NextDouble() * 2 - 1) * Spread,
|
||||
(float) (random.NextDouble() * 2 - 1) * Spread));
|
||||
|
||||
var ent = entManager.SpawnAtPosition(Prototype, spawnCoords);
|
||||
var direction = targetPoint.Value.ToMapPos(entManager, transform) -
|
||||
spawnCoords.ToMapPos(entManager, transform);
|
||||
gunSystem.ShootProjectile(ent, direction, userVelocity, args.User.Value, args.User);
|
||||
var ent = entManager.SpawnAtPosition(Prototype, spawnCoords);
|
||||
|
||||
var direction = offsetedTargetPoint.ToMapPos(entManager, transform) -
|
||||
spawnCoords.ToMapPos(entManager, transform);
|
||||
|
||||
gunSystem.ShootProjectile(ent, direction, userVelocity, args.User.Value, args.User, ProjectileSpeed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
using Content.Shared._CP14.Skill;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpell.Spells;
|
||||
|
||||
public sealed partial class CP14SpellRemoveMemoryPoint : CP14SpellEffect
|
||||
{
|
||||
[DataField]
|
||||
public float RemovedPoints = 0.5f;
|
||||
|
||||
public override void Effect(EntityManager entManager, CP14SpellEffectBaseArgs args)
|
||||
{
|
||||
if (args.Target is null)
|
||||
return;
|
||||
|
||||
var skillSys = entManager.System<CP14SharedSkillSystem>();
|
||||
|
||||
skillSys.RemoveMemoryPoints(args.Target.Value, RemovedPoints);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using Content.Shared._CP14.Religion.Components;
|
||||
using Content.Shared._CP14.Religion.Systems;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpell.Spells;
|
||||
|
||||
public sealed partial class CP14SpellSendMessageToGod : CP14SpellEffect
|
||||
{
|
||||
[DataField]
|
||||
public LocId? Message;
|
||||
|
||||
public override void Effect(EntityManager entManager, CP14SpellEffectBaseArgs args)
|
||||
{
|
||||
if (!entManager.TryGetComponent<CP14ReligionFollowerComponent>(args.User, out var follower))
|
||||
return;
|
||||
if (!entManager.TryGetComponent<MetaDataComponent>(args.User, out var metaData))
|
||||
return;
|
||||
|
||||
if (follower.Religion is null)
|
||||
return;
|
||||
|
||||
var religionSys = entManager.System<CP14SharedReligionGodSystem>();
|
||||
|
||||
religionSys.SendMessageToGods(follower.Religion.Value, Loc.GetString("cp14-call-follower-message", ("name", metaData.EntityName)) + " " + Loc.GetString(Message?? ""), args.User.Value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using Content.Shared._CP14.MagicEnergy;
|
||||
using Content.Shared._CP14.Religion.Components;
|
||||
using Content.Shared._CP14.Religion.Systems;
|
||||
using Content.Shared.FixedPoint;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpell.Spells;
|
||||
|
||||
public sealed partial class CP14SpellTransferManaToGod : CP14SpellEffect
|
||||
{
|
||||
[DataField]
|
||||
public FixedPoint2 Amount = 10f;
|
||||
|
||||
[DataField]
|
||||
public bool Safe = false;
|
||||
|
||||
public override void Effect(EntityManager entManager, CP14SpellEffectBaseArgs args)
|
||||
{
|
||||
if (args.User is null)
|
||||
return;
|
||||
|
||||
if (!entManager.TryGetComponent<CP14ReligionFollowerComponent>(args.User, out var follower))
|
||||
return;
|
||||
|
||||
if (follower.Religion is null)
|
||||
return;
|
||||
|
||||
var religionSys = entManager.System<CP14SharedReligionGodSystem>();
|
||||
var magicEnergySys = entManager.System<SharedCP14MagicEnergySystem>();
|
||||
|
||||
var gods = religionSys.GetGods(follower.Religion.Value);
|
||||
var manaAmount = Amount / gods.Count;
|
||||
foreach (var god in gods)
|
||||
{
|
||||
magicEnergySys.TransferEnergy(args.User.Value, god.Owner, manaAmount, out _, out _, safe: Safe);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Content.Shared._CP14.Religion.Prototypes;
|
||||
using Content.Shared._CP14.Religion.Systems;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Religion.Components;
|
||||
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(CP14SharedReligionGodSystem))]
|
||||
public sealed partial class CP14ReligionAltarComponent : Component
|
||||
{
|
||||
[DataField, AutoNetworkedField]
|
||||
public ProtoId<CP14ReligionPrototype>? Religion;
|
||||
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool CanBeConverted = true;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Content.Shared._CP14.Religion.Prototypes;
|
||||
using Content.Shared._CP14.Religion.Systems;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Religion.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(CP14SharedReligionGodSystem))]
|
||||
public sealed partial class CP14ReligionEntityComponent : Component
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public ProtoId<CP14ReligionPrototype>? Religion;
|
||||
|
||||
public HashSet<EntityUid> PvsOverridedObservers = new();
|
||||
public ICommonSession? Session;
|
||||
|
||||
/// <summary>
|
||||
/// Number of followers as a percentage. Automatically calculated on the server and sent to the client for data synchronization.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public FixedPoint2 FollowerPercentage = 0;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using Content.Shared._CP14.Religion.Prototypes;
|
||||
using Content.Shared._CP14.Religion.Systems;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Religion.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the entity is a follower of God, or may never be able to become one
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(CP14SharedReligionGodSystem))]
|
||||
public sealed partial class CP14ReligionFollowerComponent : Component
|
||||
{
|
||||
[DataField, AutoNetworkedField]
|
||||
public ProtoId<CP14ReligionPrototype>? Religion;
|
||||
|
||||
[DataField, AutoNetworkedField]
|
||||
public HashSet<ProtoId<CP14ReligionPrototype>> RejectedReligions = new();
|
||||
|
||||
[DataField]
|
||||
public EntProtoId RenounceActionProto = "CP14ActionRenounceFromGod";
|
||||
|
||||
[DataField]
|
||||
public EntProtoId AppealToGofProto = "CP14ActionAppealToGod";
|
||||
|
||||
[DataField]
|
||||
public EntityUid? RenounceAction;
|
||||
|
||||
[DataField]
|
||||
public EntityUid? AppealAction;
|
||||
|
||||
/// <summary>
|
||||
/// how much energy does the entity transfer to its god
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public FixedPoint2 EnergyToGodTransfer = 0.5f;
|
||||
|
||||
/// <summary>
|
||||
/// how often will the entity transfer mana to its patreon
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float ManaTransferDelay = 3f;
|
||||
|
||||
/// <summary>
|
||||
/// the time of the next magic energy change
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public TimeSpan NextUpdateTime { get; set; } = TimeSpan.Zero;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Content.Shared._CP14.Religion.Prototypes;
|
||||
using Content.Shared._CP14.Religion.Systems;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Religion.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Allows the god of a particular religion to see within a radius around the observer.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true), Access(typeof(CP14SharedReligionGodSystem))]
|
||||
public sealed partial class CP14ReligionObserverComponent : Component
|
||||
{
|
||||
[DataField, AutoNetworkedField]
|
||||
public Dictionary<ProtoId<CP14ReligionPrototype>, float> Observation = new(); //DAMNATION
|
||||
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool Active = true;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using Content.Shared._CP14.Religion.Prototypes;
|
||||
using Content.Shared._CP14.Religion.Systems;
|
||||
using Content.Shared.Alert;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Religion.Components;
|
||||
|
||||
/// <summary>
|
||||
/// This entity has not yet become a follower of God, but wants to become one. Confirmation from god is expected
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(CP14SharedReligionGodSystem))]
|
||||
public sealed partial class CP14ReligionPendingFollowerComponent : Component
|
||||
{
|
||||
[DataField, AutoNetworkedField]
|
||||
public ProtoId<CP14ReligionPrototype>? Religion;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using Content.Shared._CP14.Religion.Systems;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Religion.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Disables standard communication. Instead, attempts to say anything will consume mana, will be limited by the zone
|
||||
/// of influence of religion, and will be spoken through the created entity of the “speaker.”
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(CP14SharedReligionGodSystem))]
|
||||
public sealed partial class CP14ReligionSpeakerComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public FixedPoint2 ManaCost = 5f;
|
||||
|
||||
[DataField(required: true)]
|
||||
public EntProtoId Speaker;
|
||||
|
||||
/// <summary>
|
||||
/// You can only talk within the sphere of influence of religion.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool RestrictedReligionZone = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using Content.Shared._CP14.Religion.Systems;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared._CP14.Religion.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Limits the vision of entities, allowing them to see only areas within a radius around observers of their religion.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(CP14SharedReligionGodSystem))]
|
||||
public sealed partial class CP14ReligionVisionComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public Vector3 ShaderColor = new (1f, 1f, 1f);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Religion.Prototypes;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Prototype("cp14Religion")]
|
||||
public sealed partial class CP14ReligionPrototype : IPrototype
|
||||
{
|
||||
[IdDataField] public string ID { get; } = default!;
|
||||
|
||||
[DataField]
|
||||
public float FollowerObservationRadius = 8f;
|
||||
|
||||
[DataField]
|
||||
public float AltarObservationRadius = 25f;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
using Content.Shared._CP14.Religion.Components;
|
||||
using Content.Shared._CP14.Religion.Prototypes;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._CP14.Religion.Systems;
|
||||
|
||||
public abstract partial class CP14SharedReligionGodSystem
|
||||
{
|
||||
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
||||
|
||||
private void InitializeAltars()
|
||||
{
|
||||
SubscribeLocalEvent<CP14ReligionAltarComponent, GetVerbsEvent<AlternativeVerb>>(GetAltVerb);
|
||||
}
|
||||
|
||||
private void GetAltVerb(Entity<CP14ReligionAltarComponent> ent, ref GetVerbsEvent<AlternativeVerb> args)
|
||||
{
|
||||
if (ent.Comp.Religion is null)
|
||||
return;
|
||||
|
||||
var disabled = !CanBecomeFollower(args.User, ent.Comp.Religion.Value);
|
||||
|
||||
if (!disabled && TryComp<CP14ReligionPendingFollowerComponent>(args.User, out var pendingFollower))
|
||||
{
|
||||
if (pendingFollower.Religion is not null)
|
||||
disabled = true;
|
||||
}
|
||||
|
||||
if (disabled)
|
||||
return;
|
||||
|
||||
var user = args.User;
|
||||
args.Verbs.Add(new AlternativeVerb()
|
||||
{
|
||||
Text = Loc.GetString("cp14-altar-become-follower"),
|
||||
Message = Loc.GetString("cp14-altar-become-follower-desc"),
|
||||
Act = () =>
|
||||
{
|
||||
var doAfterArgs = new DoAfterArgs(EntityManager, user, 5f, new CP14AltarOfferDoAfter(), ent, used: ent)
|
||||
{
|
||||
BreakOnDamage = true,
|
||||
BreakOnMove = true,
|
||||
};
|
||||
_doAfter.TryStartDoAfter(doAfterArgs);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public bool TryConvertAltar(EntityUid target, ProtoId<CP14ReligionPrototype> religion)
|
||||
{
|
||||
if (!_proto.TryIndex(religion, out var indexedReligion))
|
||||
return false;
|
||||
|
||||
EnsureComp<CP14ReligionAltarComponent>(target, out var altar);
|
||||
|
||||
if (!altar.CanBeConverted)
|
||||
return false;
|
||||
|
||||
var oldReligion = altar.Religion;
|
||||
altar.Religion = religion;
|
||||
Dirty(target, altar);
|
||||
|
||||
EditObservation(target, religion, indexedReligion.AltarObservationRadius);
|
||||
|
||||
var ev = new CP14ReligionChangedEvent(oldReligion, religion);
|
||||
RaiseLocalEvent(target, ev);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void DeconvertAltar(EntityUid target)
|
||||
{
|
||||
if (!TryComp<CP14ReligionAltarComponent>(target, out var altar))
|
||||
return;
|
||||
|
||||
if (altar.Religion is null)
|
||||
return;
|
||||
|
||||
if (!_proto.TryIndex(altar.Religion, out var indexedReligion))
|
||||
return;
|
||||
|
||||
EditObservation(target, altar.Religion.Value, -indexedReligion.AltarObservationRadius);
|
||||
|
||||
var oldReligion = altar.Religion;
|
||||
altar.Religion = null;
|
||||
|
||||
var ev = new CP14ReligionChangedEvent(oldReligion, null);
|
||||
RaiseLocalEvent(target, ev);
|
||||
|
||||
Dirty(target, altar);
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class CP14AltarOfferDoAfter : SimpleDoAfterEvent
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
using Content.Shared._CP14.MagicSpell.Spells;
|
||||
using Content.Shared._CP14.Religion.Components;
|
||||
using Content.Shared._CP14.Religion.Prototypes;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Follower;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Mobs;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Religion.Systems;
|
||||
|
||||
public abstract partial class CP14SharedReligionGodSystem
|
||||
{
|
||||
[Dependency] private readonly AlertsSystem _alerts = default!;
|
||||
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
||||
[Dependency] protected readonly SharedMindSystem Mind = default!;
|
||||
[Dependency] private readonly FollowerSystem _follower = default!;
|
||||
|
||||
[ValidatePrototypeId<AlertPrototype>]
|
||||
public const string AlertProto = "CP14DivineOffer";
|
||||
|
||||
private void InitializeFollowers()
|
||||
{
|
||||
SubscribeLocalEvent<CP14ReligionPendingFollowerComponent, MapInitEvent>(OnPendingFollowerInit);
|
||||
SubscribeLocalEvent<CP14ReligionPendingFollowerComponent, ComponentShutdown>(OnPendingFollowerShutdown);
|
||||
SubscribeLocalEvent<CP14ReligionPendingFollowerComponent, CP14BreakDivineOfferEvent>(OnBreakDivineOffer);
|
||||
SubscribeLocalEvent<CP14ReligionPendingFollowerComponent, CP14GodTouchEvent>(OnGodTouch);
|
||||
|
||||
SubscribeLocalEvent<CP14ReligionAltarComponent, CP14AltarOfferDoAfter>(OnOfferDoAfter);
|
||||
|
||||
SubscribeLocalEvent<CP14ReligionFollowerComponent, CP14RenounceFromGodEvent>(OnRenounceFromGod);
|
||||
SubscribeLocalEvent<CP14ReligionFollowerComponent, GetVerbsEvent<AlternativeVerb>>(OnGetAltVerbs);
|
||||
SubscribeLocalEvent<CP14ReligionFollowerComponent, MobStateChangedEvent>(OnFollowerStateChange);
|
||||
}
|
||||
|
||||
private void OnFollowerStateChange(Entity<CP14ReligionFollowerComponent> ent, ref MobStateChangedEvent args)
|
||||
{
|
||||
if (ent.Comp.Religion is null)
|
||||
return;
|
||||
|
||||
switch (args.NewMobState)
|
||||
{
|
||||
case MobState.Critical:
|
||||
SendMessageToGods(ent.Comp.Religion.Value, Loc.GetString("cp14-critical-follower-message", ("name", MetaData(ent).EntityName)), ent);
|
||||
break;
|
||||
|
||||
case MobState.Dead:
|
||||
SendMessageToGods(ent.Comp.Religion.Value, Loc.GetString("cp14-dead-follower-message", ("name", MetaData(ent).EntityName)), ent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGetAltVerbs(EntityUid uid, CP14ReligionFollowerComponent component, GetVerbsEvent<AlternativeVerb> args)
|
||||
{
|
||||
if (!TryComp<CP14ReligionEntityComponent>(args.User, out var god))
|
||||
return;
|
||||
|
||||
if (god.Religion != component.Religion)
|
||||
return;
|
||||
|
||||
args.Verbs.Add(new AlternativeVerb
|
||||
{
|
||||
Text = Loc.GetString("admin-player-actions-follow"),
|
||||
Act = () =>
|
||||
{
|
||||
_follower.StartFollowingEntity(args.User, uid);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private void OnRenounceFromGod(Entity<CP14ReligionFollowerComponent> ent, ref CP14RenounceFromGodEvent args)
|
||||
{
|
||||
ToDisbelieve(ent);
|
||||
}
|
||||
|
||||
private void OnOfferDoAfter(Entity<CP14ReligionAltarComponent> ent, ref CP14AltarOfferDoAfter args)
|
||||
{
|
||||
if (args.Handled || args.Cancelled)
|
||||
return;
|
||||
|
||||
if (ent.Comp.Religion is null)
|
||||
return;
|
||||
|
||||
TryAddPendingFollower(args.User, ent.Comp.Religion.Value);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnGodTouch(Entity<CP14ReligionPendingFollowerComponent> ent, ref CP14GodTouchEvent args)
|
||||
{
|
||||
if (args.Religion != ent.Comp.Religion)
|
||||
return;
|
||||
|
||||
TryToBelieve(ent);
|
||||
}
|
||||
|
||||
private void OnBreakDivineOffer(Entity<CP14ReligionPendingFollowerComponent> ent, ref CP14BreakDivineOfferEvent args)
|
||||
{
|
||||
RemCompDeferred<CP14ReligionPendingFollowerComponent>(ent);
|
||||
|
||||
if (ent.Comp.Religion is null)
|
||||
return;
|
||||
|
||||
SendMessageToGods(ent.Comp.Religion.Value, Loc.GetString("cp14-unoffer-soul-god-message", ("name", MetaData(ent).EntityName)), ent);
|
||||
}
|
||||
|
||||
private void OnPendingFollowerInit(Entity<CP14ReligionPendingFollowerComponent> ent, ref MapInitEvent args)
|
||||
{
|
||||
_alerts.ShowAlert(ent, AlertProto);
|
||||
}
|
||||
|
||||
private void OnPendingFollowerShutdown(Entity<CP14ReligionPendingFollowerComponent> ent, ref ComponentShutdown args)
|
||||
{
|
||||
_alerts.ClearAlert(ent, AlertProto);
|
||||
}
|
||||
|
||||
private bool CanBecomeFollower(EntityUid target, ProtoId<CP14ReligionPrototype> religion)
|
||||
{
|
||||
if (HasComp<CP14ReligionEntityComponent>(target))
|
||||
return false;
|
||||
|
||||
EnsureComp<CP14ReligionFollowerComponent>(target, out var follower);
|
||||
|
||||
if (follower.Religion is not null)
|
||||
return false;
|
||||
|
||||
return !follower.RejectedReligions.Contains(religion);
|
||||
}
|
||||
|
||||
private void TryAddPendingFollower(EntityUid target, ProtoId<CP14ReligionPrototype> religion)
|
||||
{
|
||||
if (!CanBecomeFollower(target, religion))
|
||||
return;
|
||||
|
||||
EnsureComp<CP14ReligionPendingFollowerComponent>(target, out var pendingFollower);
|
||||
pendingFollower.Religion = religion;
|
||||
|
||||
SendMessageToGods(religion, Loc.GetString("cp14-offer-soul-god-message", ("name", MetaData(target).EntityName)), target);
|
||||
}
|
||||
|
||||
private bool TryToBelieve(Entity<CP14ReligionPendingFollowerComponent> pending)
|
||||
{
|
||||
if (pending.Comp.Religion is null)
|
||||
return false;
|
||||
|
||||
if (!_proto.TryIndex(pending.Comp.Religion, out var indexedReligion))
|
||||
return false;
|
||||
|
||||
if (!CanBecomeFollower(pending, pending.Comp.Religion.Value))
|
||||
return false;
|
||||
|
||||
EnsureComp<CP14ReligionFollowerComponent>(pending, out var follower);
|
||||
|
||||
var oldReligion = follower.Religion;
|
||||
follower.Religion = pending.Comp.Religion;
|
||||
Dirty(pending, follower);
|
||||
|
||||
EditObservation(pending, pending.Comp.Religion.Value, indexedReligion.FollowerObservationRadius);
|
||||
|
||||
var ev = new CP14ReligionChangedEvent(oldReligion, pending.Comp.Religion);
|
||||
RaiseLocalEvent(pending, ev);
|
||||
|
||||
RemCompDeferred<CP14ReligionPendingFollowerComponent>(pending);
|
||||
SendMessageToGods(pending.Comp.Religion.Value, Loc.GetString("cp14-become-follower-message", ("name", MetaData(pending).EntityName)), pending);
|
||||
|
||||
_actions.AddAction(pending, ref follower.RenounceAction, follower.RenounceActionProto);
|
||||
_actions.AddAction(pending, ref follower.AppealAction, follower.AppealToGofProto);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ToDisbelieve(EntityUid target)
|
||||
{
|
||||
if (!TryComp<CP14ReligionFollowerComponent>(target, out var follower))
|
||||
return;
|
||||
|
||||
if (follower.Religion is null)
|
||||
return;
|
||||
|
||||
if (!_proto.TryIndex(follower.Religion, out var indexedReligion))
|
||||
return;
|
||||
|
||||
SendMessageToGods(follower.Religion.Value, Loc.GetString("cp14-remove-follower-message", ("name", MetaData(target).EntityName)), target);
|
||||
EditObservation(target, follower.Religion.Value, -indexedReligion.FollowerObservationRadius);
|
||||
|
||||
var oldReligion = follower.Religion;
|
||||
follower.Religion = null;
|
||||
if (oldReligion is not null)
|
||||
follower.RejectedReligions.Add(oldReligion.Value);
|
||||
|
||||
var ev = new CP14ReligionChangedEvent(oldReligion, null);
|
||||
RaiseLocalEvent(target, ev);
|
||||
|
||||
Dirty(target, follower);
|
||||
|
||||
_actions.RemoveAction(target, follower.RenounceAction);
|
||||
_actions.RemoveAction(target, follower.AppealAction);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed partial class CP14BreakDivineOfferEvent : BaseAlertEvent;
|
||||
|
||||
public sealed partial class CP14RenounceFromGodEvent : InstantActionEvent;
|
||||
@@ -0,0 +1,93 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared._CP14.Religion.Components;
|
||||
using Content.Shared._CP14.Religion.Prototypes;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Religion.Systems;
|
||||
|
||||
public abstract partial class CP14SharedReligionGodSystem
|
||||
{
|
||||
private void InitializeObservation()
|
||||
{
|
||||
SubscribeLocalEvent<CP14ReligionEntityComponent, InRangeOverrideEvent>(OnGodInRange);
|
||||
SubscribeLocalEvent<CP14ReligionEntityComponent, MenuVisibilityEvent>(OnGodMenu);
|
||||
}
|
||||
|
||||
private void OnGodInRange(Entity<CP14ReligionEntityComponent> ent, ref InRangeOverrideEvent args)
|
||||
{
|
||||
args.Handled = true;
|
||||
|
||||
args.InRange = InVision(args.Target, ent);
|
||||
}
|
||||
|
||||
private void OnGodMenu(Entity<CP14ReligionEntityComponent> ent, ref MenuVisibilityEvent args)
|
||||
{
|
||||
args.Visibility &= ~MenuVisibility.NoFov;
|
||||
}
|
||||
|
||||
public void EditObservation(EntityUid target, ProtoId<CP14ReligionPrototype> religion, float range)
|
||||
{
|
||||
EnsureComp<CP14ReligionObserverComponent>(target, out var observer);
|
||||
|
||||
if (observer.Observation.ContainsKey(religion))
|
||||
{
|
||||
var newRange = Math.Clamp(observer.Observation[religion] + range, 0, float.MaxValue);
|
||||
|
||||
if (newRange <= 0)
|
||||
observer.Observation.Remove(religion);
|
||||
else
|
||||
observer.Observation[religion] = newRange;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, add a new observation for the religion.
|
||||
observer.Observation.Add(religion, range);
|
||||
}
|
||||
|
||||
Dirty(target, observer);
|
||||
}
|
||||
|
||||
public bool InVision(EntityUid target, Entity<CP14ReligionEntityComponent> user)
|
||||
{
|
||||
var position = Transform(target).Coordinates;
|
||||
|
||||
return InVision(position, user);
|
||||
}
|
||||
|
||||
public bool InVision(EntityCoordinates coords, Entity<CP14ReligionEntityComponent> user)
|
||||
{
|
||||
if (!HasComp<CP14ReligionVisionComponent>(user))
|
||||
return true;
|
||||
|
||||
var userXform = Transform(user);
|
||||
var query = EntityQueryEnumerator<CP14ReligionObserverComponent, TransformComponent>();
|
||||
while (query.MoveNext(out var uid, out var observer, out var xform))
|
||||
{
|
||||
if (!observer.Active)
|
||||
continue;
|
||||
|
||||
if (xform.MapID != userXform.MapID)
|
||||
continue;
|
||||
|
||||
if (user.Comp.Religion is null)
|
||||
continue;
|
||||
|
||||
if (!observer.Observation.ContainsKey(user.Comp.Religion.Value))
|
||||
continue;
|
||||
|
||||
|
||||
var obsPos = _transform.GetWorldPosition(uid);
|
||||
var targetPos = coords.Position;
|
||||
if (Vector2.Distance(obsPos, targetPos) <= observer.Observation[user.Comp.Religion.Value])
|
||||
{
|
||||
// If the observer is within range of the target, they can see it.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._CP14.Religion.Systems;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum CP14ReligionEntityUiKey
|
||||
{
|
||||
Key,
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CP14ReligionEntityUiState(Dictionary<NetEntity, string> altars, Dictionary<NetEntity, string> followers, FixedPoint2 followerPercentage, FixedPoint2 manaPercentage) : BoundUserInterfaceState
|
||||
{
|
||||
public Dictionary<NetEntity, string> Altars = altars;
|
||||
public Dictionary<NetEntity, string> Followers = followers;
|
||||
public FixedPoint2 FollowerPercentage = followerPercentage;
|
||||
public FixedPoint2 ManaPercentage = manaPercentage;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CP14ReligionEntityTeleportAttempt(NetEntity entity) : BoundUserInterfaceMessage
|
||||
{
|
||||
public readonly NetEntity Entity = entity;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using Content.Shared._CP14.Religion.Components;
|
||||
using Content.Shared._CP14.Religion.Prototypes;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Religion.Systems;
|
||||
|
||||
public abstract partial class CP14SharedReligionGodSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
InitializeObservation();
|
||||
InitializeFollowers();
|
||||
InitializeAltars();
|
||||
}
|
||||
|
||||
public HashSet<Entity<CP14ReligionEntityComponent>> GetGods(ProtoId<CP14ReligionPrototype> religion)
|
||||
{
|
||||
HashSet<Entity<CP14ReligionEntityComponent>> gods = new();
|
||||
|
||||
var query = EntityQueryEnumerator<CP14ReligionEntityComponent>();
|
||||
while (query.MoveNext(out var uid, out var god))
|
||||
{
|
||||
if (god.Religion != religion)
|
||||
continue;
|
||||
|
||||
gods.Add(new Entity<CP14ReligionEntityComponent>(uid, god));
|
||||
}
|
||||
|
||||
return gods;
|
||||
}
|
||||
|
||||
public abstract void SendMessageToGods(ProtoId<CP14ReligionPrototype> religion, string msg, EntityUid source);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// It is invoked on altars and followers when they change their religion.
|
||||
/// </summary>
|
||||
public sealed class CP14ReligionChangedEvent(ProtoId<CP14ReligionPrototype>? oldRel, ProtoId<CP14ReligionPrototype>? newRel) : EntityEventArgs
|
||||
{
|
||||
public ProtoId<CP14ReligionPrototype>? OldReligion = oldRel;
|
||||
public ProtoId<CP14ReligionPrototype>? NewReligion = newRel;
|
||||
}
|
||||
@@ -2,8 +2,10 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using Content.Shared._CP14.Skill.Components;
|
||||
using Content.Shared._CP14.Skill.Prototypes;
|
||||
using Content.Shared._CP14.Skill.Restrictions;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Shared._CP14.Skill;
|
||||
|
||||
@@ -21,6 +23,7 @@ public abstract partial class CP14SharedSkillSystem : EntitySystem
|
||||
|
||||
InitializeAdmin();
|
||||
InitializeChecks();
|
||||
InitializeScanning();
|
||||
}
|
||||
|
||||
private void OnMapInit(Entity<CP14SkillStorageComponent> ent, ref MapInitEvent args)
|
||||
@@ -174,6 +177,10 @@ public abstract partial class CP14SharedSkillSystem : EntitySystem
|
||||
if (HaveSkill(target, skill, component))
|
||||
return false;
|
||||
|
||||
//Check if the skill is in the available skill trees
|
||||
if (!component.AvailableSkillTrees.Contains(skill.Tree))
|
||||
return false;
|
||||
|
||||
//Check max cap
|
||||
if (component.SkillsSumExperience + skill.LearnCost > component.ExperienceMaxCap)
|
||||
return false;
|
||||
@@ -244,6 +251,39 @@ public abstract partial class CP14SharedSkillSystem : EntitySystem
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Obtaining all skills that are not prerequisites for other skills of this creature
|
||||
/// </summary>
|
||||
public HashSet<ProtoId<CP14SkillPrototype>> GetFrontierSkills(EntityUid target,
|
||||
CP14SkillStorageComponent? component = null)
|
||||
{
|
||||
var skills = new HashSet<ProtoId<CP14SkillPrototype>>();
|
||||
if (!Resolve(target, ref component, false))
|
||||
return skills;
|
||||
|
||||
var frontier = component.LearnedSkills.ToHashSet();
|
||||
foreach (var skill in component.LearnedSkills)
|
||||
{
|
||||
if (!_proto.TryIndex(skill, out var indexedSkill))
|
||||
continue;
|
||||
|
||||
if (HaveFreeSkill(target, skill))
|
||||
continue;
|
||||
|
||||
foreach (var req in indexedSkill.Restrictions)
|
||||
{
|
||||
if (req is NeedPrerequisite prerequisite)
|
||||
{
|
||||
if (frontier.Contains(prerequisite.Prerequisite))
|
||||
frontier.Remove(prerequisite.Prerequisite);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return frontier;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function to reset skills to only learned skills
|
||||
/// </summary>
|
||||
@@ -264,6 +304,45 @@ public abstract partial class CP14SharedSkillSystem : EntitySystem
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increases the number of memory points for a character, limited to a certain amount.
|
||||
/// </summary>
|
||||
public void AddMemoryPoints(EntityUid target, FixedPoint2 points, FixedPoint2 limit, CP14SkillStorageComponent? component = null)
|
||||
{
|
||||
if (!Resolve(target, ref component, false))
|
||||
return;
|
||||
|
||||
component.ExperienceMaxCap = FixedPoint2.Min(component.ExperienceMaxCap + points, limit);
|
||||
Dirty(target, component);
|
||||
|
||||
_popup.PopupEntity(Loc.GetString("cp14-skill-popup-added-points", ("count", points)), target, target);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes memory points. If a character has accumulated skills exceeding the new memory limit, random skills will be removed.
|
||||
/// </summary>
|
||||
public void RemoveMemoryPoints(EntityUid target, FixedPoint2 points, CP14SkillStorageComponent? component = null)
|
||||
{
|
||||
if (!Resolve(target, ref component, false))
|
||||
return;
|
||||
|
||||
component.ExperienceMaxCap = FixedPoint2.Max(component.ExperienceMaxCap - points, 0);
|
||||
Dirty(target, component);
|
||||
|
||||
_popup.PopupEntity(Loc.GetString("cp14-skill-popup-removed-points", ("count", points)), target, target);
|
||||
|
||||
while (component.SkillsSumExperience > component.ExperienceMaxCap)
|
||||
{
|
||||
var frontier = GetFrontierSkills(target, component);
|
||||
if (frontier.Count == 0)
|
||||
break;
|
||||
|
||||
//Randomly remove one of the frontier skills
|
||||
var skill = _random.Pick(frontier);
|
||||
TryRemoveSkill(target, skill, component);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ByRefEvent]
|
||||
|
||||
@@ -51,58 +51,16 @@ public abstract partial class CP14SharedSkillSystem
|
||||
|
||||
var target = args.Target;
|
||||
|
||||
//Add Skill
|
||||
foreach (var skill in _allSkills)
|
||||
{
|
||||
if (ent.Comp.LearnedSkills.Contains(skill))
|
||||
continue;
|
||||
|
||||
var name = Loc.GetString(GetSkillName(skill));
|
||||
args.Verbs.Add(new Verb
|
||||
{
|
||||
Text = name,
|
||||
Message = name + ": " + Loc.GetString(GetSkillDescription(skill)),
|
||||
Category = VerbCategory.CP14AdminSkillAdd,
|
||||
Icon = skill.Icon,
|
||||
Act = () =>
|
||||
{
|
||||
TryAddSkill(target, skill);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
//Remove Skill
|
||||
foreach (var skill in ent.Comp.LearnedSkills)
|
||||
{
|
||||
if (!_proto.TryIndex(skill, out var indexedSkill))
|
||||
continue;
|
||||
|
||||
var name = Loc.GetString(GetSkillName(skill));
|
||||
args.Verbs.Add(new Verb
|
||||
{
|
||||
Text = name,
|
||||
Message = name + ": " + Loc.GetString(GetSkillDescription(skill)),
|
||||
Category = VerbCategory.CP14AdminSkillRemove,
|
||||
Icon = indexedSkill.Icon,
|
||||
Act = () =>
|
||||
{
|
||||
TryRemoveSkill(target, skill);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
//Reset/Remove All Skills
|
||||
args.Verbs.Add(new Verb
|
||||
{
|
||||
Text = "Reset skills",
|
||||
Message = "Remove all learned skills",
|
||||
Category = VerbCategory.CP14AdminSkillRemove,
|
||||
Icon = new SpriteSpecifier.Rsi(new("/Textures/_CP14/Interface/Misc/reroll.rsi"), "reroll"),
|
||||
Act = () =>
|
||||
{
|
||||
TryResetSkills(target);
|
||||
},
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
75
Content.Shared/_CP14/Skill/CP14SkillSystem.Scanning.cs
Normal file
75
Content.Shared/_CP14/Skill/CP14SkillSystem.Scanning.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using System.Text;
|
||||
using Content.Shared._CP14.Skill.Components;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared._CP14.Skill;
|
||||
|
||||
public abstract partial class CP14SharedSkillSystem
|
||||
{
|
||||
[Dependency] private readonly ExamineSystemShared _examine = default!;
|
||||
|
||||
private void InitializeScanning()
|
||||
{
|
||||
SubscribeLocalEvent<CP14SkillScannerComponent, CP14SkillScanEvent>(OnSkillScan);
|
||||
SubscribeLocalEvent<CP14SkillScannerComponent, InventoryRelayedEvent<CP14SkillScanEvent>>((e, c, ev) => OnSkillScan(e, c, ev.Args));
|
||||
|
||||
SubscribeLocalEvent<CP14SkillStorageComponent, GetVerbsEvent<ExamineVerb>>(OnExamined);
|
||||
}
|
||||
|
||||
private void OnExamined(Entity<CP14SkillStorageComponent> ent, ref GetVerbsEvent<ExamineVerb> args)
|
||||
{
|
||||
var scanEvent = new CP14SkillScanEvent();
|
||||
RaiseLocalEvent(args.User, scanEvent);
|
||||
|
||||
if (!scanEvent.CanScan)
|
||||
return;
|
||||
|
||||
var markup = GetSkillExamine(ent);
|
||||
|
||||
_examine.AddDetailedExamineVerb(
|
||||
args,
|
||||
ent.Comp,
|
||||
markup,
|
||||
Loc.GetString("cp14-skill-info-title"),
|
||||
"/Textures/Interface/students-cap.svg.192dpi.png");
|
||||
}
|
||||
|
||||
private FormattedMessage GetSkillExamine(Entity<CP14SkillStorageComponent> ent)
|
||||
{
|
||||
var msg = new FormattedMessage();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
sb.Append(Loc.GetString("cp14-skill-examine-title") + "\n");
|
||||
|
||||
foreach (var skill in ent.Comp.LearnedSkills)
|
||||
{
|
||||
if (!_proto.TryIndex(skill, out var indexedSkill))
|
||||
continue;
|
||||
|
||||
if(!_proto.TryIndex(indexedSkill.Tree, out var indexedTree))
|
||||
continue;
|
||||
|
||||
var skillName = GetSkillName(skill);
|
||||
sb.Append($"• [color={indexedTree.Color.ToHex()}]{skillName}[/color]\n");
|
||||
}
|
||||
|
||||
sb.Append($"\n{Loc.GetString("cp14-skill-menu-level")} {ent.Comp.SkillsSumExperience}/{ent.Comp.ExperienceMaxCap}\n");
|
||||
msg.AddMarkupOrThrow(sb.ToString());
|
||||
return msg;
|
||||
}
|
||||
|
||||
private void OnSkillScan(EntityUid uid, CP14SkillScannerComponent component, CP14SkillScanEvent args)
|
||||
{
|
||||
args.CanScan = true;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CP14SkillScanEvent : EntityEventArgs, IInventoryRelayEvent
|
||||
{
|
||||
public bool CanScan;
|
||||
public SlotFlags TargetSlots { get; } = SlotFlags.EYES;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared._CP14.Skill.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Allows you to see what skills the creature possesses
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class CP14SkillScannerComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -14,9 +14,15 @@ namespace Content.Shared._CP14.Skill.Components;
|
||||
[Access(typeof(CP14SharedSkillSystem), typeof(CP14SharedResearchSystem))]
|
||||
public sealed partial class CP14SkillStorageComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Skill trees displayed in the skill tree interface. Only skills from these trees can be learned by this player.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public HashSet<ProtoId<CP14SkillTreePrototype>> AvailableSkillTrees = new();
|
||||
|
||||
/// <summary>
|
||||
/// Tracks skills that are learned without spending memory points.
|
||||
/// the skills that are here are DUBLED in the LearnedSkills,
|
||||
/// the skills that are here are DOUBLED in the LearnedSkills,
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public List<ProtoId<CP14SkillPrototype>> FreeLearnedSkills = new();
|
||||
|
||||
@@ -41,7 +41,4 @@ public sealed partial class CP14SkillTreePrototype : IPrototype
|
||||
|
||||
[DataField]
|
||||
public SoundSpecifier LearnSound = new SoundCollectionSpecifier("CP14LearnSkill");
|
||||
|
||||
[DataField]
|
||||
public SpriteSpecifier? Icon = null;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
using Content.Shared._CP14.Religion.Components;
|
||||
using Content.Shared._CP14.Skill.Prototypes;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Skill.Restrictions;
|
||||
|
||||
public sealed partial class GodFollowerPercentage : CP14SkillRestriction
|
||||
{
|
||||
[DataField]
|
||||
public FixedPoint2 Percentage = 0.5f;
|
||||
public override bool Check(IEntityManager entManager, EntityUid target, CP14SkillPrototype skill)
|
||||
{
|
||||
if (!entManager.TryGetComponent<CP14ReligionEntityComponent>(target, out var god))
|
||||
return false;
|
||||
|
||||
if (god.Religion is null)
|
||||
return false;
|
||||
|
||||
return god.FollowerPercentage >= Percentage;
|
||||
}
|
||||
|
||||
public override string GetDescription(IEntityManager entManager, IPrototypeManager protoManager)
|
||||
{
|
||||
return Loc.GetString("cp14-skill-req-god-follower-percentage", ("count", Percentage * 100));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared._CP14.Trading.Components;
|
||||
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class CP14PriceScannerComponent : Component { }
|
||||
@@ -11,7 +11,7 @@ public sealed class CP14WeatherData
|
||||
public ProtoId<WeatherPrototype>? Visuals { get; set; } = null;
|
||||
|
||||
[DataField]
|
||||
public MinMax Duration { get; set; } = new(30, 300);
|
||||
public MinMax Duration { get; set; } = new(120, 600);
|
||||
|
||||
[DataField]
|
||||
public float Weight { get; set; } = 1f;
|
||||
|
||||
@@ -67,3 +67,8 @@
|
||||
license: "CC-BY-4.0"
|
||||
copyright: 'by iainmccurdy of Freesound.org. Cropped and mixed from stereo to mono.'
|
||||
source: "https://freesound.org/people/iainmccurdy/sounds/743820/"
|
||||
|
||||
- files: ["flem1.ogg, flem2.ogg, flem3.ogg"]
|
||||
license: "CC0-1.0"
|
||||
copyright: 'by muckypete7 of Freesound.org. Cropped and mixed from stereo to mono.'
|
||||
source: "https://freesound.org/people/mucky_pete7/sounds/574208/"
|
||||
|
||||
BIN
Resources/Audio/_CP14/Animals/flem1.ogg
Normal file
BIN
Resources/Audio/_CP14/Animals/flem1.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/_CP14/Animals/flem2.ogg
Normal file
BIN
Resources/Audio/_CP14/Animals/flem2.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/_CP14/Animals/flem3.ogg
Normal file
BIN
Resources/Audio/_CP14/Animals/flem3.ogg
Normal file
Binary file not shown.
@@ -91,4 +91,14 @@
|
||||
- files: ["cash.ogg"]
|
||||
license: "CC0-1.0"
|
||||
copyright: 'Created by Zott820 on Freesound.org'
|
||||
source: "https://freesound.org/people/Zott820/sounds/209578/"
|
||||
source: "https://freesound.org/people/Zott820/sounds/209578/"
|
||||
|
||||
- files: ["ritual_begin.ogg", "ritual_end.ogg"]
|
||||
license: "CC-BY-4.0"
|
||||
copyright: 'Created by SilverIllusionist on Freesound.org'
|
||||
source: "https://freesound.org/people/SilverIllusionist/sounds/671928/"
|
||||
|
||||
- files: ["moon_strike1.ogg", "moon_strike2.ogg", "moon_strike3.ogg", "moon_strike4.ogg"]
|
||||
license: "CC-BY-4.0"
|
||||
copyright: 'Created by EminYILDIRIM on Freesound.org'
|
||||
source: "https://freesound.org/people/EminYILDIRIM/sounds/668244/"
|
||||
BIN
Resources/Audio/_CP14/Effects/moon_strike1.ogg
Normal file
BIN
Resources/Audio/_CP14/Effects/moon_strike1.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/_CP14/Effects/moon_strike2.ogg
Normal file
BIN
Resources/Audio/_CP14/Effects/moon_strike2.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/_CP14/Effects/moon_strike3.ogg
Normal file
BIN
Resources/Audio/_CP14/Effects/moon_strike3.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/_CP14/Effects/moon_strike4.ogg
Normal file
BIN
Resources/Audio/_CP14/Effects/moon_strike4.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/_CP14/Effects/ritual_begin.ogg
Normal file
BIN
Resources/Audio/_CP14/Effects/ritual_begin.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/_CP14/Effects/ritual_end.ogg
Normal file
BIN
Resources/Audio/_CP14/Effects/ritual_end.ogg
Normal file
Binary file not shown.
@@ -320,3 +320,93 @@
|
||||
id: 8084
|
||||
time: '2025-06-10T08:07:13.0000000+00:00'
|
||||
url: https://github.com/crystallpunk-14/crystall-punk-14/pull/1412
|
||||
- author: gogenych
|
||||
changes:
|
||||
- message: Copper tools and weapons are now displayed correctly in loadout
|
||||
type: Fix
|
||||
id: 8085
|
||||
time: '2025-06-10T10:40:19.0000000+00:00'
|
||||
url: https://github.com/crystallpunk-14/crystall-punk-14/pull/1414
|
||||
- author: firebat4321
|
||||
changes:
|
||||
- message: Added new combat-focused T2 Pryokinetic spell, Firebolt!
|
||||
type: Add
|
||||
id: 8086
|
||||
time: '2025-06-10T11:14:08.0000000+00:00'
|
||||
url: https://github.com/crystallpunk-14/crystall-punk-14/pull/1354
|
||||
- author: Sefaia
|
||||
changes:
|
||||
- message: Added Quiver filled with Big Iron Crossbow Bolts to Entity Spawn Menu
|
||||
for Admins/Testers
|
||||
type: Add
|
||||
- message: Fixed Quiver to hold Big Crossbow Bolts.
|
||||
type: Fix
|
||||
id: 8087
|
||||
time: '2025-06-13T07:34:32.0000000+00:00'
|
||||
url: https://github.com/crystallpunk-14/crystall-punk-14/pull/1418
|
||||
- author: SenorJaba
|
||||
changes:
|
||||
- message: Merchant's monocle has been added to replace appraisal tool.
|
||||
type: Add
|
||||
- message: Added a new trader's wit skill which works similarly to merchant's monocle.
|
||||
type: Add
|
||||
- message: Alchemist's glasses and monocle, and merchant's monocle were added into
|
||||
the buying platform.
|
||||
type: Add
|
||||
- message: Appraisal tool has been removed from the merchant's closet.
|
||||
type: Remove
|
||||
- message: Alchemist's glasses and monocle were removed from the alchemist's loadout.
|
||||
type: Remove
|
||||
id: 8088
|
||||
time: '2025-06-13T09:24:36.0000000+00:00'
|
||||
url: https://github.com/crystallpunk-14/crystall-punk-14/pull/1413
|
||||
- author: Fr0goo
|
||||
changes:
|
||||
- message: Added new creature named Flem! You can find them in demiplanes.
|
||||
type: Add
|
||||
- message: Added fish suit and mask!
|
||||
type: Add
|
||||
- message: Added a probaly temporary way to make fish pie!
|
||||
type: Add
|
||||
id: 8089
|
||||
time: '2025-06-13T10:25:33.0000000+00:00'
|
||||
url: https://github.com/crystallpunk-14/crystall-punk-14/pull/1402
|
||||
- author: TheShuEd
|
||||
changes:
|
||||
- message: A patron system has been added. By interacting with the primordial statues,
|
||||
you can become a follower of a patron. For more details, please refer to the
|
||||
in-game guidebooks.
|
||||
type: Add
|
||||
- message: "The divine patron of the night sky and knowledge, \u201CLumera,\u201D\
|
||||
\ has been added. This is a game role that gains new abilities based on the\
|
||||
\ number of followers and is capable of interacting with areas of visibility\
|
||||
\ and granting (or taking away) memory points from other players."
|
||||
type: Add
|
||||
id: 8090
|
||||
time: '2025-06-15T15:00:33.0000000+00:00'
|
||||
url: https://github.com/crystallpunk-14/crystall-punk-14/pull/1427
|
||||
- author: TheShuEd
|
||||
changes:
|
||||
- message: Added firewave spell. Now it looks like a shotgun, only made of fire.
|
||||
type: Add
|
||||
- message: Removed firebolt spell.
|
||||
type: Remove
|
||||
- message: Spiders' health reduced by half
|
||||
type: Tweak
|
||||
id: 8091
|
||||
time: '2025-06-15T15:03:38.0000000+00:00'
|
||||
url: https://github.com/crystallpunk-14/crystall-punk-14/pull/1430
|
||||
- author: TheShuEd
|
||||
changes:
|
||||
- message: you can buy wheat and cotton into victorian gardens trade faction
|
||||
type: Add
|
||||
- message: Demiplanes can no longer devour patrons if they close while the patron
|
||||
is inside the demoplan.
|
||||
type: Fix
|
||||
- message: Patron saints can no longer occupy entry slots into the demiplane.
|
||||
type: Fix
|
||||
- message: Passports removed from the gods-patrons
|
||||
type: Fix
|
||||
id: 8092
|
||||
time: '2025-06-15T18:25:58.0000000+00:00'
|
||||
url: https://github.com/crystallpunk-14/crystall-punk-14/pull/1432
|
||||
|
||||
@@ -4,7 +4,7 @@ cp14-currency-examine-gp = [color=#ebad3b]{$coin}gp[/color]
|
||||
cp14-currency-examine-sp = [color=#bad1d6]{$coin}sp[/color]
|
||||
cp14-currency-examine-cp = [color=#824e27]{$coin}cp[/color]
|
||||
|
||||
cp14-currency-converter-insert = {$cash}cp ddeposited!
|
||||
cp14-currency-converter-insert = {$cash}cp deposited!
|
||||
cp14-verb-categories-currency-converter = Withdraw currency:
|
||||
cp14-currency-converter-get-cp = As cp (1cp)
|
||||
cp14-currency-converter-get-sp = As sp (10cp)
|
||||
|
||||
@@ -24,6 +24,7 @@ cp14-modifier-air-lily = air lilies
|
||||
cp14-modifier-shadow-kudzu = spreading astral haze
|
||||
cp14-modifier-night = darkness
|
||||
cp14-modifier-spiders = spider's web
|
||||
cp14-modifier-flem = flemings
|
||||
|
||||
cp14-modifier-storm = storm
|
||||
cp14-modifier-fire-storm = fire storm
|
||||
|
||||
@@ -11,4 +11,7 @@ department-CP14Guard = Guards
|
||||
department-CP14Guard-desc = Protectors and warriors who oversee security and law and order in all corners of the Empire.
|
||||
|
||||
department-CP14Artisan = Artisans
|
||||
department-CP14Artisan-desc = People who have learnt peaceful professions, people who help the settlement with their knowledge and skills.
|
||||
department-CP14Artisan-desc = People who have learnt peaceful professions, people who help the settlement with their knowledge and skills.
|
||||
|
||||
department-CP14Demigods = Patrons
|
||||
department-CP14Demigods-desc = Higher beings playing their own games, where ordinary creatures are merely pawns in their plans.
|
||||
@@ -34,4 +34,12 @@ cp14-job-name-blacksmith = Blacksmith
|
||||
cp14-job-desc-blacksmith = Create and improve equipment for everyone in need! You have the power of metal and fire in your hands, and only you know how to use them carefully to create masterpieces.
|
||||
|
||||
cp14-job-name-apprentice = Apprentice
|
||||
cp14-job-desc-apprentice = A peaceful citizen of the empire, just beginning to learn the subtleties of various sciences. Choose a specialisation in equipment, and try to help others in their work, in exchange for a salary and invaluable experience.
|
||||
cp14-job-desc-apprentice = A peaceful citizen of the empire, just beginning to learn the subtleties of various sciences. Try to help others in their work, in exchange for a salary and invaluable experience.
|
||||
|
||||
# Demigods
|
||||
|
||||
cp14-job-name-god-merkas = Merkas
|
||||
cp14-job-desc-god-merkas = God of purity and healing. TODO
|
||||
|
||||
cp14-job-name-god-lumera = Lumera
|
||||
cp14-job-desc-god-lumera = Patroness of the night sky and knowledge. Expand your influence by helping mortals gain new knowledge.
|
||||
@@ -22,4 +22,5 @@ cp14-magic-spell-pacified = It could hurt someone!
|
||||
|
||||
cp14-magic-spell-target-not-mob = The target must be a living thing!
|
||||
cp14-magic-spell-target-dead = Can't be used on the dead!
|
||||
cp14-magic-spell-target-alive = Can't be used on the living!
|
||||
cp14-magic-spell-target-alive = Can't be used on the living!
|
||||
cp14-magic-spell-target-god-follower = Your target should be your follower!
|
||||
23
Resources/Locale/en-US/_CP14/religion/altar.ftl
Normal file
23
Resources/Locale/en-US/_CP14/religion/altar.ftl
Normal file
@@ -0,0 +1,23 @@
|
||||
cp14-altar-wrapped-message = [bold]{$name}[/bold] prays, {$msg}
|
||||
cp14-offer-soul-god-message = [bold]{$name}[/bold] [color=green]wants to become your follower[/color]. Touch him to establish a connection.
|
||||
cp14-unoffer-soul-god-message = [bold]{$name}[/bold] [color=red]has changed his mind about becoming your follower.[/color]
|
||||
cp14-become-follower-message = [bold]{$name}[/bold] [color=green]becomes your follower[/color]!
|
||||
cp14-remove-follower-message = [bold]{$name}[/bold] [color=red]rejects you and will never be able to return to you![/color]
|
||||
cp14-call-follower-message = [bold]{$name}[/bold] appeals to you!
|
||||
cp14-critical-follower-message = [bold]{$name}[/bold] is falling into critical condition!
|
||||
cp14-dead-follower-message = [bold]{$name}[/bold] is dead!
|
||||
|
||||
cp14-renounce-action-popup = YOU ARE RENOUNCING YOUR PATRON! To confirm, perform the action again.
|
||||
cp-renounce-action-god-popup = YOU ARE REJECTING YOUR FOLLOWER! To confirm, perform the action again.
|
||||
|
||||
cp14-god-ui-title = Fast Travel
|
||||
cp14-god-ui-follower = Followers
|
||||
cp14-god-ui-altars = Altars
|
||||
cp14-god-ui-follower-percentage = Follower percentage: {$count}%
|
||||
cp14-god-ui-mana-percentage = Divine energy: {$count}%
|
||||
|
||||
cp14-altar-become-follower = Become a follower
|
||||
cp14-altar-become-follower-desc = You offer yourself into the service of your patron. If he agrees, your bond will be strengthened.
|
||||
|
||||
cp14-alert-offer = Offer of patronage
|
||||
cp14-alert-offer-desc = You want to become a follower of the patron, but there is no response from him yet. Click to cancel the offer.
|
||||
@@ -1,4 +1,5 @@
|
||||
cp14-skill-req-prerequisite = Skill "{$name}" must be learned
|
||||
cp14-skill-req-species = You must be the race of “{$name}”
|
||||
cp14-skill-req-researched = A study needs to be done on the research table
|
||||
cp14-skill-req-impossible = Unable to explore during a round at the current moment
|
||||
cp14-skill-req-impossible = Unable to explore during a round at the current moment
|
||||
cp14-skill-req-god-follower-percentage = The number of your followers should be more than {$count}%
|
||||
@@ -31,4 +31,7 @@ cp14-skill-copper-melt-name = Copper melting
|
||||
cp14-skill-iron-melt-name = Iron melting
|
||||
cp14-skill-gold-melt-name = Gold melting
|
||||
cp14-skill-mithril-melt-name = Mithril melting
|
||||
cp14-skill-glass-melt-name = Glasswork
|
||||
cp14-skill-glass-melt-name = Glasswork
|
||||
|
||||
cp14-skill-trader-wit-name = Trader's wit
|
||||
cp14-skill-trader-wit-desc = You are able to estimate the exact value of any item in the empire at a first glance.
|
||||
6
Resources/Locale/en-US/_CP14/skill/skill_meta_gods.ftl
Normal file
6
Resources/Locale/en-US/_CP14/skill/skill_meta_gods.ftl
Normal file
@@ -0,0 +1,6 @@
|
||||
cp14-skill-lumera-t1-name = The origins of the secret night
|
||||
cp14-skill-lumera-t2-name = The waxing moon
|
||||
cp14-skill-lumera-t3-name = The full moon of Lumera
|
||||
|
||||
cp14-skill-lumera-mind-scan-name = Study of minds
|
||||
cp14-skill-lumera-mind-scan-desc = You are able to discern the skills possessed by mortals. You can see what spells they are capable of casting and what they are capable of doing.
|
||||
@@ -29,8 +29,14 @@ cp14-skill-tree-martial-desc = Master the secrets of deadly weapons, or make you
|
||||
|
||||
# Job
|
||||
|
||||
cp14-skill-tree-thaumaturgy-name = Alchemy
|
||||
cp14-skill-tree-thaumaturgy-desc = The art of creating magical potions that can kill, raise from the dead, or turn creatures into sheep.
|
||||
#cp14-skill-tree-thaumaturgy-name = Alchemy
|
||||
#cp14-skill-tree-thaumaturgy-desc = The art of creating magical potions that can kill, raise from the dead, or turn creatures into sheep.
|
||||
|
||||
cp14-skill-tree-blacksmithing-name = Blacksmithing
|
||||
cp14-skill-tree-blacksmithing-desc = The art of turning metal into various useful things.
|
||||
#cp14-skill-tree-blacksmithing-name = Blacksmithing
|
||||
#cp14-skill-tree-blacksmithing-desc = The art of turning metal into various useful things.
|
||||
|
||||
#cp14-skill-tree-trading-name = Trading
|
||||
#cp14-skill-tree-trading-desc = The art of understanding where, when and for how much to sell and buy different items.
|
||||
|
||||
cp14-skill-tree-craftsman-name = Craftsmanship
|
||||
cp14-skill-tree-craftsman-desc = Learn the arts and crafts that let you create and use all kinds of useful things.
|
||||
@@ -14,4 +14,9 @@ cp14-research-recipe-list = Research costs:
|
||||
cp14-research-craft = Research
|
||||
|
||||
cp14-skill-desc-add-mana = Increases your character's mana amount by {$mana}.
|
||||
cp14-skill-desc-unlock-recipes = Opens up the possibility of crafting:
|
||||
cp14-skill-desc-unlock-recipes = Opens up the possibility of crafting:
|
||||
|
||||
cp14-skill-popup-added-points = The boundaries of your consciousness are expanding. New memory points: {$count}
|
||||
|
||||
cp14-skill-examine-title = This character has the following skills:
|
||||
cp14-skill-popup-forced-remove-skill = You are beginning to forget your past... Memory points lost: {$count}
|
||||
@@ -8,4 +8,6 @@ cp14-trading-faction-prefix = Trading with:
|
||||
|
||||
cp14-trading-failure-popup-money = Not enough funds on the platform!
|
||||
|
||||
cp14-trading-contract-use = Trade with "{$name}" unlocked!
|
||||
cp14-trading-contract-use = Trade with "{$name}" unlocked!
|
||||
|
||||
cp14-trading-empty-price = None!
|
||||
@@ -754,6 +754,9 @@ ent-CP14ClothingEyesAlchemyGlasses = алхимические очки
|
||||
ent-CP14ClothingEyesAlchemyMonocle = алхимический монокль
|
||||
.desc = Специальный магический монокль, позволяющий четко видеть состав любых смесей.
|
||||
|
||||
ent-CP14ClothingEyesMerchantMonocle = монокль торговца
|
||||
.desc = Магический увеличительный монокль высочайшего качества, позволяющий вам определить точную цену любого товара.
|
||||
|
||||
ent-CP14ClothingEyesThaumaturgyGlasses = тауматургические очки
|
||||
.desc = Очки, позволяющие сканировать магические предметы и существ, чтобы четко видеть количество оставшейся в них энергии.
|
||||
|
||||
|
||||
@@ -11,4 +11,7 @@ department-CP14Guard = Стража
|
||||
department-CP14Guard-desc = Защитники и войны, следящие за безопасностью и правопорядком во всех уголках империи.
|
||||
|
||||
department-CP14Artisan = Ремесленники
|
||||
department-CP14Artisan-desc = Освоившие мирные профессии, люди, которые помогают поселению своими знаниями и умениями.
|
||||
department-CP14Artisan-desc = Освоившие мирные профессии, люди, которые помогают поселению своими знаниями и умениями.
|
||||
|
||||
department-CP14Demigods = Покровители
|
||||
department-CP14Demigods-desc = Высшие сущности, играющие в свои собственные игры, где обычные существа лишь пешки в их планах.
|
||||
@@ -34,4 +34,12 @@ cp14-job-name-blacksmith = Кузнец
|
||||
cp14-job-desc-blacksmith = Создавайте и улучшайте экипировку для всех нуждающихся! В ваших руках мощь металла и огня, и только вы знаете как аккуратно использовать их, чтобы создавать шедевры.
|
||||
|
||||
cp14-job-name-apprentice = Подмастерье
|
||||
cp14-job-desc-apprentice = Мирный житель империи, только начинающий постигать тонкости различных наук. Выберите специализацию в экипировке, и постарайтесь помочь другим в их работе, в обмен на зарплату и бесценный опыт.
|
||||
cp14-job-desc-apprentice = Мирный житель империи, только начинающий постигать тонкости различных наук. Постарайтесь помочь другим в их работе, в обмен на зарплату и бесценный опыт.
|
||||
|
||||
# Demigods
|
||||
|
||||
cp14-job-name-god-merkas = Меркас
|
||||
cp14-job-desc-god-merkas = Бог света и исцеления. TODO
|
||||
|
||||
cp14-job-name-god-lumera = Лумера
|
||||
cp14-job-desc-god-lumera = Покровительница ночного неба и знаний. Расширяйте свое влияние, помогая смертным обретать новые знания.
|
||||
@@ -22,4 +22,5 @@ cp14-magic-spell-pacified = Это может навредить кому либ
|
||||
|
||||
cp14-magic-spell-target-not-mob = Цель должна быть живым существом!
|
||||
cp14-magic-spell-target-dead = Нельзя использовать на мертвых!
|
||||
cp14-magic-spell-target-alive = Нельзя использовать на живых!
|
||||
cp14-magic-spell-target-alive = Нельзя использовать на живых!
|
||||
cp14-magic-spell-target-god-follower = Цель должна быть вашим последователем!
|
||||
23
Resources/Locale/ru-RU/_CP14/religion/altar.ftl
Normal file
23
Resources/Locale/ru-RU/_CP14/religion/altar.ftl
Normal file
@@ -0,0 +1,23 @@
|
||||
cp14-altar-wrapped-message = [bold]{$name}[/bold] молится, {$msg}
|
||||
cp14-offer-soul-god-message = [bold]{$name}[/bold] [color=green]хочет стать вашим последователем[/color]. Прикоснитесь к нему, чтобы установить связь.
|
||||
cp14-unoffer-soul-god-message = [bold]{$name}[/bold] [color=red]передумал становиться вашим последователем.[/color]
|
||||
cp14-become-follower-message = [bold]{$name}[/bold] [color=green]становится вашим последователем[/color]!
|
||||
cp14-remove-follower-message = [bold]{$name}[/bold] [color=red]отвергает вас, и больше никогда не сможет вернться к вам![/color]
|
||||
cp14-call-follower-message = [bold]{$name}[/bold] взывает к вам!
|
||||
cp14-critical-follower-message = [bold]{$name}[/bold] падает в критическое состояние!
|
||||
cp14-dead-follower-message = [bold]{$name}[/bold] погибает!
|
||||
|
||||
cp14-renounce-action-popup = ВЫ ОТРЕКАЕТЕСЬ ОТ ПОКРОВИТЕЛЯ! Для подтверждения выполните действие еще раз.
|
||||
cp-renounce-action-god-popup = ВЫ ОТВЕРГАЕТЕ СВОЕГО ПОСЛЕДОВАТЕЛЯ! Для подтверждения выполните действие еще раз.
|
||||
|
||||
cp14-god-ui-title = Быстрое перемещение
|
||||
cp14-god-ui-follower = Последователи
|
||||
cp14-god-ui-altars = Алтари
|
||||
cp14-god-ui-follower-percentage = Процент последователей: {$count}%
|
||||
cp14-god-ui-mana-percentage = Божественная энергия: {$count}%
|
||||
|
||||
cp14-altar-become-follower = Стать последователем
|
||||
cp14-altar-become-follower-desc = Вы предлагаете себя в службу покровителю. Если он согласится, ваша связь укрепится.
|
||||
|
||||
cp14-alert-offer = Предложение о покровительстве
|
||||
cp14-alert-offer-desc = Вы хотите стать последователем покровителя, но пока от него нет ответа. Нажмите, чтобы отменить предложение.
|
||||
@@ -1,4 +1,5 @@
|
||||
cp14-skill-req-prerequisite = Навык "{$name}" должен быть изучен
|
||||
cp14-skill-req-species = Вы должны быть расы "{$name}"
|
||||
cp14-skill-req-researched = Необходимо провести исследование на исследовательском столе
|
||||
cp14-skill-req-impossible = Невозможно изучить во время раунда на текущий момент
|
||||
cp14-skill-req-impossible = Невозможно изучить во время раунда на текущий момент
|
||||
cp14-skill-req-god-follower-percentage = Количество ваших последователей должно быть больше {$count}%
|
||||
@@ -31,4 +31,7 @@ cp14-skill-copper-melt-name = Плавка меди
|
||||
cp14-skill-iron-melt-name = Плавка железа
|
||||
cp14-skill-gold-melt-name = Плавка золота
|
||||
cp14-skill-mithril-melt-name = Плавка мифрила
|
||||
cp14-skill-glass-melt-name = Работа со стеклом
|
||||
cp14-skill-glass-melt-name = Работа со стеклом
|
||||
|
||||
cp14-skill-trader-wit-name = Торговая смекалка
|
||||
cp14-skill-trader-wit-desc = Вы способны одним взглядом оценить и вычислить точную стоимость предмета в империи.
|
||||
6
Resources/Locale/ru-RU/_CP14/skill/skill_meta_gods.ftl
Normal file
6
Resources/Locale/ru-RU/_CP14/skill/skill_meta_gods.ftl
Normal file
@@ -0,0 +1,6 @@
|
||||
cp14-skill-lumera-t1-name = Истоки тайной ночи
|
||||
cp14-skill-lumera-t2-name = Растущая луна
|
||||
cp14-skill-lumera-t3-name = Полнолуние Лумеры
|
||||
|
||||
cp14-skill-lumera-mind-scan-name = Изучение разумов
|
||||
cp14-skill-lumera-mind-scan-desc = Вы способны узнавать какими навыками владеют смертные. Видеть, какие заклинания им подвластны, и на что они способны.
|
||||
@@ -1,6 +1,3 @@
|
||||
cp14-skill-tree-blaksmithing-name = Кузнечное дело
|
||||
cp14-skill-tree-blaksmithing-desc = Исследуйте и создавайте новые предметы из металла.
|
||||
|
||||
# Magic
|
||||
|
||||
cp14-skill-tree-pyrokinetic-name = Пирокинетика
|
||||
@@ -31,8 +28,14 @@ cp14-skill-tree-martial-desc = Овладейте секретами смерт
|
||||
|
||||
# Job
|
||||
|
||||
cp14-skill-tree-thaumaturgy-name = Алхимия
|
||||
cp14-skill-tree-thaumaturgy-desc = Исскуство создания волшебных зелий, способных убивать, воскрешать из мертвых или превращать существ в овечек.
|
||||
#cp14-skill-tree-thaumaturgy-name = Алхимия
|
||||
#cp14-skill-tree-thaumaturgy-desc = Исскуство создания волшебных зелий, способных убивать, воскрешать из мертвых или превращать существ в овечек.
|
||||
|
||||
cp14-skill-tree-blacksmithing-name = Кузнечное дело
|
||||
cp14-skill-tree-blacksmithing-desc = Исскуство превращения металла в различные полезные вещи.
|
||||
#cp14-skill-tree-blacksmithing-name = Кузнечное дело
|
||||
#cp14-skill-tree-blacksmithing-desc = Исскуство превращения металла в различные полезные вещи.
|
||||
|
||||
#cp14-skill-tree-trading-name = Торговля
|
||||
#cp14-skill-tree-trading-desc = Исскуство познания где, когда, и за сколько продавать и покупать различные предметы.
|
||||
|
||||
cp14-skill-tree-craftsman-name = Ремесленничество
|
||||
cp14-skill-tree-craftsman-desc = Изучайте навыки и умения для создания и использования различных полезных вещей.
|
||||
@@ -14,4 +14,9 @@ cp14-research-recipe-list = Затраты на исследование:
|
||||
cp14-research-craft = Исследовать
|
||||
|
||||
cp14-skill-desc-add-mana = Увеличивает объем маны вашего персонажа на {$mana}.
|
||||
cp14-skill-desc-unlock-recipes = Открывает возможность создания:
|
||||
cp14-skill-desc-unlock-recipes = Открывает возможность создания:
|
||||
|
||||
cp14-skill-popup-added-points = Границы вашего сознания расширяются. Новых очков памяти: {$count}
|
||||
cp14-skill-popup-forced-remove-skill = Вы начинаете забывать свое прошлое... Потеряно очков памяти: {$count}
|
||||
|
||||
cp14-skill-examine-title = Этот персонаж владеет следующими навыками:
|
||||
@@ -8,4 +8,6 @@ cp14-trading-faction-prefix = Торговля с:
|
||||
|
||||
cp14-trading-failure-popup-money = Недостаточно средств на платформе!
|
||||
|
||||
cp14-trading-contract-use = Торговля с "{$name}" разблокирована!
|
||||
cp14-trading-contract-use = Торговля с "{$name}" разблокирована!
|
||||
|
||||
cp14-trading-empty-price = Отсутствует!
|
||||
@@ -4,8 +4,8 @@ meta:
|
||||
engineVersion: 260.2.0
|
||||
forkId: ""
|
||||
forkVersion: ""
|
||||
time: 06/04/2025 21:43:51
|
||||
entityCount: 15261
|
||||
time: 06/15/2025 11:12:00
|
||||
entityCount: 15254
|
||||
maps:
|
||||
- 1
|
||||
grids:
|
||||
@@ -190,7 +190,7 @@ entities:
|
||||
version: 7
|
||||
0,-3:
|
||||
ind: 0,-3
|
||||
tiles: AgAAAAAAAAIAAAAAAAAcAAAAAAAAAgAAAAABAAIAAAAADwAcAAAAAAUAAgAAAAAHAAIAAAAACgACAAAAAAIAHAAAAAAEABwAAAAABQAcAAAAAAEAHAAAAAABABwAAAAAAQAeAAAAAAEAHgAAAAAAAAMAAAAAAAADAAAAAAAADQAAAAAAAA0AAAAAAAANAAAAAAAADQAAAAAAAA0AAAAAAAANAAAAAAAADQAAAAAAAA0AAAAAAAADAAAAAAgAAwAAAAAAAAMAAAAAAAADAAAAAAQAAwAAAAAAAAMAAAAAAAAQAAAAAAAAEAAAAAAAAA0AAAAAAAANAAAAAAAADQAAAAAAAA0AAAAAAAANAAAAAAAADQAAAAAAAA0AAAAAAAANAAAAAAAADQAAAAAAAA0AAAAAAAANAAAAAAAADQAAAAAAAA0AAAAAAAANAAAAAAAAAwAAAAAAAAMAAAAAAAANAAAAAAAADQAAAAAAAA0AAAAAAAANAAAAAAAADQAAAAAAAA0AAAAAAAANAAAAAAAADQAAAAAAAAMAAAAABAABAAAAAAIAAQAAAAADAAEAAAAAAgANAAAAAAAAHgAAAAAAACEAAAAAAAACAAAAAAYAHAAAAAAAABwAAAAAAAAcAAAAAAAAHAAAAAAAABwAAAAAAAAcAAAAAAAAHAAAAAAAAB4AAAAAAgADAAAAAAAAAQAAAAACAB4AAAAAAAABAAAAAAQAAQAAAAABAAEAAAAAAwAhAAAAAAAAAgAAAAANAB4AAAAAAAAcAAAAAAAAHAAAAAAAAB0AAAAAAAAdAAAAAAAAHQAAAAAAAB0AAAAAAAAeAAAAAAIAAwAAAAAAAB4AAAAAAwABAAAAAAQAAQAAAAADAAEAAAAAAQABAAAAAAQAIQAAAAAAAAIAAAAABAAeAAAAAAAAHgAAAAAAAB0AAAAAAAAdAAAAAAAAHQAAAAAAAB4AAAAAAAAdAAAAAAAAHgAAAAAFAAMAAAAAAAABAAAAAAAAAQAAAAACAAEAAAAAAgABAAAAAAQAHgAAAAAEACEAAAAAAAAeAAAAAAUAHAAAAAAAAB4AAAAAAAAdAAAAAAAAHQAAAAAAAB4AAAAAAAAeAAAAAAAAHgAAAAAAAB4AAAAABQADAAAAAAAAAQAAAAADAAEAAAAAAAABAAAAAAEAAQAAAAACAAEAAAAAAgAhAAAAAAAAHgAAAAAAAB0AAAAAAAAeAAAAAAAAHQAAAAAAAB0AAAAAAAAcAAAAAAAAHgAAAAAAAB4AAAAAAAAeAAAAAAMAAwAAAAAAAAEAAAAAAQABAAAAAAQAAQAAAAAEAAEAAAAAAgABAAAAAAAAIQAAAAAAAB4AAAAAAQAdAAAAAAAAHQAAAAAAAB0AAAAAAAAcAAAAAAAAHgAAAAAAAB4AAAAAAAAeAAAAAAAAHgAAAAAAAAMAAAAAAAABAAAAAAEAAQAAAAACAAEAAAAAAQABAAAAAAQAAQAAAAAAACEAAAAAAAACAAAAAA0AHAAAAAAAAB0AAAAAAAAdAAAAAAAAHQAAAAAAAB0AAAAAAAAdAAAAAAAAHgAAAAAAAB4AAAAAAQADAAAAAAAAAQAAAAACAAEAAAAAAgABAAAAAAQAAQAAAAADAAEAAAAAAgAhAAAAAAAAHAAAAAAAAB4AAAAAAQAeAAAAAAAAHgAAAAACAB4AAAAABAAeAAAAAAIAHQAAAAAAAAIAAAAABgAeAAAAAAEAAwAAAAAAAAEAAAAAAwABAAAAAAAAAQAAAAADAAEAAAAAAwABAAAAAAEAIQAAAAAAAB4AAAAABQAGAAAAAAIABgAAAAAAAAYAAAAAAgAGAAAAAAAABgAAAAAAAAYAAAAAAAAGAAAAAAIAHgAAAAABAAMAAAAAAgAeAAAAAAUAAQAAAAADAAEAAAAABAABAAAAAAAAAQAAAAACACEAAAAAAAAeAAAAAAEABgAAAAACAAUAAAAAAwAFAAAAAAMABQAAAAADAAUAAAAAAgAFAAAAAAIABgAAAAADAB4AAAAABAADAAAAAAAAHgAAAAAAAB4AAAAAAgAeAAAAAAQAHgAAAAAAAAEAAAAAAAACAAAAAAAAAgAAAAAEAAYAAAAAAgAFAAAAAAMABQAAAAABAAUAAAAAAQAGAAAAAAEABgAAAAADAAYAAAAAAQAeAAAAAAEAAwAAAAAAAB4AAAAABQAeAAAAAAIAHgAAAAABAB4AAAAAAwAeAAAAAAUAAgAAAAAAAAIAAAAACgAGAAAAAAEABQAAAAACAAUAAAAAAAAFAAAAAAAABQAAAAABAAUAAAAAAgAGAAAAAAEAHgAAAAAFAAMAAAAABgADAAAAAAQAAwAAAAADAAMAAAAABAADAAAAAAMAAwAAAAABAA==
|
||||
tiles: AgAAAAAAAAIAAAAAAAAcAAAAAAAAAgAAAAABAAIAAAAADwAcAAAAAAUAAgAAAAAHAAIAAAAACgACAAAAAAIAHAAAAAAEABwAAAAABQAcAAAAAAEAHAAAAAABABwAAAAAAQAeAAAAAAEAHgAAAAAAAAMAAAAAAAADAAAAAAAADQAAAAAAAA0AAAAAAAANAAAAAAAADQAAAAAAAA0AAAAAAAANAAAAAAAADQAAAAAAAA0AAAAAAAADAAAAAAgAAwAAAAAAAAMAAAAAAAADAAAAAAQAAwAAAAAAAAMAAAAAAAAQAAAAAAAAEAAAAAAAAA0AAAAAAAANAAAAAAAADQAAAAAAAA0AAAAAAAANAAAAAAAADQAAAAAAAA0AAAAAAAANAAAAAAAADQAAAAAAAA0AAAAAAAANAAAAAAAADQAAAAAAAA0AAAAAAAANAAAAAAAAAwAAAAAAAAMAAAAAAAANAAAAAAAADQAAAAAAAA0AAAAAAAANAAAAAAAADQAAAAAAAA0AAAAAAAANAAAAAAAADQAAAAAAAAMAAAAABAABAAAAAAIAAQAAAAADAAEAAAAAAgANAAAAAAAAHgAAAAAAACEAAAAAAAACAAAAAAYAHAAAAAAAABwAAAAAAAAcAAAAAAAAHAAAAAAAABwAAAAAAAAcAAAAAAAAHAAAAAAAAB4AAAAAAgADAAAAAAAAAQAAAAACAB4AAAAAAAABAAAAAAQAAQAAAAABAAEAAAAAAwAhAAAAAAAAAgAAAAANAB4AAAAAAAAcAAAAAAAAHAAAAAAAAB0AAAAAAAAdAAAAAAAAHQAAAAAAAB0AAAAAAAAeAAAAAAIAAwAAAAAAAB4AAAAAAwABAAAAAAQAAQAAAAADAAEAAAAAAQABAAAAAAQAIQAAAAAAAAIAAAAABAAeAAAAAAAAHgAAAAAAAB0AAAAAAAAdAAAAAAAAHQAAAAAAAB4AAAAAAAAdAAAAAAAAHgAAAAAFAAMAAAAAAAABAAAAAAAAAQAAAAACAAEAAAAAAgABAAAAAAQAHgAAAAAEACEAAAAAAAAeAAAAAAUAHAAAAAAAAB4AAAAAAAAdAAAAAAAAHQAAAAAAAB4AAAAAAAAeAAAAAAAAHgAAAAAAAB4AAAAABQADAAAAAAAAAQAAAAADAAEAAAAAAAABAAAAAAEAAQAAAAACAAEAAAAAAgAhAAAAAAAAHgAAAAAAAB0AAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAcAAAAAAAAHgAAAAAAAB4AAAAAAAAeAAAAAAMAAwAAAAAAAAEAAAAAAQABAAAAAAQAAQAAAAAEAAEAAAAAAgABAAAAAAAAIQAAAAAAAB4AAAAAAQAdAAAAAAAAEAAAAAAAABEAAAAAAAAQAAAAAAAAHgAAAAAAAB4AAAAAAAAeAAAAAAAAHgAAAAAAAAMAAAAAAAABAAAAAAEAAQAAAAACAAEAAAAAAQABAAAAAAQAAQAAAAAAACEAAAAAAAACAAAAAA0AHAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAAB0AAAAAAAAdAAAAAAAAHgAAAAAAAB4AAAAAAQADAAAAAAAAAQAAAAACAAEAAAAAAgABAAAAAAQAAQAAAAADAAEAAAAAAgAhAAAAAAAAHAAAAAAAAB4AAAAAAQAeAAAAAAAAHgAAAAACAB4AAAAABAAeAAAAAAIAHQAAAAAAAAIAAAAABgAeAAAAAAEAAwAAAAAAAAEAAAAAAwABAAAAAAAAAQAAAAADAAEAAAAAAwABAAAAAAEAIQAAAAAAAB4AAAAABQAGAAAAAAIABgAAAAAAAAYAAAAAAgAGAAAAAAAABgAAAAAAAAYAAAAAAAAGAAAAAAIAHgAAAAABAAMAAAAAAgAeAAAAAAUAAQAAAAADAAEAAAAABAABAAAAAAAAAQAAAAACACEAAAAAAAAeAAAAAAEABgAAAAACAAUAAAAAAwAFAAAAAAMABQAAAAADAAUAAAAAAgAFAAAAAAIABgAAAAADAB4AAAAABAADAAAAAAAAHgAAAAAAAB4AAAAAAgAeAAAAAAQAHgAAAAAAAAEAAAAAAAACAAAAAAAAAgAAAAAEAAYAAAAAAgAFAAAAAAMABQAAAAABAAUAAAAAAQAGAAAAAAEABgAAAAADAAYAAAAAAQAeAAAAAAEAAwAAAAAAAB4AAAAABQAeAAAAAAIAHgAAAAABAB4AAAAAAwAeAAAAAAUAAgAAAAAAAAIAAAAACgAGAAAAAAEABQAAAAACAAUAAAAAAAAFAAAAAAAABQAAAAABAAUAAAAAAgAGAAAAAAEAHgAAAAAFAAMAAAAABgADAAAAAAQAAwAAAAADAAMAAAAABAADAAAAAAMAAwAAAAABAA==
|
||||
version: 7
|
||||
1,-3:
|
||||
ind: 1,-3
|
||||
@@ -730,6 +730,26 @@ entities:
|
||||
decals:
|
||||
168: -22,-69
|
||||
169: -22,-71
|
||||
- node:
|
||||
color: '#FFFFFFFF'
|
||||
id: CP14BrickTileStoneInnerNe
|
||||
decals:
|
||||
231: 3,-40
|
||||
- node:
|
||||
color: '#FFFFFFFF'
|
||||
id: CP14BrickTileStoneInnerNw
|
||||
decals:
|
||||
232: 5,-40
|
||||
- node:
|
||||
color: '#FFFFFFFF'
|
||||
id: CP14BrickTileStoneInnerSe
|
||||
decals:
|
||||
229: 3,-38
|
||||
- node:
|
||||
color: '#FFFFFFFF'
|
||||
id: CP14BrickTileStoneInnerSw
|
||||
decals:
|
||||
230: 5,-38
|
||||
- node:
|
||||
color: '#FFFFFFFF'
|
||||
id: CP14BrickTileStoneLineE
|
||||
@@ -738,6 +758,7 @@ entities:
|
||||
115: 21,-44
|
||||
128: 18,-44
|
||||
129: 18,-43
|
||||
228: 3,-39
|
||||
- node:
|
||||
color: '#FFFFFFFF'
|
||||
id: CP14BrickTileStoneLineN
|
||||
@@ -756,6 +777,7 @@ entities:
|
||||
203: -3,-20
|
||||
204: -10,-20
|
||||
205: -9,-20
|
||||
225: 4,-40
|
||||
- node:
|
||||
color: '#FFFFFFFF'
|
||||
id: CP14BrickTileStoneLineS
|
||||
@@ -764,6 +786,7 @@ entities:
|
||||
119: 19,-45
|
||||
120: 20,-42
|
||||
121: 19,-42
|
||||
226: 4,-38
|
||||
- node:
|
||||
color: '#FFFFFFFF'
|
||||
id: CP14BrickTileStoneLineW
|
||||
@@ -772,6 +795,7 @@ entities:
|
||||
117: 21,-43
|
||||
126: 18,-44
|
||||
127: 18,-43
|
||||
227: 5,-39
|
||||
- node:
|
||||
cleanable: True
|
||||
color: '#6EAAEBFF'
|
||||
@@ -892,6 +916,14 @@ entities:
|
||||
- type: Transform
|
||||
pos: 15.5,0.5
|
||||
parent: 1
|
||||
- proto: CP14AltarPrimordialGodLumera
|
||||
entities:
|
||||
- uid: 7335
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 4.5,-38.5
|
||||
parent: 1
|
||||
- proto: CP14BarrelWater
|
||||
entities:
|
||||
- uid: 10
|
||||
@@ -10860,12 +10892,6 @@ entities:
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 7.5,-38.5
|
||||
parent: 1
|
||||
- uid: 26
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 4.5,-39.5
|
||||
parent: 1
|
||||
- uid: 1861
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -30774,18 +30800,6 @@ entities:
|
||||
- type: Transform
|
||||
pos: 103.5,59.5
|
||||
parent: 1
|
||||
- uid: 7335
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 4.5,-38.5
|
||||
parent: 1
|
||||
- uid: 8737
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 5.5,-38.5
|
||||
parent: 1
|
||||
- uid: 8901
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -30923,18 +30937,6 @@ entities:
|
||||
- type: Transform
|
||||
pos: 109.5,58.5
|
||||
parent: 1
|
||||
- uid: 11070
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 5.5,-37.5
|
||||
parent: 1
|
||||
- uid: 11140
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 3.5,-37.5
|
||||
parent: 1
|
||||
- uid: 11141
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -30987,12 +30989,6 @@ entities:
|
||||
- type: Transform
|
||||
pos: 34.5,-2.5
|
||||
parent: 1
|
||||
- uid: 13907
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 6.5,-38.5
|
||||
parent: 1
|
||||
- uid: 14556
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -31034,12 +31030,6 @@ entities:
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 7.5,-39.5
|
||||
parent: 1
|
||||
- uid: 14623
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 5.5,-40.5
|
||||
parent: 1
|
||||
- uid: 14624
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -31052,24 +31042,12 @@ entities:
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 6.5,-40.5
|
||||
parent: 1
|
||||
- uid: 14626
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 6.5,-39.5
|
||||
parent: 1
|
||||
- uid: 14632
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 2.5,-41.5
|
||||
parent: 1
|
||||
- uid: 14633
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 4.5,-37.5
|
||||
parent: 1
|
||||
- uid: 14636
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -31100,12 +31078,6 @@ entities:
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: -2.5,-40.5
|
||||
parent: 1
|
||||
- uid: 14946
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 5.5,-39.5
|
||||
parent: 1
|
||||
- uid: 14963
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -38165,6 +38137,13 @@ entities:
|
||||
- type: Transform
|
||||
pos: 18.607292,16.662266
|
||||
parent: 1
|
||||
- proto: CP14BlueAmanita
|
||||
entities:
|
||||
- uid: 26
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 4.5032434,-39.154808
|
||||
parent: 1
|
||||
- proto: CP14BlueBottle
|
||||
entities:
|
||||
- uid: 7125
|
||||
@@ -38296,6 +38275,28 @@ entities:
|
||||
- type: Transform
|
||||
pos: -17.264824,5.8419228
|
||||
parent: 1
|
||||
- proto: CP14CandleBlue
|
||||
entities:
|
||||
- uid: 8737
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 5.330699,-38.98751
|
||||
parent: 1
|
||||
- uid: 9582
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 3.902204,-39.324844
|
||||
parent: 1
|
||||
- proto: CP14CandleBlueSmall
|
||||
entities:
|
||||
- uid: 9583
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 3.6772437,-38.26787
|
||||
parent: 1
|
||||
- proto: CP14CandleGreen
|
||||
entities:
|
||||
- uid: 7165
|
||||
@@ -40719,17 +40720,17 @@ entities:
|
||||
rot: 3.141592653589793 rad
|
||||
pos: -5.5,-34.5
|
||||
parent: 1
|
||||
- uid: 11655
|
||||
- uid: 11140
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 3.141592653589793 rad
|
||||
pos: 5.5,-34.5
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 3.5,-31.5
|
||||
parent: 1
|
||||
- uid: 11656
|
||||
- uid: 11311
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 3.141592653589793 rad
|
||||
pos: 4.5,-34.5
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 3.5,-32.5
|
||||
parent: 1
|
||||
- proto: CP14Dayflin
|
||||
entities:
|
||||
@@ -65910,12 +65911,6 @@ entities:
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -7.5,-43.5
|
||||
parent: 1
|
||||
- uid: 15366
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 6.5,-36.5
|
||||
parent: 1
|
||||
- uid: 15367
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -67628,11 +67623,6 @@ entities:
|
||||
- type: Transform
|
||||
pos: 12.5,-43.5
|
||||
parent: 1
|
||||
- uid: 15370
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 3.5,-36.5
|
||||
parent: 1
|
||||
- uid: 15371
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -68827,6 +68817,14 @@ entities:
|
||||
fixtures: {}
|
||||
- proto: CP14WallmountLampEmpty
|
||||
entities:
|
||||
- uid: 11070
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 3.5,-30.5
|
||||
parent: 1
|
||||
- type: Fixtures
|
||||
fixtures: {}
|
||||
- uid: 11758
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -68956,14 +68954,6 @@ entities:
|
||||
parent: 1
|
||||
- type: Fixtures
|
||||
fixtures: {}
|
||||
- uid: 11836
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 3.5,-32.5
|
||||
parent: 1
|
||||
- type: Fixtures
|
||||
fixtures: {}
|
||||
- uid: 11837
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -82689,6 +82679,16 @@ entities:
|
||||
- type: Transform
|
||||
pos: 2.5,21.5
|
||||
parent: 1
|
||||
- uid: 11393
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 4.5,-35.5
|
||||
parent: 1
|
||||
- uid: 11394
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 5.5,-35.5
|
||||
parent: 1
|
||||
- uid: 14358
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -83812,16 +83812,6 @@ entities:
|
||||
- type: Transform
|
||||
pos: -6.5,1.5
|
||||
parent: 1
|
||||
- uid: 14579
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,-32.5
|
||||
parent: 1
|
||||
- uid: 14581
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,-31.5
|
||||
parent: 1
|
||||
- uid: 14582
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -85516,15 +85506,17 @@ entities:
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 6.5,19.5
|
||||
parent: 1
|
||||
- uid: 14592
|
||||
- uid: 11312
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 4.5,-35.5
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 2.5,-32.5
|
||||
parent: 1
|
||||
- uid: 14608
|
||||
- uid: 11370
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 5.5,-35.5
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 2.5,-31.5
|
||||
parent: 1
|
||||
- uid: 14695
|
||||
components:
|
||||
|
||||
@@ -4,8 +4,8 @@ meta:
|
||||
engineVersion: 260.2.0
|
||||
forkId: ""
|
||||
forkVersion: ""
|
||||
time: 06/07/2025 21:12:48
|
||||
entityCount: 15201
|
||||
time: 06/15/2025 11:14:05
|
||||
entityCount: 15204
|
||||
maps:
|
||||
- 2
|
||||
grids:
|
||||
@@ -96,7 +96,7 @@ entities:
|
||||
version: 7
|
||||
0,-1:
|
||||
ind: 0,-1
|
||||
tiles: IAAAAAAEACAAAAAABAAgAAAAAAEAIAAAAAAEACAAAAAABAAgAAAAAAEAIAAAAAAEACAAAAAAAwACAAAAAAoAAgAAAAAEAAIAAAAAAAACAAAAAAkAAgAAAAACAAIAAAAABwACAAAAAAcAAgAAAAALACAAAAAAAwAgAAAAAAEAIAAAAAAEACAAAAAAAwAgAAAAAAMAAgAAAAAGACAAAAAAAgAgAAAAAAEAIAAAAAAAACAAAAAAAwACAAAAAAsAAgAAAAAOAAIAAAAAAwACAAAAAAsAAgAAAAAJACAAAAAAAQAgAAAAAAEAIAAAAAADACAAAAAABAAgAAAAAAMAIAAAAAADAAIAAAAADQACAAAAAAwAIAAAAAABAAIAAAAADgACAAAAAA8AAgAAAAAGACAAAAAAAAAgAAAAAAQAIAAAAAADACAAAAAABAAgAAAAAAMAAgAAAAAMAAIAAAAAAgACAAAAAAkAAgAAAAAAAAIAAAAABAACAAAAAAkAIAAAAAADACAAAAAAAgACAAAAAAkAAgAAAAACAAIAAAAADwAgAAAAAAQAIAAAAAADAAIAAAAABAACAAAAAA8AAgAAAAAMAAIAAAAAAQACAAAAAA8AAgAAAAADAAIAAAAAAgACAAAAAAsAAgAAAAAJAAIAAAAADgACAAAAAAgAAgAAAAAEAAIAAAAABAACAAAAAAgAAgAAAAACAB0AAAAAAAAeAAAAAAIAHgAAAAACAB4AAAAAAwAdAAAAAAMAHQAAAAADAB4AAAAAAwAeAAAAAAQAHgAAAAACAB4AAAAAAQAeAAAAAAIAHQAAAAACAB0AAAAAAAAdAAAAAAEAHQAAAAAEAB4AAAAAAAAeAAAAAAQAHQAAAAABAAIAAAAAAgAgAAAAAAMAAgAAAAALAAIAAAAACAACAAAAAA0AAgAAAAANAAIAAAAACwACAAAAAAMAAgAAAAAKAAIAAAAABwAgAAAAAAEAIAAAAAACACAAAAAAAgACAAAAAAoAAgAAAAACAAIAAAAADAACAAAAAAAAAgAAAAALACAAAAAAAQACAAAAAA4AAgAAAAAGACAAAAAAAQAgAAAAAAAAIAAAAAADACAAAAAAAQACAAAAAAgAAgAAAAABAAIAAAAAAQACAAAAAAsAAgAAAAAFAAIAAAAACQACAAAAAAQAIAAAAAADAAIAAAAACgAcAAAAAAUAHAAAAAAAABwAAAAAAgAcAAAAAAUAHAAAAAAFAB0AAAAABAAdAAAAAAEAHQAAAAACAB0AAAAAAgAdAAAAAAQAHQAAAAAFAB0AAAAABAAdAAAAAAMAHQAAAAADACAAAAAAAwAgAAAAAAIAHAAAAAACABwAAAAAAQAcAAAAAAMAHAAAAAABAB0AAAAAAgAdAAAAAAQAHQAAAAADAB4AAAAABAAFAAAAAAAABQAAAAABAAUAAAAAAAAFAAAAAAMABQAAAAADAB0AAAAABQAgAAAAAAIAIAAAAAAEAB0AAAAAAQAdAAAAAAAAHAAAAAABABwAAAAAAwAdAAAAAAEAHQAAAAADAB4AAAAABAAeAAAAAAUABQAAAAABAAUAAAAAAQAFAAAAAAMABQAAAAAAAAUAAAAAAAAHAAAAAAIABQAAAAAAAAUAAAAAAAAeAAAAAAEAHQAAAAACABwAAAAAAgAcAAAAAAMABQAAAAADAAUAAAAAAwAHAAAAAAMABwAAAAACAAcAAAAAAAAHAAAAAAAABQAAAAACAAYAAAAAAwAFAAAAAAEABQAAAAACAAUAAAAAAQAFAAAAAAEAHgAAAAABAB0AAAAAAgAdAAAAAAAAHAAAAAADAAUAAAAAAwAFAAAAAAMABwAAAAADAAcAAAAAAAAHAAAAAAMABwAAAAACAAUAAAAAAQAGAAAAAAAABQAAAAABAAUAAAAAAgAHAAAAAAAABwAAAAACAA4AAAAAAAAOAAAAAAQAHgAAAAABAB0AAAAABQAFAAAAAAEABQAAAAACAAcAAAAAAAAHAAAAAAMABwAAAAACAAcAAAAAAAAFAAAAAAMABQAAAAACAAUAAAAAAgAFAAAAAAAABwAAAAABAAcAAAAAAAAOAAAAAAQADgAAAAAEAA4AAAAAAAAdAAAAAAQABQAAAAADAAUAAAAAAwAFAAAAAAEABQAAAAADAAUAAAAAAQAFAAAAAAEABQAAAAACAAUAAAAAAgAFAAAAAAMABQAAAAAAAAcAAAAAAwAHAAAAAAAAIQAAAAAEAA4AAAAAAgAOAAAAAAMAHQAAAAAAAAUAAAAAAAAFAAAAAAIABQAAAAADAAYAAAAAAQAGAAAAAAMABgAAAAADAAUAAAAAAgAFAAAAAAIABQAAAAACAAUAAAAAAwAFAAAAAAMABQAAAAACAA==
|
||||
tiles: IAAAAAAEACAAAAAABAAgAAAAAAEAIAAAAAAEACAAAAAABAAgAAAAAAEAIAAAAAAEACAAAAAAAwACAAAAAAoAAgAAAAAEAAIAAAAAAAACAAAAAAkAAgAAAAACAAIAAAAABwACAAAAAAcAAgAAAAALACAAAAAAAwAgAAAAAAEAIAAAAAAEACAAAAAAAwAgAAAAAAMAAgAAAAAGACAAAAAAAgAgAAAAAAEAIAAAAAAAACAAAAAAAwACAAAAAAsAAgAAAAAOAAIAAAAAAwACAAAAAAsAAgAAAAAJACAAAAAAAQAgAAAAAAEAIAAAAAADACAAAAAABAAgAAAAAAMAIAAAAAADAAIAAAAADQACAAAAAAwAIAAAAAABAAIAAAAADgACAAAAAA8AAgAAAAAGACAAAAAAAAAgAAAAAAQAIAAAAAADACAAAAAABAAgAAAAAAMAAgAAAAAMAAIAAAAAAgACAAAAAAkAAgAAAAAAAAIAAAAABAACAAAAAAkAIAAAAAADACAAAAAAAgACAAAAAAkAAgAAAAACAAIAAAAADwAgAAAAAAQAIAAAAAADAAIAAAAABAACAAAAAA8AAgAAAAAMAAIAAAAAAQACAAAAAA8AAgAAAAADAAIAAAAAAgACAAAAAAsAAgAAAAAJAAIAAAAADgACAAAAAAgAAgAAAAAEAAIAAAAABAACAAAAAAgAAgAAAAACAB0AAAAAAAAeAAAAAAIAHgAAAAACAB4AAAAAAwAdAAAAAAMAHQAAAAADAB4AAAAAAwAeAAAAAAQAHgAAAAACAB4AAAAAAQAeAAAAAAIAHQAAAAACAB0AAAAAAAAdAAAAAAEAHQAAAAAEAB4AAAAAAAAeAAAAAAQAHQAAAAABAAIAAAAAAgAgAAAAAAMAAgAAAAALAAIAAAAACAACAAAAAA0AAgAAAAANAAIAAAAACwACAAAAAAMAAgAAAAAKAAIAAAAABwAgAAAAAAEAIAAAAAACACAAAAAAAgACAAAAAAoAAgAAAAACAAIAAAAADAACAAAAAAAAAgAAAAALACAAAAAAAQACAAAAAA4AAgAAAAAGACAAAAAAAQAgAAAAAAAAIAAAAAADACAAAAAAAQACAAAAAAgAAgAAAAABAAIAAAAAAQACAAAAAAsAAgAAAAAFAAIAAAAACQACAAAAAAQAIAAAAAADAAIAAAAACgAcAAAAAAUAHAAAAAAAABwAAAAAAgAcAAAAAAUAHAAAAAAFAB0AAAAABAAdAAAAAAEAHQAAAAACAB0AAAAAAgAdAAAAAAQAHQAAAAAFAB0AAAAABAAdAAAAAAMAHQAAAAADACAAAAAAAwAgAAAAAAIAEAAAAAAAABAAAAAAAAAQAAAAAAAAHAAAAAABAB0AAAAAAgAdAAAAAAQAHQAAAAADAB4AAAAABAAFAAAAAAAABQAAAAABAAUAAAAAAAAFAAAAAAMABQAAAAADAB0AAAAABQAgAAAAAAIAIAAAAAAEABAAAAAAAAARAAAAAAAAEAAAAAAAABwAAAAAAwAdAAAAAAEAHQAAAAADAB4AAAAABAAeAAAAAAUABQAAAAABAAUAAAAAAQAFAAAAAAMABQAAAAAAAAUAAAAAAAAHAAAAAAIABQAAAAAAAAUAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAcAAAAAAMABQAAAAADAAUAAAAAAwAHAAAAAAMABwAAAAACAAcAAAAAAAAHAAAAAAAABQAAAAACAAYAAAAAAwAFAAAAAAEABQAAAAACAAUAAAAAAQAFAAAAAAEAHgAAAAABAB0AAAAAAgAdAAAAAAAAHAAAAAADAAUAAAAAAwAFAAAAAAMABwAAAAADAAcAAAAAAAAHAAAAAAMABwAAAAACAAUAAAAAAQAGAAAAAAAABQAAAAABAAUAAAAAAgAHAAAAAAAABwAAAAACAA4AAAAAAAAOAAAAAAQAHgAAAAABAB0AAAAABQAFAAAAAAEABQAAAAACAAcAAAAAAAAHAAAAAAMABwAAAAACAAcAAAAAAAAFAAAAAAMABQAAAAACAAUAAAAAAgAFAAAAAAAABwAAAAABAAcAAAAAAAAOAAAAAAQADgAAAAAEAA4AAAAAAAAdAAAAAAQABQAAAAADAAUAAAAAAwAFAAAAAAEABQAAAAADAAUAAAAAAQAFAAAAAAEABQAAAAACAAUAAAAAAgAFAAAAAAMABQAAAAAAAAcAAAAAAwAHAAAAAAAAIQAAAAAEAA4AAAAAAgAOAAAAAAMAHQAAAAAAAAUAAAAAAAAFAAAAAAIABQAAAAADAAYAAAAAAQAGAAAAAAMABgAAAAADAAUAAAAAAgAFAAAAAAIABQAAAAACAAUAAAAAAwAFAAAAAAMABQAAAAACAA==
|
||||
version: 7
|
||||
0,0:
|
||||
ind: 0,0
|
||||
@@ -500,11 +500,24 @@ entities:
|
||||
id: CP14BrickTileStoneInnerNe
|
||||
decals:
|
||||
79: 8,-31
|
||||
142: 0,-7
|
||||
143: 0,-7
|
||||
- node:
|
||||
color: '#FFFFFFFF'
|
||||
id: CP14BrickTileStoneInnerNw
|
||||
decals:
|
||||
144: 2,-7
|
||||
- node:
|
||||
color: '#FFFFFFFF'
|
||||
id: CP14BrickTileStoneInnerSe
|
||||
decals:
|
||||
78: 8,-28
|
||||
140: 0,-5
|
||||
- node:
|
||||
color: '#FFFFFFFF'
|
||||
id: CP14BrickTileStoneInnerSw
|
||||
decals:
|
||||
141: 2,-5
|
||||
- node:
|
||||
color: '#DE3A3A96'
|
||||
id: CP14BrickTileStoneLineE
|
||||
@@ -519,6 +532,7 @@ entities:
|
||||
51: 24,-24
|
||||
74: 8,-30
|
||||
75: 8,-29
|
||||
138: 0,-6
|
||||
- node:
|
||||
color: '#DE3A3A96'
|
||||
id: CP14BrickTileStoneLineN
|
||||
@@ -532,6 +546,7 @@ entities:
|
||||
47: 22,-23
|
||||
48: 23,-23
|
||||
77: 9,-31
|
||||
139: 1,-7
|
||||
- node:
|
||||
color: '#DE3A3A96'
|
||||
id: CP14BrickTileStoneLineS
|
||||
@@ -545,6 +560,7 @@ entities:
|
||||
42: 22,-27
|
||||
43: 23,-27
|
||||
76: 9,-28
|
||||
136: 1,-5
|
||||
- node:
|
||||
color: '#DE3A3A96'
|
||||
id: CP14BrickTileStoneLineW
|
||||
@@ -557,6 +573,7 @@ entities:
|
||||
44: 21,-26
|
||||
45: 21,-25
|
||||
46: 21,-24
|
||||
137: 2,-6
|
||||
- node:
|
||||
color: '#FFFFFFFF'
|
||||
id: CP14FloraGrass10
|
||||
@@ -753,6 +770,13 @@ entities:
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 5.5,0.5
|
||||
parent: 2
|
||||
- proto: CP14AltarPrimordialGodLumera
|
||||
entities:
|
||||
- uid: 12327
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,-5.5
|
||||
parent: 2
|
||||
- proto: CP14BarrelBloodGoblin
|
||||
entities:
|
||||
- uid: 8065
|
||||
@@ -30239,6 +30263,25 @@ entities:
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 48.210453,-20.351133
|
||||
parent: 2
|
||||
- proto: CP14CandleBlue
|
||||
entities:
|
||||
- uid: 12328
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 0.7710935,-5.9935446
|
||||
parent: 2
|
||||
- uid: 15201
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.2783234,-5.80239
|
||||
parent: 2
|
||||
- proto: CP14CandleBlueSmall
|
||||
entities:
|
||||
- uid: 15202
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5022119,-4.666708
|
||||
parent: 2
|
||||
- proto: CP14CarpetBlue
|
||||
entities:
|
||||
- uid: 1836
|
||||
@@ -33924,6 +33967,13 @@ entities:
|
||||
- type: Transform
|
||||
pos: -25.5,-33.5
|
||||
parent: 2
|
||||
- proto: CP14ClothingBlueCollarDress
|
||||
entities:
|
||||
- uid: 15203
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5201155,-6.2672186
|
||||
parent: 2
|
||||
- proto: CP14ClothingSatchelLeather
|
||||
entities:
|
||||
- uid: 1484
|
||||
@@ -34254,7 +34304,7 @@ entities:
|
||||
pos: 14.5,-24.5
|
||||
parent: 2
|
||||
- type: Door
|
||||
secondsUntilStateChange: -8969.771
|
||||
secondsUntilStateChange: -9077.496
|
||||
state: Closing
|
||||
- uid: 1792
|
||||
components:
|
||||
@@ -52183,12 +52233,6 @@ entities:
|
||||
- type: Transform
|
||||
pos: 24.5,-42.5
|
||||
parent: 2
|
||||
- uid: 12328
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 3.5,-6.5
|
||||
parent: 2
|
||||
- uid: 12329
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -52292,12 +52336,6 @@ entities:
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: -0.5,-10.5
|
||||
parent: 2
|
||||
- uid: 12327
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 1.5,-4.5
|
||||
parent: 2
|
||||
- uid: 12334
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -77711,6 +77749,13 @@ entities:
|
||||
rot: 3.141592653589793 rad
|
||||
pos: 44.5,-28.5
|
||||
parent: 2
|
||||
- proto: CP14TableMarble
|
||||
entities:
|
||||
- uid: 15204
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,-6.5
|
||||
parent: 2
|
||||
- proto: CP14TableWooden
|
||||
entities:
|
||||
- uid: 1459
|
||||
@@ -79091,13 +79136,6 @@ entities:
|
||||
parent: 2
|
||||
- type: Fixtures
|
||||
fixtures: {}
|
||||
- uid: 15201
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 4.5,-5.5
|
||||
parent: 2
|
||||
- type: Fixtures
|
||||
fixtures: {}
|
||||
- proto: CP14WallmountFlagBank
|
||||
entities:
|
||||
- uid: 7830
|
||||
|
||||
@@ -88,6 +88,7 @@
|
||||
#- type: WirelessNetworkConnection
|
||||
# range: 500
|
||||
#- type: StationLimitedNetwork
|
||||
- type: CP14SkillScanner
|
||||
- type: Thieving
|
||||
stripTimeReduction: 9999
|
||||
stealthy: true
|
||||
|
||||
@@ -48,3 +48,11 @@
|
||||
name: alerts-hunger-name
|
||||
description: alerts-hunger-desc
|
||||
|
||||
- type: alert
|
||||
id: CP14DivineOffer
|
||||
icons:
|
||||
- sprite: /Textures/_CP14/Interface/Alerts/divine_offer.rsi
|
||||
state: offer
|
||||
name: cp14-alert-offer
|
||||
description: cp14-alert-offer-desc
|
||||
clickEvent: !type:CP14BreakDivineOfferEvent
|
||||
@@ -47,7 +47,6 @@
|
||||
- id: CP14StampDenied
|
||||
- id: CP14StampApproved
|
||||
- id: CP14ManaOperationGlove
|
||||
- id: AppraisalTool
|
||||
- id: CP14PaperFolderRed
|
||||
amount: 2
|
||||
- id: CP14PaperFolderBlue
|
||||
|
||||
@@ -16,3 +16,8 @@
|
||||
- Toxin
|
||||
- Genetic
|
||||
- CP14Magic
|
||||
|
||||
- type: damageContainer
|
||||
id: CP14Spectral
|
||||
supportedGroups:
|
||||
- CP14Magic
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user