forked from SpaceStation14-Shenanigans/Monolith
Compare commits
141 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aa8c6622b8 | |||
| bcc3402ef7 | |||
| a8a3cec8e4 | |||
| e19e64b903 | |||
| 5b6542720c | |||
| db7066605a | |||
| e14c8c0a8f | |||
| c061eaf610 | |||
| e56c2c5272 | |||
| 238d77ead3 | |||
| dea4d76981 | |||
| 82b46194d1 | |||
| e6835a4934 | |||
| 3d6597526b | |||
| 8894d4e5ff | |||
| eef28959e2 | |||
| 4ea83d389a | |||
| 02f74c26e9 | |||
| c0ea5adf5d | |||
| 6daf9f02e6 | |||
| afabe747f2 | |||
| 699232f653 | |||
| 262aa8cd4b | |||
| bcb9440046 | |||
| 93bd8b8356 | |||
| d14dd88149 | |||
| f520ddf911 | |||
| c2ea1eaf94 | |||
| fc105b61fc | |||
| 271c4e7efc | |||
| a4138f4b11 | |||
| ff74cf3ae1 | |||
| 663425a050 | |||
| b4e4a284bc | |||
| 3a8ac92ef8 | |||
| d3d3ab531e | |||
| 71cf5f42c7 | |||
| fce9e95910 | |||
| ee337596d6 | |||
| a2b3ddecdf | |||
| 0939533dc1 | |||
| 42f6f53be9 | |||
| 2651c00cfd | |||
| a462d09fb9 | |||
| ce617c185e | |||
| 131c5e79a5 | |||
| 86c9a843b1 | |||
| dd910f1550 | |||
| cd8d59c095 | |||
| 20bc7af2a4 | |||
| 65ea89b673 | |||
| 44445f3d2a | |||
| 648cc99aff | |||
| e8c2b72aa0 | |||
| 7d85dbca00 | |||
| 85e0cb1c76 | |||
| 3c32d2f6f5 | |||
| 9d8d0b9016 | |||
| 02e72a4c1d | |||
| 5fac554802 | |||
| bc62bf3700 | |||
| accb1404b0 | |||
| 326440aa22 | |||
| b4fe4ab5e7 | |||
| 8ff52fcd7b | |||
| e8a620e044 | |||
| 9ea80d6405 | |||
| abec847ca3 | |||
| 36214087e9 | |||
| 2b4f4f2ba0 | |||
| 258bc12f16 | |||
| d73cf7aeaf | |||
| b1e200408d | |||
| 95227750d9 | |||
| 34f71b59b9 | |||
| 547420d4bc | |||
| 510434fb65 | |||
| 862ce8352c | |||
| 552ab5718a | |||
| 2bacec206b | |||
| bd8ae0ec9b | |||
| 6ba17c6e1b | |||
| 50d7de7818 | |||
| 02348e780e | |||
| 80cc460d69 | |||
| e95a87a1d8 | |||
| 78ecd13c0a | |||
| 9eb4c8333c | |||
| 882b1acae7 | |||
| df39f7bd6d | |||
| c68d329dd2 | |||
| 5a2341407b | |||
| b4b49016d9 | |||
| 53a40c6c3c | |||
| fbf93d50be | |||
| 68144857e8 | |||
| 820a70c695 | |||
| bff7436490 | |||
| 2b76b0a55a | |||
| fa61e959fb | |||
| b427f087b0 | |||
| 7a8b90339f | |||
| cecc52bff9 | |||
| 378592a0ba | |||
| 89dff2ec03 | |||
| 4faad89b0c | |||
| 8f8b94862a | |||
| 7c29b33d27 | |||
| 8180e5d436 | |||
| e081dd59c6 | |||
| 295ef88a95 | |||
| 39292553b3 | |||
| 2652423c4d | |||
| fb836a0ee7 | |||
| 7a63aba489 | |||
| 7ec10d578c | |||
| 91f4eb7b51 | |||
| e552e2498f | |||
| ef34f255bf | |||
| 0f3390aba8 | |||
| 25033ae9c1 | |||
| d32fd9dd0a | |||
| 728c10974e | |||
| 50c5891b4e | |||
| 51818f6dc3 | |||
| dcaefa16d7 | |||
| 15936634b1 | |||
| 574bb25522 | |||
| 1125715a3f | |||
| 9e3a270988 | |||
| bf1a02bfcb | |||
| 57c59e3684 | |||
| 0e31d3885f | |||
| 27b05a3b75 | |||
| f99e36e101 | |||
| 5a17e7781f | |||
| 98f8d334a1 | |||
| c9bba3367d | |||
| 4ac8f937fb | |||
| 9648f54fc3 | |||
| 33e0bf8293 |
@@ -10,18 +10,18 @@ jobs:
|
||||
if: ${{github.head_ref == 'master' || github.head_ref == 'main' || github.head_ref == 'develop'}}
|
||||
|
||||
steps:
|
||||
# - uses: superbrothers/close-pull-request@v3
|
||||
# with:
|
||||
# comment: "Thank you for contributing to the Space Station 14 repository. Unfortunately, it looks like you submitted your pull request from the master branch. We suggest you follow [our git usage documentation](https://docs.spacestation14.com/en/general-development/setup/git-for-the-ss14-developer.html) \n\n You can move your current work from the master branch to another branch by doing `git branch <branch_name` and resetting the master branch."
|
||||
- uses: superbrothers/close-pull-request@v3
|
||||
with:
|
||||
comment: "Thank you for contributing to the Monolith repository. Unfortunately, it looks like you submitted your pull request from the master branch. We suggest you follow [our git usage documentation](https://docs.spacestation14.com/en/general-development/setup/git-for-the-ss14-developer.html) \n\n You can move your current work from the master branch to another branch by doing `git branch <branch_name` and resetting the master branch."
|
||||
|
||||
# If you prefer to just comment on the pr and not close it, uncomment the bellow and comment the above
|
||||
|
||||
- uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.createComment({
|
||||
issue_number: ${{ github.event.number }},
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: "Thank you for contributing to the Space Station 14 repository. Unfortunately, it looks like you submitted your pull request from the master branch. We suggest you follow [our git usage documentation](https://docs.spacestation14.com/en/general-development/setup/git-for-the-ss14-developer.html) \n\n You can move your current work from the master branch to another branch by doing `git branch <branch_name>` and resetting the master branch. \n\n This pr won't be automatically closed. However, a maintainer may close it for this reason."
|
||||
})
|
||||
#- uses: actions/github-script@v7
|
||||
# with:
|
||||
# script: |
|
||||
# github.rest.issues.createComment({
|
||||
# issue_number: ${{ github.event.number }},
|
||||
# owner: context.repo.owner,
|
||||
# repo: context.repo.repo,
|
||||
# body: "Thank you for contributing to the Monolith repository. Unfortunately, it looks like you submitted your pull request from the master branch. We suggest you follow [our git usage documentation](https://docs.spacestation14.com/en/general-development/setup/git-for-the-ss14-developer.html) \n\n You can move your current work from the master branch to another branch by doing `git branch <branch_name>` and resetting the master branch. \n\n This pr won't be automatically closed. However, a maintainer may close it for this reason."
|
||||
# })
|
||||
|
||||
@@ -2196,7 +2196,7 @@ namespace Content.Client.Lobby.UI
|
||||
return;
|
||||
|
||||
var companies = _prototypeManager.EnumeratePrototypes<CompanyPrototype>()
|
||||
.Where(c => !c.Disabled && _companyManager.IsAllowed(c))
|
||||
.Where(c => !c.Disabled && _companyManager.IsAllowed(c.ID))
|
||||
.ToList();
|
||||
companies.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.Ordinal));
|
||||
|
||||
|
||||
@@ -138,6 +138,293 @@ public partial class BaseShuttleControl : MapGridControl
|
||||
}
|
||||
// End Frontier Corvax
|
||||
|
||||
// Mono
|
||||
protected void DrawAzimuthScale(DrawingHandleScreen handle, Angle rotation)
|
||||
{
|
||||
const int azimuthMinorTickStepDegrees = 10;
|
||||
const int azimuthMajorTickInterval = 3;
|
||||
const int azimuthCardinalTickInterval = 9;
|
||||
const float edgeInset = 10f;
|
||||
const float tickInset = 4f;
|
||||
const float minorTickLength = 5f;
|
||||
const float majorTickLength = 9f;
|
||||
const float cardinalTickLength = 12f;
|
||||
const float labelPadding = 3f;
|
||||
const float labelOffset = tickInset + cardinalTickLength + labelPadding;
|
||||
const float regularLabelScale = 0.62f;
|
||||
const float cardinalLabelScale = 0.72f;
|
||||
|
||||
var origin = MidPointVector;
|
||||
var viewportSize = new Vector2(PixelWidth, PixelHeight);
|
||||
|
||||
var subtleGray = Color.FromHex("#676767");
|
||||
var northAccent = Color.FromHex("#7F7442");
|
||||
var eastAccent = Color.FromHex("#456273");
|
||||
var baseTickColor = subtleGray.WithAlpha(0.34f);
|
||||
var majorTickColor = subtleGray.WithAlpha(0.5f);
|
||||
var cardinalTickColor = subtleGray.WithAlpha(0.68f);
|
||||
var regularLabelColor = subtleGray.WithAlpha(0.76f);
|
||||
var cardinalLabelColor = subtleGray.WithAlpha(0.9f);
|
||||
var labelShadowColor = Color.Black.WithAlpha(0.36f);
|
||||
|
||||
for (var step = 0; step < 360 / azimuthMinorTickStepDegrees; step++)
|
||||
{
|
||||
var degrees = step * azimuthMinorTickStepDegrees;
|
||||
var direction = GetAzimuthDirection(rotation, degrees);
|
||||
var isCardinal = step % azimuthCardinalTickInterval == 0;
|
||||
var isMajor = step % azimuthMajorTickInterval == 0;
|
||||
var isNorth = degrees == 0;
|
||||
var isEast = degrees == 90;
|
||||
var tickLength = isCardinal
|
||||
? cardinalTickLength
|
||||
: isMajor
|
||||
? majorTickLength
|
||||
: minorTickLength;
|
||||
|
||||
if (!TryGetViewportEdgePoint(origin, direction, viewportSize, edgeInset, out var edgePoint, out var inwardNormal))
|
||||
continue;
|
||||
|
||||
var outer = edgePoint + inwardNormal * tickInset;
|
||||
var inner = outer + inwardNormal * tickLength;
|
||||
var tickColor = isNorth
|
||||
? northAccent.WithAlpha(0.58f)
|
||||
: isEast
|
||||
? eastAccent.WithAlpha(0.58f)
|
||||
: isCardinal
|
||||
? cardinalTickColor
|
||||
: isMajor
|
||||
? majorTickColor
|
||||
: baseTickColor;
|
||||
handle.DrawLine(outer, inner, tickColor);
|
||||
if (isNorth)
|
||||
{
|
||||
var sideOffset = new Vector2(-inwardNormal.Y, inwardNormal.X) * 0.35f;
|
||||
handle.DrawLine(outer + sideOffset, inner + sideOffset, tickColor.WithAlpha(0.46f));
|
||||
}
|
||||
|
||||
if (!isMajor)
|
||||
continue;
|
||||
|
||||
var label = degrees.ToString();
|
||||
var labelScale = isCardinal ? cardinalLabelScale : regularLabelScale;
|
||||
var labelColor = isEast
|
||||
? eastAccent.WithAlpha(0.76f)
|
||||
: isCardinal
|
||||
? cardinalLabelColor
|
||||
: regularLabelColor;
|
||||
var labelSize = handle.GetDimensions(Font, label, labelScale);
|
||||
var labelPosition = GetEdgeLabelPosition(edgePoint, inwardNormal, labelSize, viewportSize, labelOffset);
|
||||
handle.DrawString(Font, labelPosition + new Vector2(1f, 1f), label, labelScale, labelShadowColor);
|
||||
handle.DrawString(Font, labelPosition, label, labelScale, labelColor);
|
||||
}
|
||||
}
|
||||
|
||||
protected void DrawAzimuthRing(DrawingHandleScreen handle, Angle rotation)
|
||||
{
|
||||
const int azimuthMinorTickStepDegrees = 10;
|
||||
const int azimuthMajorTickInterval = 3;
|
||||
const int azimuthCardinalTickInterval = 9;
|
||||
const float ringInset = 16f;
|
||||
const float minorTickLength = 5f;
|
||||
const float majorTickLength = 9f;
|
||||
const float cardinalTickLength = 12f;
|
||||
const float labelPadding = 5f;
|
||||
const float regularLabelScale = 0.62f;
|
||||
const float cardinalLabelScale = 0.72f;
|
||||
|
||||
var origin = MidPointVector;
|
||||
var radius = MathF.Max(8f, SizeFull * 0.5f - ringInset);
|
||||
|
||||
var subtleGray = Color.FromHex("#676767");
|
||||
var northAccent = Color.FromHex("#7F7442");
|
||||
var eastAccent = Color.FromHex("#456273");
|
||||
var baseTickColor = subtleGray.WithAlpha(0.34f);
|
||||
var majorTickColor = subtleGray.WithAlpha(0.5f);
|
||||
var cardinalTickColor = subtleGray.WithAlpha(0.68f);
|
||||
var regularLabelColor = subtleGray.WithAlpha(0.76f);
|
||||
var cardinalLabelColor = subtleGray.WithAlpha(0.9f);
|
||||
var labelShadowColor = Color.Black.WithAlpha(0.36f);
|
||||
|
||||
handle.DrawCircle(origin, radius, subtleGray.WithAlpha(0.12f), false);
|
||||
|
||||
for (var step = 0; step < 360 / azimuthMinorTickStepDegrees; step++)
|
||||
{
|
||||
var degrees = step * azimuthMinorTickStepDegrees;
|
||||
var direction = GetAzimuthDirection(rotation, degrees);
|
||||
var isCardinal = step % azimuthCardinalTickInterval == 0;
|
||||
var isMajor = step % azimuthMajorTickInterval == 0;
|
||||
var isNorth = degrees == 0;
|
||||
var isEast = degrees == 90;
|
||||
var tickLength = isCardinal
|
||||
? cardinalTickLength
|
||||
: isMajor
|
||||
? majorTickLength
|
||||
: minorTickLength;
|
||||
|
||||
var outer = origin + direction * radius;
|
||||
var inner = origin + direction * (radius - tickLength);
|
||||
var tickColor = isNorth
|
||||
? northAccent.WithAlpha(0.58f)
|
||||
: isEast
|
||||
? eastAccent.WithAlpha(0.58f)
|
||||
: isCardinal
|
||||
? cardinalTickColor
|
||||
: isMajor
|
||||
? majorTickColor
|
||||
: baseTickColor;
|
||||
handle.DrawLine(outer, inner, tickColor);
|
||||
if (isNorth)
|
||||
{
|
||||
var sideOffset = new Vector2(-direction.Y, direction.X) * 0.35f;
|
||||
handle.DrawLine(outer + sideOffset, inner + sideOffset, tickColor.WithAlpha(0.46f));
|
||||
}
|
||||
|
||||
if (!isMajor)
|
||||
continue;
|
||||
|
||||
var label = degrees.ToString();
|
||||
var labelScale = isCardinal ? cardinalLabelScale : regularLabelScale;
|
||||
var labelColor = isEast
|
||||
? eastAccent.WithAlpha(0.76f)
|
||||
: isCardinal
|
||||
? cardinalLabelColor
|
||||
: regularLabelColor;
|
||||
var labelSize = handle.GetDimensions(Font, label, labelScale);
|
||||
var labelPosition = origin + direction * (radius - tickLength - labelPadding) - labelSize * 0.5f;
|
||||
handle.DrawString(Font, labelPosition + new Vector2(1f, 1f), label, labelScale, labelShadowColor);
|
||||
handle.DrawString(Font, labelPosition, label, labelScale, labelColor);
|
||||
}
|
||||
}
|
||||
|
||||
protected void DrawCompassOverlay(DrawingHandleScreen handle, Angle heading)
|
||||
{
|
||||
var compassCenter = new Vector2(44f, 44f);
|
||||
const float compassRadius = 24f;
|
||||
var ringColor = Color.White.WithAlpha(0.08f);
|
||||
var northColor = Color.FromHex("#776C43");
|
||||
var eastColor = Color.FromHex("#4C6572");
|
||||
handle.DrawCircle(compassCenter, compassRadius, ringColor, false);
|
||||
handle.DrawCircle(compassCenter, 2.5f, ringColor.WithAlpha(0.48f), true);
|
||||
|
||||
DrawCompassNeedle(handle, compassCenter, compassRadius, GetAzimuthDirection(heading, 0f), "N", northColor);
|
||||
DrawCompassNeedle(handle, compassCenter, compassRadius * 0.82f, GetAzimuthDirection(heading, 90f), "E", eastColor);
|
||||
}
|
||||
|
||||
private void DrawCompassNeedle(
|
||||
DrawingHandleScreen handle,
|
||||
Vector2 compassCenter,
|
||||
float radius,
|
||||
Vector2 direction,
|
||||
string label,
|
||||
Color color)
|
||||
{
|
||||
var tip = compassCenter + direction * radius;
|
||||
var tail = compassCenter - direction * (radius * 0.35f);
|
||||
DrawArrowLine(handle, tail, tip, color.WithAlpha(0.58f), 6f);
|
||||
|
||||
var labelSize = handle.GetDimensions(Font, label, 0.9f);
|
||||
var labelPosition = tip + direction * 6f - new Vector2(labelSize.X * 0.5f, labelSize.Y * 0.5f);
|
||||
handle.DrawString(Font, labelPosition, label, 0.9f, color.WithAlpha(0.7f));
|
||||
}
|
||||
|
||||
private static void DrawArrowLine(
|
||||
DrawingHandleScreen handle,
|
||||
Vector2 start,
|
||||
Vector2 end,
|
||||
Color color,
|
||||
float headLength)
|
||||
{
|
||||
var direction = end - start;
|
||||
if (direction.LengthSquared() <= 0.001f)
|
||||
return;
|
||||
|
||||
direction = Vector2.Normalize(direction);
|
||||
var left = new Vector2(-direction.Y, direction.X);
|
||||
handle.DrawLine(start, end, color);
|
||||
handle.DrawLine(end, end - direction * headLength + left * (headLength * 0.45f), color);
|
||||
handle.DrawLine(end, end - direction * headLength - left * (headLength * 0.45f), color);
|
||||
}
|
||||
|
||||
private static bool TryGetViewportEdgePoint(
|
||||
Vector2 origin,
|
||||
Vector2 direction,
|
||||
Vector2 viewportSize,
|
||||
float inset,
|
||||
out Vector2 edgePoint,
|
||||
out Vector2 inwardNormal)
|
||||
{
|
||||
edgePoint = default;
|
||||
inwardNormal = default;
|
||||
|
||||
if (direction.LengthSquared() <= 0.001f)
|
||||
return false;
|
||||
|
||||
direction = Vector2.Normalize(direction);
|
||||
var min = new Vector2(inset, inset);
|
||||
var max = viewportSize - min;
|
||||
if (max.X <= min.X || max.Y <= min.Y)
|
||||
return false;
|
||||
|
||||
var tx = direction.X > 0f
|
||||
? (max.X - origin.X) / direction.X
|
||||
: direction.X < 0f
|
||||
? (min.X - origin.X) / direction.X
|
||||
: float.PositiveInfinity;
|
||||
var ty = direction.Y > 0f
|
||||
? (max.Y - origin.Y) / direction.Y
|
||||
: direction.Y < 0f
|
||||
? (min.Y - origin.Y) / direction.Y
|
||||
: float.PositiveInfinity;
|
||||
|
||||
var t = Math.Min(tx, ty);
|
||||
if (!float.IsFinite(t) || t <= 0f)
|
||||
return false;
|
||||
|
||||
edgePoint = origin + direction * t;
|
||||
|
||||
if (tx < ty)
|
||||
inwardNormal = direction.X > 0f ? -Vector2.UnitX : Vector2.UnitX;
|
||||
else
|
||||
inwardNormal = direction.Y > 0f ? -Vector2.UnitY : Vector2.UnitY;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Vector2 GetEdgeLabelPosition(
|
||||
Vector2 edgePoint,
|
||||
Vector2 inwardNormal,
|
||||
Vector2 labelSize,
|
||||
Vector2 viewportSize,
|
||||
float offset)
|
||||
{
|
||||
var anchor = edgePoint + inwardNormal * offset;
|
||||
Vector2 requested;
|
||||
if (Math.Abs(inwardNormal.X) > Math.Abs(inwardNormal.Y))
|
||||
{
|
||||
requested = inwardNormal.X > 0f
|
||||
? new Vector2(anchor.X, anchor.Y - labelSize.Y * 0.5f)
|
||||
: new Vector2(anchor.X - labelSize.X, anchor.Y - labelSize.Y * 0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
requested = inwardNormal.Y > 0f
|
||||
? new Vector2(anchor.X - labelSize.X * 0.5f, anchor.Y)
|
||||
: new Vector2(anchor.X - labelSize.X * 0.5f, anchor.Y - labelSize.Y);
|
||||
}
|
||||
|
||||
var minPosition = new Vector2(offset, offset);
|
||||
var maxPosition = viewportSize - labelSize - minPosition;
|
||||
return Vector2.Clamp(requested, minPosition, maxPosition);
|
||||
}
|
||||
|
||||
private static Vector2 GetAzimuthDirection(Angle baseAngle, float azimuthDegrees)
|
||||
{
|
||||
var angle = baseAngle + Angle.FromDegrees(azimuthDegrees);
|
||||
var radians = (float) angle.Theta - MathF.PI / 2f;
|
||||
return new Vector2(MathF.Cos(radians), MathF.Sin(radians));
|
||||
}
|
||||
// End Mono
|
||||
|
||||
protected void DrawGrid(DrawingHandleScreen handle, Matrix3x2 gridToView, Entity<MapGridComponent> grid, Color color, float alpha = 0.01f)
|
||||
{
|
||||
var rator = Maps.GetAllTilesEnumerator(grid.Owner, grid.Comp);
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
Orientation="Vertical">
|
||||
<!-- FTL Lock Section -->
|
||||
<controls1:StripeBack MinSize="48 48">
|
||||
<controls:Label Text="{controls:Loc 'FTL Lock'}" HorizontalAlignment="Center"/>
|
||||
<controls:Label Text="{controls:Loc 'shuttle-console-ftl-lock'}" HorizontalAlignment="Center"/>
|
||||
</controls1:StripeBack>
|
||||
<controls:PanelContainer VerticalExpand="True" HorizontalExpand="True" Margin="4 4 4 4">
|
||||
<controls:PanelContainer.PanelOverride>
|
||||
@@ -36,12 +36,12 @@
|
||||
</controls:PanelContainer.PanelOverride>
|
||||
<controls:BoxContainer Orientation="Horizontal" HorizontalAlignment="Stretch" Margin="5 5 5 5">
|
||||
<controls:Button Name="FTLLockEnabledButton"
|
||||
Text="{controls:Loc 'Enabled'}"
|
||||
Text="{controls:Loc 'shuttle-console-ftl-lock-enabled'}"
|
||||
ToggleMode="True"
|
||||
HorizontalExpand="True"
|
||||
StyleClasses="OpenRight"/>
|
||||
<controls:Button Name="FTLLockDisabledButton"
|
||||
Text="{controls:Loc 'Disabled'}"
|
||||
Text="{controls:Loc 'shuttle-console-ftl-lock-disabled'}"
|
||||
ToggleMode="True"
|
||||
HorizontalExpand="True"
|
||||
StyleClasses="OpenLeft"/>
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
<!-- Docks Section -->
|
||||
<controls1:StripeBack MinSize="48 48">
|
||||
<controls:Label Text="{controls:Loc 'Docks'}" HorizontalAlignment="Center"/>
|
||||
<controls:Label Text="{controls:Loc 'shuttle-console-docks-label'}" HorizontalAlignment="Center"/>
|
||||
</controls1:StripeBack>
|
||||
<controls:PanelContainer VerticalExpand="True" HorizontalExpand="True" Margin="4 4 4 4">
|
||||
<controls:PanelContainer.PanelOverride>
|
||||
@@ -62,7 +62,7 @@
|
||||
<graphics:StyleBoxFlat BorderThickness="2" BorderColor="#333333" BackgroundColor="#121212"/>
|
||||
</controls:PanelContainer.PanelOverride>
|
||||
<controls:Button Name="UndockAllButton"
|
||||
Text="{controls:Loc 'Undock All'}"
|
||||
Text="{controls:Loc 'shuttle-console-undock-all'}"
|
||||
Margin="5 5 5 5"
|
||||
StyleClasses="ButtonSquare"/>
|
||||
</controls:PanelContainer>
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
xmlns:ui="clr-namespace:Content.Client.Shuttles.UI"
|
||||
xmlns:controls1="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
xmlns:graphics="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client">
|
||||
<ui:ShuttleNavControl Name="NavRadar"
|
||||
MouseFilter="Stop"
|
||||
VerticalAlignment="Stretch"
|
||||
VerticalExpand="True"
|
||||
HorizontalExpand="True"
|
||||
Margin="5 4 10 5"/>
|
||||
<!-- Mono - wrap -->
|
||||
<controls:LayoutContainer Margin="5 4 10 5">
|
||||
<ui:ShuttleNavControl Name="NavRadar"
|
||||
MouseFilter="Stop"
|
||||
VerticalAlignment="Stretch"
|
||||
VerticalExpand="True"
|
||||
HorizontalExpand="True"/>
|
||||
</controls:LayoutContainer>
|
||||
<!-- Nav controls -->
|
||||
<controls:PanelContainer VerticalExpand="True" HorizontalExpand="True" Margin="4 4 4 4">
|
||||
<controls:PanelContainer.PanelOverride>
|
||||
@@ -212,36 +214,43 @@
|
||||
Text="{controls:Loc 'shuttle-console-device-button-1'}"
|
||||
TextAlign="Center"
|
||||
StyleClasses="ButtonSquare"
|
||||
ToolTip="{controls:Loc 'shuttle-console-network-connect-tooltip'}"
|
||||
SetWidth="55"/>
|
||||
<controls:Button Name="DeviceButton2"
|
||||
Text="{controls:Loc 'shuttle-console-device-button-2'}"
|
||||
TextAlign="Center"
|
||||
StyleClasses="ButtonSquare"
|
||||
ToolTip="{controls:Loc 'shuttle-console-network-connect-tooltip'}"
|
||||
SetWidth="55"/>
|
||||
<controls:Button Name="DeviceButton3"
|
||||
Text="{controls:Loc 'shuttle-console-device-button-3'}"
|
||||
TextAlign="Center"
|
||||
StyleClasses="ButtonSquare"
|
||||
ToolTip="{controls:Loc 'shuttle-console-network-connect-tooltip'}"
|
||||
SetWidth="55"/>
|
||||
<controls:Button Name="DeviceButton4"
|
||||
Text="{controls:Loc 'shuttle-console-device-button-4'}"
|
||||
TextAlign="Center"
|
||||
StyleClasses="ButtonSquare"
|
||||
ToolTip="{controls:Loc 'shuttle-console-network-connect-tooltip'}"
|
||||
SetWidth="55"/>
|
||||
<controls:Button Name="DeviceButton5"
|
||||
Text="{controls:Loc 'shuttle-console-device-button-5'}"
|
||||
TextAlign="Center"
|
||||
StyleClasses="ButtonSquare"
|
||||
ToolTip="{controls:Loc 'shuttle-console-network-connect-tooltip'}"
|
||||
SetWidth="55"/>
|
||||
<controls:Button Name="DeviceButton6"
|
||||
Text="{controls:Loc 'shuttle-console-device-button-6'}"
|
||||
TextAlign="Center"
|
||||
StyleClasses="ButtonSquare"
|
||||
ToolTip="{controls:Loc 'shuttle-console-network-connect-tooltip'}"
|
||||
SetWidth="55"/>
|
||||
<controls:Button Name="DeviceButton7"
|
||||
Text="{controls:Loc 'shuttle-console-device-button-7'}"
|
||||
TextAlign="Center"
|
||||
StyleClasses="ButtonSquare"
|
||||
ToolTip="{controls:Loc 'shuttle-console-network-connect-tooltip'}"
|
||||
SetWidth="55"/>
|
||||
<controls:Button Name="DeviceButton8"
|
||||
Text="{controls:Loc 'shuttle-console-device-button-8'}"
|
||||
|
||||
@@ -176,14 +176,15 @@ public sealed partial class NavScreen : BoxContainer
|
||||
var (_, worldRot, worldMatrix) = _xformSystem.GetWorldPositionRotationMatrix(gridXform);
|
||||
var worldPos = Vector2.Transform(gridBody.LocalCenter, worldMatrix);
|
||||
|
||||
// Get the positive reduced angle.
|
||||
var displayRot = -worldRot.Reduced();
|
||||
// Mono - remap to [0, 360)
|
||||
var displayRot = (-worldRot).Reduced();
|
||||
var displayRotDegrees = displayRot.FlipPositive().Degrees;
|
||||
|
||||
GridPosition.Text = Loc.GetString("shuttle-console-position-value",
|
||||
("X", $"{worldPos.X:0.0}"),
|
||||
("Y", $"{worldPos.Y:0.0}"));
|
||||
GridOrientation.Text = Loc.GetString("shuttle-console-orientation-value",
|
||||
("angle", $"{displayRot.Degrees:0.0}"));
|
||||
("angle", $"{displayRotDegrees:0.0}"));
|
||||
|
||||
var gridVelocity = gridBody.LinearVelocity;
|
||||
gridVelocity = displayRot.RotateVec(gridVelocity);
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
Title="{Loc 'radar-console-window-title'}"
|
||||
SetSize="648 672"
|
||||
MinSize="256 256">
|
||||
<ui:ShuttleNavControl Name="RadarScreen"
|
||||
Margin="4"
|
||||
HorizontalExpand = "True"
|
||||
VerticalExpand = "True"/>
|
||||
<LayoutContainer Margin="4">
|
||||
<!-- Mono - wrap -->
|
||||
<ui:ShuttleNavControl Name="RadarScreen"
|
||||
HorizontalExpand = "True"
|
||||
VerticalExpand = "True"/>
|
||||
</LayoutContainer>
|
||||
</controls:FancyWindow>
|
||||
|
||||
@@ -13,6 +13,7 @@ using JetBrains.Annotations;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Map;
|
||||
@@ -45,9 +46,10 @@ public partial class ShuttleNavControl : BaseShuttleControl // Mono
|
||||
/// <summary>
|
||||
/// Entity of controlling console
|
||||
/// </summary>
|
||||
private EntityUid? _consoleEntity;
|
||||
protected EntityUid? _consoleEntity; // Mono
|
||||
|
||||
protected Angle? _rotation; // Mono
|
||||
// Mono - is world rotation of the view.
|
||||
protected Angle? _rotation = Angle.Zero;
|
||||
|
||||
private Dictionary<NetEntity, List<DockingPortState>> _docks = new();
|
||||
|
||||
@@ -65,7 +67,6 @@ public partial class ShuttleNavControl : BaseShuttleControl // Mono
|
||||
public bool ShowIFF { get; set; } = true;
|
||||
public bool ShowIFFShuttles { get; set; } = true;
|
||||
public bool ShowDocks { get; set; } = true;
|
||||
public bool RotateWithEntity { get; set; } = true;
|
||||
|
||||
public float MaximumIFFDistance { get; set; } = 3000f; // Frontier // Mono - 3000 by default to not gigaclutter
|
||||
public bool HideCoords { get; set; } = false; // Frontier
|
||||
@@ -88,14 +89,16 @@ public partial class ShuttleNavControl : BaseShuttleControl // Mono
|
||||
public List<EntityUid>? Detectors = null;
|
||||
|
||||
#region Mono
|
||||
public bool RelativePanning = false;
|
||||
|
||||
// These 2 handle timing updates
|
||||
protected const float RadarUpdateInterval = 0f;
|
||||
protected float _updateAccumulator = 0f;
|
||||
|
||||
// doesn't support absolute panning and angle follow, but why would you need that?
|
||||
protected bool _relativePanning = false;
|
||||
protected bool _angleFollow = true;
|
||||
private bool _radarModeDefaultsApplied;
|
||||
|
||||
private bool _wasPanned = false;
|
||||
private EntityCoordinates? _oldCoordinates;
|
||||
#endregion
|
||||
|
||||
protected bool _isMouseDown;
|
||||
@@ -104,6 +107,20 @@ public partial class ShuttleNavControl : BaseShuttleControl // Mono
|
||||
protected float _lastFireTime;
|
||||
protected const float FireRateLimit = 0.1f; // 100ms between shots
|
||||
|
||||
private enum RadarAzimuthMode : byte
|
||||
{
|
||||
Edge,
|
||||
Ring,
|
||||
Off,
|
||||
}
|
||||
|
||||
private BoxContainer? _radarModeButtons;
|
||||
private RadarModeButton? _radarAzimuthButton;
|
||||
private RadarModeButton? _radarRotationButton;
|
||||
private RadarModeButton? _radarAnchorButton;
|
||||
private RadarModeButton? _radarResetButton;
|
||||
private RadarAzimuthMode _azimuthMode;
|
||||
|
||||
public ShuttleNavControl() : this(64f, 256f, 256f) { } // Mono
|
||||
|
||||
public ShuttleNavControl(float minRange, float maxRange, float range) : base(minRange, maxRange, range) // Mono
|
||||
@@ -135,12 +152,279 @@ public partial class ShuttleNavControl : BaseShuttleControl // Mono
|
||||
return;
|
||||
|
||||
_coordinates = coordinates;
|
||||
_rotation = angle;
|
||||
// Mono - TODO: either remove this or make this do anything
|
||||
// _rotation = angle;
|
||||
}
|
||||
|
||||
public void SetConsole(EntityUid? consoleEntity)
|
||||
{
|
||||
if (_consoleEntity == consoleEntity)
|
||||
return;
|
||||
|
||||
_consoleEntity = consoleEntity;
|
||||
_radarModeDefaultsApplied = false;
|
||||
ApplyRadarModeDefaults();
|
||||
}
|
||||
|
||||
// converts Offset to world-relative offset so we can modify radar parameters without conversion headaches
|
||||
// call this before potentially rotation-modifying operations and PanToEnt() after
|
||||
private void PanToWorld()
|
||||
{
|
||||
if (!_angleFollow || _coordinates is not { } cord)
|
||||
return;
|
||||
var coordEntRot = _transform.GetWorldRotation(cord.EntityId);
|
||||
Offset = coordEntRot.RotateVec(Offset);
|
||||
}
|
||||
|
||||
// converts world-relative Offset to relative to current view
|
||||
// call this after potentially rotation-modifying operations and PanToWorld() before
|
||||
private void PanToEnt()
|
||||
{
|
||||
if (!_angleFollow || _coordinates is not { } cord)
|
||||
return;
|
||||
var coordEntRot = _transform.GetWorldRotation(cord.EntityId);
|
||||
Offset = (-coordEntRot).RotateVec(Offset);
|
||||
}
|
||||
|
||||
// reanchor our view to console or grid
|
||||
private void ReanchorView()
|
||||
{
|
||||
if (_consoleEntity is not { } cons
|
||||
|| _coordinates is not { } cord
|
||||
|| !EntManager.TryGetComponent<TransformComponent>(cons, out var xform))
|
||||
return;
|
||||
|
||||
PanToWorld();
|
||||
var anchTo = cons;
|
||||
if (xform.GridUid != null)
|
||||
anchTo = xform.GridUid.Value;
|
||||
_coordinates = _transform.WithEntityId(cord, anchTo);
|
||||
_relativePanning = true;
|
||||
PanToEnt();
|
||||
}
|
||||
|
||||
private void EnsureRadarModeButtons()
|
||||
{
|
||||
if (_radarModeButtons != null)
|
||||
return;
|
||||
|
||||
if (Parent is not LayoutContainer parent)
|
||||
return;
|
||||
|
||||
LayoutContainer.SetAnchorPreset(this, LayoutContainer.LayoutPreset.Wide);
|
||||
|
||||
_radarModeButtons = new BoxContainer
|
||||
{
|
||||
Orientation = BoxContainer.LayoutOrientation.Horizontal,
|
||||
SeparationOverride = 2,
|
||||
HorizontalExpand = false,
|
||||
VerticalExpand = false,
|
||||
MouseFilter = MouseFilterMode.Stop,
|
||||
};
|
||||
|
||||
_radarAzimuthButton = CreateRadarModeButton(RadarModeButtonIcon.Azimuth);
|
||||
_radarAzimuthButton.ToolTip = Loc.GetString("shuttle-console-button-azimuth");
|
||||
_radarAzimuthButton.OnPressed += _ =>
|
||||
{
|
||||
_azimuthMode = _azimuthMode switch
|
||||
{
|
||||
RadarAzimuthMode.Edge => RadarAzimuthMode.Ring,
|
||||
RadarAzimuthMode.Ring => RadarAzimuthMode.Off,
|
||||
_ => RadarAzimuthMode.Edge,
|
||||
};
|
||||
};
|
||||
|
||||
_radarRotationButton = CreateRadarModeButton(RadarModeButtonIcon.Rotation);
|
||||
_radarRotationButton.ToolTip = Loc.GetString("shuttle-console-button-rotation");
|
||||
_radarRotationButton.OnPressed += _ =>
|
||||
{
|
||||
PanToWorld();
|
||||
_angleFollow ^= true;
|
||||
PanToEnt();
|
||||
};
|
||||
|
||||
_radarAnchorButton = CreateRadarModeButton(RadarModeButtonIcon.Anchor);
|
||||
_radarAnchorButton.ToolTip = Loc.GetString("shuttle-console-button-anchor");
|
||||
_radarAnchorButton.OnPressed += _ =>
|
||||
{
|
||||
if (_coordinates is not { } cord)
|
||||
return;
|
||||
|
||||
// if we're anchored or not yet bound to map, just deanchor
|
||||
if (_relativePanning || !EntManager.HasComponent<MapComponent>(cord.EntityId))
|
||||
{
|
||||
PanToWorld();
|
||||
// we're deanchoring, so simply detach our view to the map
|
||||
_coordinates = _transform.ToCoordinates(_transform.ToMapCoordinates(cord));
|
||||
_relativePanning = false;
|
||||
_wasPanned = true;
|
||||
PanToEnt();
|
||||
}
|
||||
else
|
||||
{
|
||||
ReanchorView();
|
||||
}
|
||||
};
|
||||
|
||||
_radarResetButton = CreateRadarModeButton(RadarModeButtonIcon.Reset);
|
||||
_radarResetButton.ToolTip = Loc.GetString("shuttle-console-button-reset");
|
||||
_radarResetButton.OnPressed += _ =>
|
||||
{
|
||||
_radarModeDefaultsApplied = false;
|
||||
ApplyRadarModeDefaults();
|
||||
if (EntManager.TryGetComponent<TransformComponent>(_consoleEntity, out var xform))
|
||||
{
|
||||
Offset = Vector2.Zero;
|
||||
_coordinates = xform.Coordinates;
|
||||
ReanchorView();
|
||||
}
|
||||
};
|
||||
|
||||
_radarModeButtons.AddChild(_radarAzimuthButton);
|
||||
_radarModeButtons.AddChild(_radarRotationButton);
|
||||
_radarModeButtons.AddChild(_radarAnchorButton);
|
||||
_radarModeButtons.AddChild(_radarResetButton);
|
||||
|
||||
parent.AddChild(_radarModeButtons);
|
||||
LayoutContainer.SetAnchorAndMarginPreset(_radarModeButtons, LayoutContainer.LayoutPreset.BottomLeft, margin: 10);
|
||||
}
|
||||
|
||||
private void ApplyRadarModeDefaults()
|
||||
{
|
||||
if (_radarModeDefaultsApplied)
|
||||
return;
|
||||
|
||||
if (!EntManager.TryGetComponent<RadarConsoleComponent>(_consoleEntity, out var radar))
|
||||
return;
|
||||
|
||||
_radarModeDefaultsApplied = true;
|
||||
Draggable = radar.Pannable;
|
||||
_angleFollow = !radar.NoRotate;
|
||||
_relativePanning = radar.RelativePanning;
|
||||
}
|
||||
|
||||
private static RadarModeButton CreateRadarModeButton(RadarModeButtonIcon icon = RadarModeButtonIcon.None)
|
||||
{
|
||||
return new RadarModeButton(icon)
|
||||
{
|
||||
MinWidth = 16f,
|
||||
MaxWidth = 16f,
|
||||
MinHeight = 16f,
|
||||
MaxHeight = 16f,
|
||||
HorizontalExpand = false,
|
||||
VerticalExpand = false,
|
||||
ModulateSelfOverride = Color.White.WithAlpha(0.55f),
|
||||
};
|
||||
}
|
||||
|
||||
internal enum RadarModeButtonIcon : byte
|
||||
{
|
||||
None,
|
||||
Azimuth,
|
||||
Rotation,
|
||||
Anchor,
|
||||
Reset
|
||||
}
|
||||
|
||||
public sealed class RadarModeButton : BaseButton
|
||||
{
|
||||
private readonly RadarModeButtonIcon _icon;
|
||||
|
||||
internal RadarModeButton(RadarModeButtonIcon icon)
|
||||
{
|
||||
_icon = icon;
|
||||
}
|
||||
|
||||
protected override Vector2 MeasureOverride(Vector2 availableSize)
|
||||
{
|
||||
return new Vector2(16f, 16f);
|
||||
}
|
||||
|
||||
protected override void Draw(DrawingHandleScreen handle)
|
||||
{
|
||||
var alpha = DrawMode switch
|
||||
{
|
||||
DrawModeEnum.Pressed => 0.62f,
|
||||
DrawModeEnum.Hover => 0.48f,
|
||||
_ => 0.32f,
|
||||
};
|
||||
|
||||
var center = new Vector2(PixelSize.X * 0.5f, PixelSize.Y * 0.5f);
|
||||
var radius = MathF.Min(PixelSize.X, PixelSize.Y) * 0.42f;
|
||||
handle.DrawCircle(center, radius, Color.White.WithAlpha(alpha));
|
||||
|
||||
var up = new Vector2(0f, -radius);
|
||||
var down = new Vector2(0f, radius);
|
||||
var leftOffs = new Vector2(-radius, 0f);
|
||||
var rightOffs = new Vector2(radius, 0f);
|
||||
var top = center + up;
|
||||
var bottom = center + down;
|
||||
var left = center + leftOffs;
|
||||
var right = center + rightOffs;
|
||||
|
||||
switch (_icon) {
|
||||
case RadarModeButtonIcon.Azimuth:
|
||||
{
|
||||
var iconColor = Color.Black.WithAlpha(0.95f);
|
||||
var topLeft = center + (up + leftOffs) / MathF.Sqrt(2f);
|
||||
var topRight = center + (up + rightOffs) / MathF.Sqrt(2f);
|
||||
var bottomLeft = center + (down + leftOffs) / MathF.Sqrt(2f);
|
||||
var bottomRight = center + (down + rightOffs) / MathF.Sqrt(2f);
|
||||
|
||||
handle.DrawLine(topLeft, bottomRight, iconColor);
|
||||
handle.DrawLine(bottomLeft, topRight, iconColor);
|
||||
handle.DrawLine(left, right, iconColor);
|
||||
handle.DrawLine(bottom, top, iconColor);
|
||||
break;
|
||||
}
|
||||
case RadarModeButtonIcon.Rotation:
|
||||
{
|
||||
var iconColor = Color.Yellow.WithAlpha(0.95f);
|
||||
var innerRatio = 0.8f;
|
||||
var segCount = 3;
|
||||
var prevOffs = up * innerRatio;
|
||||
for (var i = 0; i < segCount; i++)
|
||||
{
|
||||
var angle = Angle.FromDegrees(120f * i / (float)segCount - 15f);
|
||||
var thisOffs = angle.RotateVec(up * innerRatio);
|
||||
var thisPointUp = center + thisOffs;
|
||||
var thisPointDown = center - thisOffs;
|
||||
var oldPointUp = center + prevOffs;
|
||||
var oldPointDown = center - prevOffs;
|
||||
handle.DrawLine(oldPointUp, thisPointUp, iconColor);
|
||||
handle.DrawLine(oldPointDown, thisPointDown, iconColor);
|
||||
prevOffs = thisOffs;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RadarModeButtonIcon.Anchor:
|
||||
{
|
||||
var iconColor = Color.Blue.WithAlpha(0.95f);
|
||||
var stemTop = center + up * 0.5f;
|
||||
var crossLeft = center + leftOffs * 0.3f + up * 0.7f;
|
||||
var crossRight = center + rightOffs * 0.3f + up * 0.7f;;
|
||||
var leftFluke = center + leftOffs * 0.6f + down * 0.6f;
|
||||
var rightFluke = center + rightOffs * 0.6f + down * 0.6f;
|
||||
var innerRadius = radius * 0.4f;
|
||||
var innerTop = center + up * 0.6f;
|
||||
|
||||
handle.DrawCircle(innerTop, innerRadius, iconColor, false);
|
||||
handle.DrawLine(stemTop, bottom, iconColor);
|
||||
handle.DrawLine(crossLeft, crossRight, iconColor);
|
||||
handle.DrawLine(bottom, leftFluke, iconColor);
|
||||
handle.DrawLine(bottom, rightFluke, iconColor);
|
||||
break;
|
||||
}
|
||||
case RadarModeButtonIcon.Reset:
|
||||
{
|
||||
var iconColor = Color.Red.WithAlpha(0.95f);
|
||||
handle.DrawLine(left, right, iconColor);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mono - evil hack
|
||||
@@ -153,18 +437,15 @@ public partial class ShuttleNavControl : BaseShuttleControl // Mono
|
||||
if (!_draggin || _coordinates == null)
|
||||
return;
|
||||
|
||||
if (!_wasPanned)
|
||||
{
|
||||
_wasPanned = true;
|
||||
_oldCoordinates = RelativePanning ? _coordinates.Value : _transform.ToCoordinates(_transform.ToMapCoordinates(_coordinates.Value));
|
||||
if (!RelativePanning)
|
||||
_rotation = new Angle(0);
|
||||
}
|
||||
if (_oldCoordinates == null)
|
||||
return;
|
||||
if (!_relativePanning
|
||||
&& _coordinates?.EntityId is { } coordEnt
|
||||
&& EntManager.TryGetComponent<TransformComponent>(coordEnt, out var coordXform)
|
||||
&& coordXform.MapUid != coordEnt
|
||||
)
|
||||
_coordinates = _transform.ToCoordinates(_transform.ToMapCoordinates(_coordinates.Value));
|
||||
|
||||
var offs = (_rotation ?? new Angle(0)).RotateVec(InverseMapPosition(MidPointVector));
|
||||
_coordinates = _oldCoordinates.Value.Offset(offs);
|
||||
|
||||
_wasPanned = true;
|
||||
}
|
||||
|
||||
protected override void KeyBindDown(GUIBoundKeyEventArgs args)
|
||||
@@ -184,21 +465,11 @@ public partial class ShuttleNavControl : BaseShuttleControl // Mono
|
||||
base.KeyBindUp(args);
|
||||
|
||||
if (args.Function != EngineKeyFunctions.UIClick)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_isMouseDown = false;
|
||||
|
||||
if (_coordinates == null || _rotation == null || OnRadarClick == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var a = InverseScalePosition(args.RelativePosition);
|
||||
var relativeWorldPos = a with { Y = -a.Y };
|
||||
relativeWorldPos = _rotation.Value.RotateVec(relativeWorldPos);
|
||||
var coords = _coordinates.Value.Offset(relativeWorldPos);
|
||||
var coords = GetMouseEntityCoordinates(args.RelativePosition);
|
||||
OnRadarClick?.Invoke(coords);
|
||||
}
|
||||
|
||||
@@ -235,13 +506,7 @@ public partial class ShuttleNavControl : BaseShuttleControl // Mono
|
||||
|
||||
private void TryFireAtPosition(Vector2 relativePosition)
|
||||
{
|
||||
if (_coordinates == null || _rotation == null || OnRadarClick == null)
|
||||
return;
|
||||
|
||||
var a = InverseScalePosition(relativePosition);
|
||||
var relativeWorldPos = new Vector2(a.X, -a.Y);
|
||||
relativeWorldPos = _rotation.Value.RotateVec(relativeWorldPos);
|
||||
var coords = _coordinates.Value.Offset(relativeWorldPos);
|
||||
var coords = GetMouseEntityCoordinates(relativePosition);
|
||||
OnRadarClick?.Invoke(coords);
|
||||
}
|
||||
|
||||
@@ -257,14 +522,13 @@ public partial class ShuttleNavControl : BaseShuttleControl // Mono
|
||||
}
|
||||
|
||||
var pos = _uiManager.MousePositionScaled.Position - GlobalPosition;
|
||||
var relativeWorldPos = _rotation.Value.RotateVec(pos);
|
||||
|
||||
// I am not sure why the resulting point is 20 units under the mouse.
|
||||
return _coordinates.Value.Offset(relativeWorldPos);
|
||||
return GetMouseEntityCoordinates(pos);
|
||||
}
|
||||
|
||||
public void UpdateState(NavInterfaceState state)
|
||||
{
|
||||
EnsureRadarModeButtons();
|
||||
ApplyRadarModeDefaults();
|
||||
SetMatrix(EntManager.GetCoordinates(state.Coordinates), state.Angle);
|
||||
|
||||
WorldMaxRange = state.MaxRange;
|
||||
@@ -279,14 +543,6 @@ public partial class ShuttleNavControl : BaseShuttleControl // Mono
|
||||
|
||||
ActualRadarRange = Math.Clamp(ActualRadarRange, WorldMinRange, WorldMaxRange);
|
||||
|
||||
// Mono
|
||||
RelativePanning = state.RelativePanning;
|
||||
Draggable = state.Pannable;
|
||||
if (!Draggable)
|
||||
_wasPanned = false; // also reset
|
||||
|
||||
RotateWithEntity = state.RotateWithEntity;
|
||||
|
||||
// Frontier
|
||||
if (state.MaxIffRange != null)
|
||||
MaximumIFFDistance = state.MaxIffRange.Value;
|
||||
@@ -321,12 +577,24 @@ public partial class ShuttleNavControl : BaseShuttleControl // Mono
|
||||
return;
|
||||
}
|
||||
|
||||
var mapPos = _transform.ToMapCoordinates(_coordinates.Value);
|
||||
var posMatrix = Matrix3Helpers.CreateTransform(_coordinates.Value.Position, _rotation.Value);
|
||||
var ourEntRot = _wasPanned && !RelativePanning ? new Angle(0) : RotateWithEntity ? _transform.GetWorldRotation(xform) : _rotation.Value;
|
||||
var ourEntMatrix = Matrix3Helpers.CreateTransform(_transform.GetWorldPosition(xform), ourEntRot);
|
||||
var shuttleToWorld = Matrix3x2.Multiply(posMatrix, ourEntMatrix);
|
||||
Matrix3x2.Invert(shuttleToWorld, out var worldToShuttle);
|
||||
// Mono
|
||||
if (EntManager.TryGetComponent<RadarConsoleComponent>(_consoleEntity, out var radar))
|
||||
{
|
||||
Draggable = radar.Pannable;
|
||||
}
|
||||
// Mono - TODO: remove _rotation and make it a method instead
|
||||
var coordEnt = _coordinates.Value.EntityId;
|
||||
var coordEntRot = _transform.GetWorldRotation(coordEnt);
|
||||
if (_angleFollow && EntManager.TryGetComponent<TransformComponent>(coordEnt, out var coordXform))
|
||||
_rotation = coordEntRot;
|
||||
else
|
||||
_rotation = Angle.Zero;
|
||||
|
||||
var worldRot = _rotation.Value;
|
||||
var mapPos = _transform.ToMapCoordinates(_coordinates.Value).Offset(_rotation.Value.RotateVec(Offset));
|
||||
var mapCoord = _transform.ToCoordinates(mapPos);
|
||||
var worldToShuttle = Matrix3Helpers.CreateTranslation(-mapCoord.Position) * Matrix3Helpers.CreateRotation(-worldRot);
|
||||
Matrix3x2.Invert(worldToShuttle, out var shuttleToWorld);
|
||||
var shuttleToView = Matrix3x2.CreateScale(new Vector2(MinimapScale, -MinimapScale)) * Matrix3x2.CreateTranslation(MidPointVector);
|
||||
var worldToView = worldToShuttle * shuttleToView;
|
||||
|
||||
@@ -334,8 +602,23 @@ public partial class ShuttleNavControl : BaseShuttleControl // Mono
|
||||
DrawShields(handle, xform, worldToShuttle);
|
||||
|
||||
// Frontier Corvax: north line drawing
|
||||
var rot = ourEntRot + _rotation.Value;
|
||||
DrawNorthLine(handle, rot);
|
||||
DrawNorthLine(handle, worldRot);
|
||||
|
||||
// Mono
|
||||
switch (_azimuthMode)
|
||||
{
|
||||
case RadarAzimuthMode.Edge:
|
||||
DrawAzimuthScale(handle, worldRot);
|
||||
break;
|
||||
case RadarAzimuthMode.Ring:
|
||||
DrawAzimuthRing(handle, worldRot);
|
||||
break;
|
||||
}
|
||||
|
||||
if (worldRot != Angle.Zero)
|
||||
{
|
||||
DrawCompassOverlay(handle, coordEntRot);
|
||||
}
|
||||
|
||||
// Draw our grid in detail
|
||||
var ourGridId = xform.GridUid;
|
||||
@@ -361,7 +644,7 @@ public partial class ShuttleNavControl : BaseShuttleControl // Mono
|
||||
|
||||
handle.DrawPrimitives(DrawPrimitiveTopology.TriangleFan, radarPosVerts, Color.Lime);
|
||||
|
||||
var viewBounds = new Box2Rotated(new Box2(-WorldRange, -WorldRange, WorldRange, WorldRange).Translated(mapPos.Position), rot, mapPos.Position);
|
||||
var viewBounds = new Box2Rotated(new Box2(-WorldRange, -WorldRange, WorldRange, WorldRange).Translated(mapPos.Position), worldRot, mapPos.Position);
|
||||
var viewAABB = viewBounds.CalcBoundingBox();
|
||||
|
||||
_grids.Clear();
|
||||
@@ -426,9 +709,8 @@ public partial class ShuttleNavControl : BaseShuttleControl // Mono
|
||||
//shouldDrawIFF = NfCheckShouldDrawIffRangeCondition(shouldDrawIFF, mapCenter, curGridToWorld); // Frontier code
|
||||
// Frontier: range checks // Mono
|
||||
var gridMapPos = _transform.ToMapCoordinates(new EntityCoordinates(gUid, gridBody.LocalCenter)).Position;
|
||||
var ourPos = _transform.ToMapCoordinates(_coordinates.Value);
|
||||
if (!hideLabel) // Mono - show thermal signatures even at long range
|
||||
shouldDrawIFF = NfCheckShouldDrawIffRangeCondition(shouldDrawIFF, ourPos.Position - gridMapPos);
|
||||
shouldDrawIFF = NfCheckShouldDrawIffRangeCondition(shouldDrawIFF, mapPos.Position - gridMapPos);
|
||||
// End Frontier
|
||||
|
||||
// Mono
|
||||
@@ -629,7 +911,7 @@ public partial class ShuttleNavControl : BaseShuttleControl // Mono
|
||||
if (blip.Config.RespectZoom)
|
||||
box.Box = new Box2(box.Box.BottomLeft * MinimapScale, box.Box.TopRight * MinimapScale);
|
||||
if (blip.Config.Rotate)
|
||||
box.Rotation = ourEntRot - blip.Rotation;
|
||||
box.Rotation = worldRot - blip.Rotation;
|
||||
|
||||
if (blip.GridUid is { } grid)
|
||||
{
|
||||
@@ -873,11 +1155,24 @@ public partial class ShuttleNavControl : BaseShuttleControl // Mono
|
||||
|
||||
protected Vector2 InverseScalePosition(Vector2 value)
|
||||
{
|
||||
// Account for UI scaling: value is unscaled, so adjust by UIScale
|
||||
var scaledValue = value * UIScale;
|
||||
return (scaledValue - MidPointVector) / MinimapScale;
|
||||
}
|
||||
|
||||
// Mono
|
||||
protected EntityCoordinates GetMouseEntityCoordinates(Vector2 relativePosition)
|
||||
{
|
||||
if (_coordinates is not { } cord || _rotation is not { } rot)
|
||||
return new();
|
||||
|
||||
// multiply by UIScale because UI is Very Intelligent and doesn't scale mouse position for whatever reason
|
||||
var screenRelativeWorldPos = InverseMapPosition(relativePosition * UIScale);
|
||||
var relativeWorldPos = rot.RotateVec(screenRelativeWorldPos);
|
||||
var coordEntRot = _transform.GetWorldRotation(cord.EntityId);
|
||||
var coords = cord.Offset((-coordEntRot).RotateVec(relativeWorldPos));
|
||||
return coords;
|
||||
}
|
||||
|
||||
public class BlipData
|
||||
{
|
||||
public bool IsOutsideRadarCircle { get; set; }
|
||||
|
||||
@@ -257,7 +257,7 @@ public sealed partial class ChatUIController : IOnSystemChanged<CharacterInfoSys
|
||||
}
|
||||
|
||||
// Make it so it doesn't hightlight your own name when you are talking
|
||||
keyword = StartAtSign.Replace(keyword, @"(?<=\[BubbleContent\].*)");
|
||||
keyword = StartAtSign.Replace(keyword, @"(?<=\[BubbleContent\].*|""\[/color\].*)");
|
||||
|
||||
return keyword;
|
||||
}
|
||||
|
||||
@@ -23,10 +23,13 @@
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
|
||||
<ui:ShuttleNavControl Name="NavRadar"
|
||||
HorizontalExpand="True"
|
||||
VerticalExpand="True"
|
||||
MinHeight="400"/>
|
||||
<!-- Mono - wrap -->
|
||||
<LayoutContainer>
|
||||
<ui:ShuttleNavControl Name="NavRadar"
|
||||
HorizontalExpand="True"
|
||||
VerticalExpand="True"
|
||||
MinHeight="400"/>
|
||||
</LayoutContainer>
|
||||
|
||||
</GridContainer>
|
||||
</controls:FancyWindow>
|
||||
|
||||
@@ -34,7 +34,7 @@ public sealed partial class CompanyManager
|
||||
if (!_config.GetCVar(MonoCVars.CompanyWhitelist))
|
||||
return true;
|
||||
|
||||
if (!_proto.TryIndex(company, out var companyPrototype) ||
|
||||
if (!_proto.Resolve(company, out var companyPrototype) ||
|
||||
!companyPrototype.Whitelisted)
|
||||
{
|
||||
return true;
|
||||
|
||||
@@ -68,12 +68,14 @@ public sealed class FireControlNavControl : ShuttleNavControl
|
||||
|
||||
base.Draw(handle);
|
||||
|
||||
var mapPos = _transform.ToMapCoordinates(_coordinates.Value);
|
||||
var posMatrix = Matrix3Helpers.CreateTransform(_coordinates.Value.Position, _rotation.Value);
|
||||
var ourEntRot = RotateWithEntity ? _transform.GetWorldRotation(xform) : _rotation.Value;
|
||||
var ourEntMatrix = Matrix3Helpers.CreateTransform(_transform.GetWorldPosition(xform), ourEntRot);
|
||||
var shuttleToWorld = Matrix3x2.Multiply(posMatrix, ourEntMatrix);
|
||||
Matrix3x2.Invert(shuttleToWorld, out var worldToShuttle);
|
||||
var coordEntRot = _transform.GetWorldRotation(_coordinates.Value.EntityId);
|
||||
|
||||
var worldRot = _rotation.Value;
|
||||
|
||||
var mapPos = _transform.ToMapCoordinates(_coordinates.Value).Offset(_rotation.Value.RotateVec(Offset));
|
||||
var mapCoord = _transform.ToCoordinates(mapPos);
|
||||
var worldToShuttle = Matrix3Helpers.CreateTranslation(-mapCoord.Position) * Matrix3Helpers.CreateRotation(-worldRot);
|
||||
Matrix3x2.Invert(worldToShuttle, out var shuttleToWorld);
|
||||
var shuttleToView = Matrix3x2.CreateScale(new Vector2(MinimapScale, -MinimapScale)) * Matrix3x2.CreateTranslation(MidPointVector);
|
||||
var worldToView = worldToShuttle * shuttleToView;
|
||||
Matrix3x2.Invert(worldToView, out var viewToWorld);
|
||||
@@ -128,15 +130,7 @@ public sealed class FireControlNavControl : ShuttleNavControl
|
||||
|
||||
_lastCursorUpdateTime = (float)currentTime;
|
||||
|
||||
// Convert mouse position to world coordinates for missile tracking
|
||||
if (_coordinates == null || _rotation == null || OnRadarClick == null)
|
||||
return;
|
||||
|
||||
var a = InverseScalePosition(relativePosition);
|
||||
var relativeWorldPos = new Vector2(a.X, -a.Y);
|
||||
relativeWorldPos = _rotation.Value.RotateVec(relativeWorldPos);
|
||||
var coords = _coordinates.Value.Offset(relativeWorldPos);
|
||||
|
||||
var coords = GetMouseEntityCoordinates(relativePosition);
|
||||
// This will update the server of our cursor position without triggering actual firing
|
||||
OnRadarClick?.Invoke(coords);
|
||||
}
|
||||
|
||||
@@ -90,7 +90,9 @@
|
||||
|
||||
<!-- Radar Display -->
|
||||
<BoxContainer Name="RadarContainer" Orientation="Horizontal" HorizontalExpand="True" Margin="50 50 50 50">
|
||||
<ui:FireControlNavControl Name="NavRadar" />
|
||||
<LayoutContainer>
|
||||
<ui:FireControlNavControl Name="NavRadar" />
|
||||
</LayoutContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</controls:FancyWindow>
|
||||
|
||||
@@ -34,11 +34,6 @@ public sealed class PlantAnalyzerBoundUserInterface : BoundUserInterface
|
||||
_window.Populate(cast);
|
||||
}
|
||||
|
||||
public void AdvPressed(bool scanMode)
|
||||
{
|
||||
SendMessage(new PlantAnalyzerSetMode(scanMode));
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
@@ -3,30 +3,28 @@
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
Title="{Loc 'plant-analyzer-interface-title'}">
|
||||
<!-- Margin="left,top,right,bottom" -->
|
||||
<GridContainer Rows="3" Name ="GridCont" Margin="10 5 10 5" VerticalAlignment="Stretch" HorizontalExpand="True">
|
||||
<BoxContainer Name="Toggle">
|
||||
<Label Name="AdvMode" Text="{Loc 'plant-analyzer-window-scanmode'}" Margin="5 0 5 0"/>
|
||||
<Button Name="OnButton" Text="{Loc 'plant-analyzer-window-mode-on'}" StyleClasses="OpenRight"/>
|
||||
<Button Name="OffButton" Text="{Loc 'plant-analyzer-window-mode-off'}" StyleClasses="OpenLeft"/>
|
||||
</BoxContainer>
|
||||
<GridContainer Rows="2" Name ="GridCont" Margin="10 5 10 5">
|
||||
<BoxContainer Name="Top">
|
||||
<Label Name="NoData" Text="{Loc 'plant-analyzer-window-no-seed-information-text'}" Margin="10 0 0 0"/>
|
||||
</BoxContainer>
|
||||
<TabContainer Name="Tabs" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" HorizontalExpand="True">
|
||||
<BoxContainer Name ="{Loc 'plant-analyzer-window-tab-basics'}" Orientation="Vertical" VerticalAlignment="Stretch" Margin="10 0 5 0">
|
||||
<Label Name="PlantName" Margin="0 5 0 5"/>
|
||||
<Label Name="PlantYield" Margin="0 5 0 5"/>
|
||||
<Label Name="Potency" Margin="0 5 0 5"/>
|
||||
<Label Name="Repeat" Margin="0 5 0 5"/>
|
||||
<Label Name="Chemicals" Margin="0 5 0 5"/>
|
||||
<Label Name="ConsumeGases" Margin="0 5 0 5" />
|
||||
<Label Name="ExudeGases" Margin="0 5 0 5" />
|
||||
<Label Name="Lifespan" Margin="0 5 0 5"/>
|
||||
<Label Name="Maturation" Margin="0 5 0 5"/>
|
||||
<Label Name="Production" Margin="0 5 0 5"/>
|
||||
<Label Name="GrowthStages" Margin="0 5 0 5"/>
|
||||
<Label Name="Endurance" Margin="0 5 0 5"/>
|
||||
</BoxContainer>
|
||||
<TabContainer Name="Tabs" VerticalExpand="True" HorizontalExpand="True" VerticalAlignment="Stretch" MinSize="300 400">
|
||||
<ScrollContainer Name ="{Loc 'plant-analyzer-window-tab-basics'}">
|
||||
<BoxContainer Orientation="Vertical" VerticalAlignment="Stretch" Margin="10 0 5 0">
|
||||
<Label Name="PlantName" Margin="0 5 0 5"/>
|
||||
<Label Name="PlantYield" Margin="0 5 0 5"/>
|
||||
<Label Name="Potency" Margin="0 5 0 5"/>
|
||||
<Label Name="Repeat" Margin="0 5 0 5"/>
|
||||
<Label Name="Lifespan" Margin="0 5 0 5"/>
|
||||
<Label Name="Maturation" Margin="0 5 0 5"/>
|
||||
<Label Name="Production" Margin="0 5 0 5"/>
|
||||
<Label Name="GrowthStages" Margin="0 5 0 5"/>
|
||||
<Label Name="Endurance" Margin="0 5 0 5"/>
|
||||
<Label Name="ConsumeGases" Margin="0 5 0 5" />
|
||||
<Label Name="ExudeGases" Margin="0 5 0 5" />
|
||||
<Label Name="Chemicals" Margin="0 5 0 5"/>
|
||||
</BoxContainer>
|
||||
</ScrollContainer>
|
||||
|
||||
<BoxContainer Name="{Loc 'plant-analyzer-window-tab-tolerances'}" Orientation="Vertical" VerticalAlignment="Stretch" Margin="10 0 5 0">
|
||||
<Label Name="NutrientUsage" Margin="0 5 0 5"/>
|
||||
<Label Name="WaterUsage" Margin="0 5 0 5"/>
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
using Content.Shared._NF.PlantAnalyzer;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Prototypes;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using FancyWindow = Content.Client.UserInterface.Controls.FancyWindow;
|
||||
|
||||
@@ -15,8 +10,6 @@ namespace Content.Client._NF.PlantAnalyzer.UI;
|
||||
public sealed partial class PlantAnalyzerWindow : FancyWindow
|
||||
{
|
||||
private readonly IEntityManager _entityManager;
|
||||
private readonly ButtonGroup _buttonGroup = new();
|
||||
|
||||
private const string IndentedNewline = "\n ";
|
||||
|
||||
public PlantAnalyzerWindow(PlantAnalyzerBoundUserInterface owner)
|
||||
@@ -26,13 +19,6 @@ public sealed partial class PlantAnalyzerWindow : FancyWindow
|
||||
var dependencies = IoCManager.Instance!;
|
||||
_entityManager = dependencies.Resolve<IEntityManager>();
|
||||
|
||||
OnButton.Group = _buttonGroup;
|
||||
OnButton.ToggleMode = true;
|
||||
OffButton.Group = _buttonGroup;
|
||||
OffButton.ToggleMode = true;
|
||||
|
||||
OnButton.OnPressed += _ => owner.AdvPressed(true);
|
||||
OffButton.OnPressed += _ => owner.AdvPressed(false);
|
||||
}
|
||||
|
||||
public void Populate(PlantAnalyzerScannedSeedPlantInformation msg)
|
||||
@@ -47,15 +33,6 @@ public sealed partial class PlantAnalyzerWindow : FancyWindow
|
||||
}
|
||||
NoData.Visible = false;
|
||||
|
||||
if (msg.AdvancedInfo is not null)
|
||||
{
|
||||
OnButton.Pressed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
OffButton.Pressed = true;
|
||||
}
|
||||
|
||||
// Process message fields into strings.
|
||||
StringBuilder chemString = new();
|
||||
if (msg.SeedChem != null)
|
||||
@@ -79,60 +56,65 @@ public sealed partial class PlantAnalyzerWindow : FancyWindow
|
||||
Potency.Text = Loc.GetString("plant-analyzer-plant-potency-text", ("seedPotency", $"{msg.SeedPotency:F0}"));
|
||||
Repeat.Text = Loc.GetString("plant-analyzer-plant-harvest-text", ("plantHarvestType", Loc.GetString($"plant-analyzer-harvest-{msg.HarvestType}").ToString()));
|
||||
Endurance.Text = Loc.GetString("plant-analyzer-plant-endurance-text", ("seedEndurance", $"{msg.Endurance:F0}"));
|
||||
Chemicals.Text = Loc.GetString("plant-analyzer-plant-chemistry-text", ("seedChem", chemString));
|
||||
ExudeGases.Text = Loc.GetString("plant-analyzer-plant-exude-text", ("gases", exudeGases.Length == 0 ? Loc.GetString("plant-analyzer-plant-gases-none") : exudeGases.ToString()));
|
||||
ConsumeGases.Text = Loc.GetString("plant-analyzer-plant-consume-text", ("gases", consudeGases.Length == 0 ? Loc.GetString("plant-analyzer-plant-gases-none") : consudeGases.ToString()));
|
||||
Lifespan.Text = Loc.GetString("plant-analyzer-plant-lifespan-text", ("lifespan", $"{msg.Lifespan:F1}"));
|
||||
Maturation.Text = Loc.GetString("plant-analyzer-plant-maturation-text", ("maturation", $"{msg.Maturation:F1}"));
|
||||
Production.Text = Loc.GetString("plant-analyzer-plant-production-text", ("production", $"{msg.Production:F1}"));
|
||||
GrowthStages.Text = Loc.GetString("plant-analyzer-plant-growthstages-text", ("growthStages", $"{msg.GrowthStages:D0}"));
|
||||
ConsumeGases.Text = Loc.GetString("plant-analyzer-plant-consume-text", ("gases", consudeGases.Length == 0 ? Loc.GetString("plant-analyzer-plant-gases-none") : consudeGases.ToString()));
|
||||
ExudeGases.Text = Loc.GetString("plant-analyzer-plant-exude-text", ("gases", exudeGases.Length == 0 ? Loc.GetString("plant-analyzer-plant-gases-none") : exudeGases.ToString()));
|
||||
Chemicals.Text = Loc.GetString("plant-analyzer-plant-chemistry-text", ("seedChem", chemString));
|
||||
// Tolerances
|
||||
var adv = msg.AdvancedInfo;
|
||||
NutrientUsage.Text = Loc.GetString("plant-analyzer-tolerance-nutrient-usage", ("nutrientUsage", adv is null ? "-" : $"{adv.Value.NutrientConsumption:F2}"));
|
||||
WaterUsage.Text = Loc.GetString("plant-analyzer-tolerance-water-usage", ("waterUsage", adv is null ? "-" : $"{adv.Value.WaterConsumption:F2}"));
|
||||
IdealHeat.Text = Loc.GetString("plant-analyzer-tolerance-ideal-heat", ("idealHeat", adv is null ? "-" : $"{adv.Value.IdealHeat:F0}"));
|
||||
HeatTolerance.Text = Loc.GetString("plant-analyzer-tolerance-heat-tolerance", ("heatTolerance", adv is null ? "-" : $"{adv.Value.HeatTolerance:F1}"));
|
||||
IdealLight.Text = Loc.GetString("plant-analyzer-tolerance-ideal-light", ("idealLight", adv is null ? "-" : $"{adv.Value.IdealLight:F1}"));
|
||||
LightTolerance.Text = Loc.GetString("plant-analyzer-tolerance-light-tolerance", ("lightTolerance", adv is null ? "-" : $"{adv.Value.LightTolerance:F1}"));
|
||||
ToxinsTolerance.Text = Loc.GetString("plant-analyzer-tolerance-toxin-tolerance", ("toxinsTolerance", adv is null ? "-" : $"{adv.Value.ToxinsTolerance:F1}"));
|
||||
LowPressureTolerance.Text = Loc.GetString("plant-analyzer-tolerance-low-pressure", ("lowPressureTolerance", adv is null ? "-" : $"{adv.Value.LowPressureTolerance:F1}")); ;
|
||||
HighPressureTolerance.Text = Loc.GetString("plant-analyzer-tolerance-high-pressure", ("highPressureTolerance", adv is null ? "-" : $"{adv.Value.HighPressureTolerance:F1}"));
|
||||
PestTolerance.Text = Loc.GetString("plant-analyzer-tolerance-pest-tolerance", ("pestTolerance", adv is null ? "-" : $"{adv.Value.PestTolerance:F1}"));
|
||||
WeedTolerance.Text = Loc.GetString("plant-analyzer-tolerance-weed-tolerance", ("weedTolerance", adv is null ? "-" : $"{adv.Value.WeedTolerance:F1}"));
|
||||
NutrientUsage.Text = Loc.GetString("plant-analyzer-tolerance-nutrient-usage", ("nutrientUsage", $"{msg.NutrientConsumption:F2}"));
|
||||
WaterUsage.Text = Loc.GetString("plant-analyzer-tolerance-water-usage", ("waterUsage", $"{msg.WaterConsumption:F2}"));
|
||||
IdealHeat.Text = Loc.GetString("plant-analyzer-tolerance-ideal-heat", ("idealHeat", $"{msg.IdealHeat:F0}"));
|
||||
HeatTolerance.Text = Loc.GetString("plant-analyzer-tolerance-heat-tolerance", ("heatTolerance", $"{msg.HeatTolerance:F1}"));
|
||||
IdealLight.Text = Loc.GetString("plant-analyzer-tolerance-ideal-light", ("idealLight", $"{msg.IdealLight:F1}"));
|
||||
LightTolerance.Text = Loc.GetString("plant-analyzer-tolerance-light-tolerance", ("lightTolerance", $"{msg.LightTolerance:F1}"));
|
||||
ToxinsTolerance.Text = Loc.GetString("plant-analyzer-tolerance-toxin-tolerance", ("toxinsTolerance", $"{msg.ToxinsTolerance:F1}"));
|
||||
LowPressureTolerance.Text = Loc.GetString("plant-analyzer-tolerance-low-pressure", ("lowPressureTolerance", $"{msg.LowPressureTolerance:F1}"));
|
||||
HighPressureTolerance.Text = Loc.GetString("plant-analyzer-tolerance-high-pressure", ("highPressureTolerance", $"{msg.HighPressureTolerance:F1}"));
|
||||
PestTolerance.Text = Loc.GetString("plant-analyzer-tolerance-pest-tolerance", ("pestTolerance", $"{msg.PestTolerance:F1}"));
|
||||
WeedTolerance.Text = Loc.GetString("plant-analyzer-tolerance-weed-tolerance", ("weedTolerance", $"{msg.WeedTolerance:F1}"));
|
||||
|
||||
// Misc
|
||||
|
||||
if (adv != null)
|
||||
{
|
||||
var advInst = adv.Value;
|
||||
StringBuilder mutations = new();
|
||||
if (advInst.Mutations.HasFlag(MutationFlags.TurnIntoKudzu))
|
||||
{
|
||||
mutations.Append(IndentedNewline);
|
||||
mutations.Append(Loc.GetString("plant-analyzer-mutation-turnintokudzu"));
|
||||
}
|
||||
if (advInst.Mutations.HasFlag(MutationFlags.Seedless))
|
||||
{
|
||||
mutations.Append(IndentedNewline);
|
||||
mutations.Append(Loc.GetString("plant-analyzer-mutation-seedless"));
|
||||
}
|
||||
if (advInst.Mutations.HasFlag(MutationFlags.Ligneous))
|
||||
{
|
||||
mutations.Append(IndentedNewline);
|
||||
mutations.Append(Loc.GetString("plant-analyzer-mutation-ligneous"));
|
||||
}
|
||||
if (advInst.Mutations.HasFlag(MutationFlags.CanScream))
|
||||
{
|
||||
mutations.Append(IndentedNewline);
|
||||
mutations.Append(Loc.GetString("plant-analyzer-mutation-canscream"));
|
||||
}
|
||||
StringBuilder mutations = new();
|
||||
|
||||
Traits.Text = Loc.GetString("plant-analyzer-plant-mutations-text", ("traits", mutations.ToString()));
|
||||
}
|
||||
else
|
||||
if (msg.Mutations.HasFlag(MutationFlags.TurnIntoKudzu))
|
||||
{
|
||||
Traits.Text = Loc.GetString("plant-analyzer-plant-mutations-text", ("traits", "-"));
|
||||
mutations.Append(IndentedNewline);
|
||||
mutations.Append(Loc.GetString("plant-analyzer-mutation-turnintokudzu"));
|
||||
}
|
||||
|
||||
if (msg.Mutations.HasFlag(MutationFlags.Seedless))
|
||||
{
|
||||
mutations.Append(IndentedNewline);
|
||||
mutations.Append(Loc.GetString("plant-analyzer-mutation-seedless"));
|
||||
}
|
||||
|
||||
if (msg.Mutations.HasFlag(MutationFlags.Ligneous))
|
||||
{
|
||||
mutations.Append(IndentedNewline);
|
||||
mutations.Append(Loc.GetString("plant-analyzer-mutation-ligneous"));
|
||||
}
|
||||
|
||||
if (msg.Mutations.HasFlag(MutationFlags.CanScream))
|
||||
{
|
||||
mutations.Append(IndentedNewline);
|
||||
mutations.Append(Loc.GetString("plant-analyzer-mutation-canscream"));
|
||||
}
|
||||
|
||||
if (msg.Mutations.HasFlag(MutationFlags.Unviable))
|
||||
{
|
||||
mutations.Append(IndentedNewline);
|
||||
mutations.Append(Loc.GetString("plant-analyzer-mutation-unviable"));
|
||||
}
|
||||
|
||||
var traitsText = mutations.Length == 0 ? "-" : mutations.ToString();
|
||||
|
||||
Traits.Text = Loc.GetString("plant-analyzer-plant-mutations-text", ("traits", traitsText));
|
||||
|
||||
|
||||
StringBuilder speciation = new();
|
||||
if (msg.Speciation is null)
|
||||
{
|
||||
|
||||
@@ -44,10 +44,15 @@ namespace Content.Server.Destructible
|
||||
[Dependency] public readonly IPrototypeManager PrototypeManager = default!;
|
||||
[Dependency] public readonly IAdminLogManager _adminLogger = default!;
|
||||
|
||||
// Mono
|
||||
private EntityQuery<DestructibleComponent> _destructibleQuery;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<DestructibleComponent, DamageChangedEvent>(Execute);
|
||||
|
||||
_destructibleQuery = GetEntityQuery<DestructibleComponent>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -131,7 +136,7 @@ namespace Content.Server.Destructible
|
||||
public bool TryGetDestroyedAt(Entity<DestructibleComponent?> ent, [NotNullWhen(true)] out FixedPoint2? destroyedAt)
|
||||
{
|
||||
destroyedAt = null;
|
||||
if (!Resolve(ent, ref ent.Comp, false))
|
||||
if (!_destructibleQuery.TryComp(ent, out ent.Comp)) // Mono
|
||||
return false;
|
||||
|
||||
destroyedAt = DestroyedAt(ent, ent.Comp);
|
||||
|
||||
@@ -81,7 +81,7 @@ public sealed partial class ExplosionSystem
|
||||
|
||||
// As above, but for space-based explosion propagating from space onto grids.
|
||||
HashSet<EntityUid> encounteredGrids = new();
|
||||
Dictionary<EntityUid, HashSet<Vector2i>>? previousGridJump;
|
||||
// Dictionary<EntityUid, HashSet<Vector2i>>? previousGridJump; // Mono
|
||||
|
||||
// variables for transforming between grid and space-coordinates
|
||||
var spaceMatrix = Matrix3x2.Identity;
|
||||
@@ -174,14 +174,27 @@ public sealed partial class ExplosionSystem
|
||||
|
||||
// In order to treat "cost" of moving off a grid on the same level as moving onto a grid, both space -> grid and grid -> space have to be delayed by one iteration.
|
||||
previousSpaceJump = spaceJump;
|
||||
previousGridJump = spaceData?.GridJump;
|
||||
spaceJump = new();
|
||||
|
||||
var newTileCount = 0;
|
||||
|
||||
if (previousGridJump != null)
|
||||
encounteredGrids.UnionWith(previousGridJump.Keys);
|
||||
// Mono - explosion fix, feat. gemini from googer
|
||||
// 1. Process space expansion FIRST.
|
||||
// If space-data is null, but some grid-based explosion reached space, we need to initialize it.
|
||||
if (spaceData == null && previousSpaceJump.Count != 0)
|
||||
spaceData = new ExplosionSpaceTileFlood(this, epicenter, referenceGrid, localGrids, maxDistance);
|
||||
|
||||
// If the explosion has reached space, do that neighbors finding step as well.
|
||||
if (spaceData != null)
|
||||
newTileCount += spaceData.AddNewTiles(iteration, previousSpaceJump);
|
||||
|
||||
// 2. Feed the new grid jumps immediately into THIS iteration (0 delay for Space -> Grid transitions)
|
||||
var currentGridJump = spaceData?.GridJump;
|
||||
|
||||
if (currentGridJump != null)
|
||||
encounteredGrids.UnionWith(currentGridJump.Keys);
|
||||
|
||||
// 3. Process grids and immediate space->grid jumps
|
||||
foreach (var grid in encounteredGrids)
|
||||
{
|
||||
// is this a new grid, for which we must create a new explosion data set
|
||||
@@ -205,18 +218,10 @@ public sealed partial class ExplosionSystem
|
||||
}
|
||||
|
||||
// get the new neighbours, and populate gridToSpaceTiles in the process.
|
||||
newTileCount += data.AddNewTiles(iteration, previousGridJump?.GetValueOrDefault(grid));
|
||||
newTileCount += data.AddNewTiles(iteration, currentGridJump?.GetValueOrDefault(grid));
|
||||
spaceJump.UnionWith(data.SpaceJump);
|
||||
}
|
||||
|
||||
// if space-data is null, but some grid-based explosion reached space, we need to initialize it.
|
||||
if (spaceData == null && previousSpaceJump.Count != 0)
|
||||
spaceData = new ExplosionSpaceTileFlood(this, epicenter, referenceGrid, localGrids, maxDistance);
|
||||
|
||||
// If the explosion has reached space, do that neighbors finding step as well.
|
||||
if (spaceData != null)
|
||||
newTileCount += spaceData.AddNewTiles(iteration, previousSpaceJump);
|
||||
|
||||
// Does adding these tiles bring us above the total target intensity?
|
||||
tilesInIteration.Add(newTileCount);
|
||||
if (newTileCount * stepSize >= remainingIntensity)
|
||||
|
||||
@@ -85,6 +85,9 @@ public sealed class SmokeSystem : EntitySystem
|
||||
if (_smokeAffectedQuery.HasComponent(args.OtherEntity))
|
||||
return;
|
||||
|
||||
if (TerminatingOrDeleted(args.OtherEntity)) // Mono: Testfail fix
|
||||
return;
|
||||
|
||||
var smokeAffected = AddComp<SmokeAffectedComponent>(args.OtherEntity);
|
||||
smokeAffected.SmokeEntity = entity;
|
||||
smokeAffected.NextSecond = _timing.CurTime + TimeSpan.FromSeconds(1);
|
||||
@@ -104,6 +107,9 @@ public sealed class SmokeSystem : EntitySystem
|
||||
if (!TryComp<PhysicsComponent>(args.OtherEntity, out var body))
|
||||
return;
|
||||
|
||||
if (TerminatingOrDeleted(args.OtherEntity)) // Mono: Testfail fix
|
||||
return;
|
||||
|
||||
foreach (var ent in _physics.GetContactingEntities(args.OtherEntity, body))
|
||||
{
|
||||
if (exists && ent == entity.Owner)
|
||||
|
||||
@@ -17,5 +17,11 @@ public sealed partial class LatheProducingComponent : Component
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public TimeSpan ProductionLength;
|
||||
|
||||
/// <summary>
|
||||
/// The Entity that queued this recipe - Mono
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public EntityUid? Actor;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ namespace Content.Server.Lathe
|
||||
[Dependency] private readonly ReagentSpeedSystem _reagentSpeed = default!;
|
||||
[Dependency] private readonly SharedSolutionContainerSystem _solution = default!;
|
||||
[Dependency] private readonly StackSystem _stack = default!;
|
||||
[Dependency] private readonly ContrabandTurnInSystem _contraband = default!; // Mono
|
||||
[Dependency] private readonly TransformSystem _transform = default!;
|
||||
[Dependency] private readonly DeviceLinkSystem _deviceLink = default!; // Mono
|
||||
|
||||
@@ -225,7 +226,7 @@ namespace Content.Server.Lathe
|
||||
}
|
||||
|
||||
public bool TryAddToQueue(EntityUid uid, LatheRecipePrototype recipe, int quantity, LatheComponent? component = null, // Frontier: add quantity
|
||||
bool canDebt = false) // Mono
|
||||
EntityUid? actor = null, bool canDebt = false) // Mono
|
||||
{
|
||||
if (!Resolve(uid, ref component))
|
||||
return false;
|
||||
@@ -243,7 +244,8 @@ namespace Content.Server.Lathe
|
||||
if (component.Queue.Count > 0 && component.Queue[^1].Recipe.ID == recipe.ID)
|
||||
component.Queue[^1].ItemsRequested += quantity;
|
||||
else
|
||||
component.Queue.Add(new LatheRecipeBatch(recipe, 0, quantity));
|
||||
component.Queue.Add(new LatheRecipeBatch(recipe, 0, quantity,
|
||||
GetNetEntity(actor))); // Mono: Adds actor
|
||||
// End Frontier
|
||||
// component.Queue.Add(recipe); // Frontier
|
||||
|
||||
@@ -264,6 +266,7 @@ namespace Content.Server.Lathe
|
||||
|
||||
// Frontier: handle batches
|
||||
var batch = component.Queue.First();
|
||||
var actor = batch.Actor; // Mono: Adds actor
|
||||
var recipe = batch.Recipe;
|
||||
// <Mono> - resources now consumed as the production goes
|
||||
if (!CanProduce(uid, recipe, 1, component))
|
||||
@@ -296,6 +299,7 @@ namespace Content.Server.Lathe
|
||||
var lathe = EnsureComp<LatheProducingComponent>(uid);
|
||||
lathe.StartTime = _timing.CurTime;
|
||||
lathe.ProductionLength = time * component.FinalTimeMultiplier; // Frontier: TimeMultiplier<FinalTimeMultiplier
|
||||
lathe.Actor = GetEntity(actor);
|
||||
component.CurrentRecipe = recipe;
|
||||
|
||||
var ev = new LatheStartPrintingEvent(recipe);
|
||||
@@ -325,8 +329,13 @@ namespace Content.Server.Lathe
|
||||
|
||||
// Frontier: adjust price before merge (stack prices changed once)
|
||||
if (result.Valid)
|
||||
{
|
||||
ModifyPrintedEntityPrice(uid, comp, result);
|
||||
// End Frontier
|
||||
// End Frontier
|
||||
|
||||
// Mono: Handle printable contraband
|
||||
_contraband.HandleContrabandValueByCompany(result, prodComp.Actor);
|
||||
}
|
||||
|
||||
_stack.TryMergeToContacts(result);
|
||||
}
|
||||
@@ -355,8 +364,9 @@ namespace Content.Server.Lathe
|
||||
}
|
||||
|
||||
// <Mono>
|
||||
// Add the actor that previously queued to looped items
|
||||
if (comp.Loop)
|
||||
TryAddToQueue(uid, comp.CurrentRecipe, 1, comp, true);
|
||||
TryAddToQueue(uid, comp.CurrentRecipe, 1, comp, prodComp.Actor, true);
|
||||
|
||||
_deviceLink.SendSignal(uid, comp.ProducedPort, true);
|
||||
// </Mono>
|
||||
@@ -493,7 +503,7 @@ namespace Content.Server.Lathe
|
||||
if (_proto.TryIndex(args.ID, out LatheRecipePrototype? recipe))
|
||||
{
|
||||
// Frontier: batching recipes
|
||||
if (TryAddToQueue(uid, recipe, args.Quantity, component))
|
||||
if (TryAddToQueue(uid, recipe, args.Quantity, component, args.Actor))
|
||||
{
|
||||
_adminLogger.Add(LogType.Action,
|
||||
LogImpact.Low,
|
||||
|
||||
@@ -50,6 +50,11 @@ public sealed partial class NPCRangedCombatComponent : Component
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public float ShootAccumulator;
|
||||
|
||||
/// <summary>
|
||||
/// Mono - accept having to fire for up to this many seconds to destroy an obstacle.
|
||||
/// </summary>
|
||||
public float ShotsThreshold = 2;
|
||||
|
||||
/// <summary>
|
||||
/// Sound to play if the target enters line of sight.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Mono - whole file
|
||||
|
||||
namespace Content.Server.NPC.Queries.Considerations;
|
||||
|
||||
/// <summary>
|
||||
/// Identical to NPCCombatSystem.Ranged LOS check.
|
||||
/// </summary>
|
||||
public sealed partial class GunTargetGoodCon : UtilityConsideration
|
||||
{
|
||||
[DataField]
|
||||
public float ShootThroughThreshold = 2f;
|
||||
}
|
||||
// TODO: rewrite HTN and make this not evil
|
||||
@@ -1,9 +1,11 @@
|
||||
using System.Numerics;
|
||||
using Content.Server.Destructible; // Mono
|
||||
using Content.Server.NPC.Components;
|
||||
using Content.Shared._Goobstation.Weapons.SmartGun;
|
||||
using Content.Shared.CombatMode;
|
||||
using Content.Shared.Damage.Components;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.NPC.Components; // Mono
|
||||
using Content.Shared.Physics;
|
||||
using Content.Shared.Weapons.Ranged.Components;
|
||||
using Content.Shared.Weapons.Ranged.Events;
|
||||
@@ -18,6 +20,7 @@ public sealed partial class NPCCombatSystem
|
||||
[Dependency] private readonly SharedCombatModeSystem _combat = default!;
|
||||
[Dependency] private readonly RotateToFaceSystem _rotate = default!;
|
||||
[Dependency] private readonly SharedLaserPointerSystem _pointer = default!; // Goobstation
|
||||
[Dependency] private readonly DestructibleSystem _destructible = default!;
|
||||
|
||||
private EntityQuery<CombatModeComponent> _combatQuery;
|
||||
private EntityQuery<NPCSteeringComponent> _steeringQuery;
|
||||
@@ -25,6 +28,7 @@ public sealed partial class NPCCombatSystem
|
||||
private EntityQuery<PhysicsComponent> _physicsQuery;
|
||||
private EntityQuery<TransformComponent> _xformQuery;
|
||||
private EntityQuery<RequireProjectileTargetComponent> _requireTargetQuery; // Mono
|
||||
private EntityQuery<NpcFactionMemberComponent> _factionQuery; // Mono
|
||||
|
||||
// TODO: Don't predict for hitscan
|
||||
private const float ShootSpeed = 20f;
|
||||
@@ -42,6 +46,7 @@ public sealed partial class NPCCombatSystem
|
||||
_steeringQuery = GetEntityQuery<NPCSteeringComponent>();
|
||||
_xformQuery = GetEntityQuery<TransformComponent>();
|
||||
_requireTargetQuery = GetEntityQuery<RequireProjectileTargetComponent>(); // Mono
|
||||
_factionQuery = GetEntityQuery<NpcFactionMemberComponent>(); // Mono
|
||||
|
||||
SubscribeLocalEvent<NPCRangedCombatComponent, ComponentStartup>(OnRangedStartup);
|
||||
SubscribeLocalEvent<NPCRangedCombatComponent, ComponentShutdown>(OnRangedShutdown);
|
||||
@@ -74,10 +79,12 @@ public sealed partial class NPCCombatSystem
|
||||
|
||||
private void UpdateRanged(float frameTime)
|
||||
{
|
||||
var query = EntityQueryEnumerator<NPCRangedCombatComponent, TransformComponent>();
|
||||
var query = EntityQueryEnumerator<NPCRangedCombatComponent>();
|
||||
|
||||
while (query.MoveNext(out var uid, out var comp, out var xform))
|
||||
while (query.MoveNext(out var uid, out var comp))
|
||||
{
|
||||
var xform = Transform(uid); // Mono
|
||||
|
||||
if (!_gun.TryGetGun(uid, out var gunUid, out var gun))
|
||||
{
|
||||
comp.Status = CombatStatus.NoWeapon;
|
||||
@@ -152,12 +159,8 @@ public sealed partial class NPCCombatSystem
|
||||
if (comp.LOSAccumulator < 0f)
|
||||
{
|
||||
comp.LOSAccumulator += UnoccludedCooldown;
|
||||
// For consistency with NPC steering. // Mono
|
||||
comp.TargetInLOS = _interaction.InRangeUnobstructed(uid, comp.Target, distance + 0.1f, comp.ObstructedMask, predicate: (EntityUid entity) =>
|
||||
{
|
||||
return _physicsQuery.TryGetComponent(entity, out var physics) && (physics.CollisionLayer & (int)comp.BulletMask) == 0 // ignore if it can't collide with bullets
|
||||
|| _requireTargetQuery.HasComponent(entity); // or if it requires targeting
|
||||
});
|
||||
// Mono
|
||||
comp.TargetInLOS = InRangeGoodTarget((gunUid, gun), uid, comp.Target, distance, comp.ShotsThreshold, comp.ObstructedMask, comp.BulletMask);
|
||||
}
|
||||
|
||||
if (!comp.TargetInLOS)
|
||||
@@ -265,4 +268,37 @@ public sealed partial class NPCCombatSystem
|
||||
target);
|
||||
}
|
||||
}
|
||||
|
||||
// Mono
|
||||
public bool InRangeGoodTarget(Entity<GunComponent?> gun, EntityUid source, EntityUid target, float distance, float shotsThreshold, CollisionGroup obstructedMask = CollisionGroup.Opaque, CollisionGroup bulletMask = CollisionGroup.Impassable | CollisionGroup.BulletImpassable)
|
||||
{
|
||||
if (!Resolve(gun, ref gun.Comp, false))
|
||||
return false;
|
||||
|
||||
var dmg = _gun.GetNextDamage(gun).GetTotal().Float(); // this will be wrong but damageable is evil and i have no idea how to do this better
|
||||
var destroyAccum = 0f;
|
||||
var firerate = gun.Comp.FireRateModified;
|
||||
var threshold = shotsThreshold;
|
||||
// For consistency with NPC steering. // Mono
|
||||
return _interaction.InRangeUnobstructed(source, target, distance + 0.1f, obstructedMask,
|
||||
predicate: (EntityUid uid) => {
|
||||
if (_physicsQuery.TryGetComponent(uid, out var physics)
|
||||
&& (physics.CollisionLayer & (int)bulletMask) == 0
|
||||
) // this will collide with the bullet
|
||||
return true;
|
||||
|
||||
if (_requireTargetQuery.HasComponent(uid)) // requires targeting so it won't collide
|
||||
return true;
|
||||
|
||||
// do not consider living things for shoot-through
|
||||
if (!_factionQuery.HasComp(uid)
|
||||
&& _destructible.TryGetDestroyedAt(uid, out var at))
|
||||
{
|
||||
destroyAccum += at.Value.Float() / dmg / firerate;
|
||||
if (destroyAccum < threshold)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Server.Atmos.Components;
|
||||
using Content.Server.Destructible; // Mono
|
||||
using Content.Server.Fluids.EntitySystems;
|
||||
using Content.Server._Mono.NPC.HTN; // Mono
|
||||
using Content.Server.NPC.Queries;
|
||||
@@ -12,6 +13,7 @@ using Content.Server.Shuttles.Components; // Mono
|
||||
using Content.Server.Storage.Components;
|
||||
using Content.Shared.Chemistry.EntitySystems;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Damage.Components;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Fluids.Components;
|
||||
using Content.Shared.Hands.Components;
|
||||
@@ -19,16 +21,20 @@ using Content.Shared.Inventory;
|
||||
using Content.Shared.Mobs;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.NPC.Components; // Mono
|
||||
using Content.Shared.NPC.Systems;
|
||||
using Content.Shared.Nutrition.Components;
|
||||
using Content.Shared.Nutrition.EntitySystems;
|
||||
using Content.Shared.Physics;
|
||||
using Content.Shared.Tools.Systems;
|
||||
using Content.Shared.Weapons.Melee;
|
||||
using Content.Shared.Weapons.Ranged.Components;
|
||||
using Content.Shared.Weapons.Ranged.Events;
|
||||
using Content.Server.Weapons.Ranged.Systems; // Mono
|
||||
using Content.Shared.Whitelist;
|
||||
using Microsoft.Extensions.ObjectPool;
|
||||
using Robust.Server.Containers;
|
||||
using Robust.Shared.Physics.Components; // Mono
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
using System.Linq;
|
||||
@@ -58,9 +64,15 @@ public sealed class NPCUtilitySystem : EntitySystem
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
[Dependency] private readonly MobThresholdSystem _thresholdSystem = default!;
|
||||
[Dependency] private readonly StatusEffectsSystem _statusEffectsSystem = default!; // Frontier
|
||||
[Dependency] private readonly DestructibleSystem _destructible = default!; // Mono
|
||||
[Dependency] private readonly GunSystem _gun = default!; // Mono
|
||||
[Dependency] private readonly NPCCombatSystem _npcCombat = default!;
|
||||
|
||||
private EntityQuery<PuddleComponent> _puddleQuery;
|
||||
private EntityQuery<TransformComponent> _xformQuery;
|
||||
private EntityQuery<PhysicsComponent> _physicsQuery; // Mono
|
||||
private EntityQuery<RequireProjectileTargetComponent> _requireTargetQuery; // Mono
|
||||
private EntityQuery<NpcFactionMemberComponent> _factionQuery; // Mono
|
||||
|
||||
private ObjectPool<HashSet<EntityUid>> _entPool =
|
||||
new DefaultObjectPool<HashSet<EntityUid>>(new SetPolicy<EntityUid>(), 256);
|
||||
@@ -75,6 +87,9 @@ public sealed class NPCUtilitySystem : EntitySystem
|
||||
base.Initialize();
|
||||
_puddleQuery = GetEntityQuery<PuddleComponent>();
|
||||
_xformQuery = GetEntityQuery<TransformComponent>();
|
||||
_physicsQuery = GetEntityQuery<PhysicsComponent>(); // Mono
|
||||
_requireTargetQuery = GetEntityQuery<RequireProjectileTargetComponent>(); // Mono
|
||||
_factionQuery = GetEntityQuery<NpcFactionMemberComponent>(); // Mono
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -353,6 +368,17 @@ public sealed class NPCUtilitySystem : EntitySystem
|
||||
|
||||
return _examine.InRangeUnOccluded(owner, targetUid, radius + bufferRange, null) ? 1f : 0f;
|
||||
}
|
||||
// Mono
|
||||
case GunTargetGoodCon con:
|
||||
{
|
||||
if (!_gun.TryGetGun(owner, out var gunUid, out var gun))
|
||||
return 0f;
|
||||
|
||||
var radius = blackboard.GetValueOrDefault<float>(blackboard.GetVisionRadiusKey(EntityManager), EntityManager);
|
||||
const float bufferRange = 0.5f;
|
||||
|
||||
return _npcCombat.InRangeGoodTarget((gunUid, gun), owner, targetUid, radius + bufferRange, con.ShootThroughThreshold) ? 1f : 0f;
|
||||
}
|
||||
case TargetIsAliveCon:
|
||||
{
|
||||
return _mobState.IsAlive(targetUid) ? 1f : 0f;
|
||||
|
||||
@@ -320,7 +320,10 @@ public sealed class MoverController : SharedMoverController
|
||||
{
|
||||
var velLenSq = localVel.LengthSquared();
|
||||
var dirCompVel = localVel * dot / velLenSq;
|
||||
var scaledComp = dirCompVel / MathF.Pow(2f, localVel.Length() / shuttle.BaseMaxLinearVelocity + 1f);
|
||||
var velRatio = localVel.Length() / shuttle.BaseMaxLinearVelocity;
|
||||
// less effect at lower velocities
|
||||
var exponent = velRatio * MathF.Pow(velRatio / (1f + velRatio), 3f);
|
||||
var scaledComp = dirCompVel / MathF.Pow(2f, exponent);
|
||||
dir = dir - dirCompVel + scaledComp;
|
||||
}
|
||||
|
||||
|
||||
@@ -144,7 +144,8 @@ public sealed class ProjectileSystem : SharedProjectileSystem
|
||||
continue;
|
||||
|
||||
var xform = Transform(uid);
|
||||
var lastPosition = _transformSystem.GetWorldPosition(xform);
|
||||
var lastMap = _transformSystem.GetMapCoordinates(xform);
|
||||
var lastPosition = lastMap.Position;
|
||||
var rayDirection = currentVelocity / velLen;
|
||||
// Ensure rayDistance is not zero to prevent issues with IntersectRay if frametime or velocity is zero.
|
||||
var rayDistance = velLen * frameTime;
|
||||
@@ -243,9 +244,9 @@ public sealed class ProjectileSystem : SharedProjectileSystem
|
||||
return false;
|
||||
|
||||
// teleport us so we hit it
|
||||
// this is cursed but i don't think there's a better way to force a collision here
|
||||
var hitXform = Transform(minHit.Uid.Value);
|
||||
var hitPos = hitXform.Coordinates;
|
||||
var hitMapCoord = lastMap.Offset(rayDirection * minHit.Distance);
|
||||
var hitPos = _transformSystem.ToCoordinates(hitMapCoord);
|
||||
// if we somehow hit something not directly parented to space or a grid
|
||||
if (hitXform.Coordinates.EntityId != hitXform.GridUid && hitXform.GridUid != null)
|
||||
hitPos = _transformSystem.WithEntityId(hitPos, hitXform.GridUid.Value);
|
||||
|
||||
@@ -457,18 +457,20 @@ namespace Content.Server.Shuttles.Systems
|
||||
return;
|
||||
}
|
||||
|
||||
var shuttleUid = Transform(console.Value).GridUid;
|
||||
|
||||
if (!CanShuttleDock(shuttleUid))
|
||||
if (!TryGetEntity(args.DockEntity, out var ourDock) ||
|
||||
!TryGetEntity(args.TargetDockEntity, out var targetDock) ||
|
||||
!TryComp(ourDock, out DockingComponent? ourDockComp) ||
|
||||
!TryComp(targetDock, out DockingComponent? targetDockComp))
|
||||
{
|
||||
_popup.PopupCursor(Loc.GetString("shuttle-console-dock-fail"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryGetEntity(args.DockEntity, out var ourDock) ||
|
||||
!TryGetEntity(args.TargetDockEntity, out var targetDock) ||
|
||||
!TryComp(ourDock, out DockingComponent? ourDockComp) ||
|
||||
!TryComp(targetDock, out DockingComponent? targetDockComp))
|
||||
var shuttleUid = Transform(console.Value).GridUid;
|
||||
var otherShuttleUid = Transform(targetDock.Value).GridUid; // Mono
|
||||
|
||||
// Mono - check both grids
|
||||
if (!CanShuttleDock(shuttleUid) || !CanShuttleDock(otherShuttleUid))
|
||||
{
|
||||
_popup.PopupCursor(Loc.GetString("shuttle-console-dock-fail"));
|
||||
return;
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace Content.Server.Shuttles.Systems;
|
||||
|
||||
public sealed class RadarConsoleSystem : SharedRadarConsoleSystem
|
||||
{
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!; // Mono
|
||||
[Dependency] private readonly ShuttleConsoleSystem _console = default!;
|
||||
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
|
||||
|
||||
@@ -39,14 +40,20 @@ public sealed class RadarConsoleSystem : SharedRadarConsoleSystem
|
||||
protected override void UpdateState(EntityUid uid, RadarConsoleComponent component)
|
||||
{
|
||||
var xform = Transform(uid);
|
||||
var onGrid = xform.ParentUid == xform.GridUid;
|
||||
EntityCoordinates? coordinates = onGrid ? xform.Coordinates : null;
|
||||
Angle? angle = onGrid ? xform.LocalRotation : null;
|
||||
// Mono
|
||||
var parentUid = xform.GridUid;
|
||||
EntityCoordinates? coordinates = null;
|
||||
Angle? angle = null;
|
||||
if (component.FollowEntity)
|
||||
{
|
||||
coordinates = new EntityCoordinates(uid, Vector2.Zero);
|
||||
angle = Angle.Zero; // Frontier: Angle.Zero<Angle.FromDegrees(180) // Mono - frontier strikes again
|
||||
}
|
||||
else if (parentUid is { } parent)
|
||||
{
|
||||
coordinates = _transform.WithEntityId(xform.Coordinates, parent);
|
||||
angle = _transform.GetWorldRotation(xform) - _transform.GetWorldRotation(parent);
|
||||
}
|
||||
|
||||
if (_uiSystem.HasUi(uid, RadarConsoleUiKey.Key))
|
||||
{
|
||||
@@ -62,8 +69,6 @@ public sealed class RadarConsoleSystem : SharedRadarConsoleSystem
|
||||
state = _console.GetNavState(uid, docks);
|
||||
}
|
||||
|
||||
state.RotateWithEntity = !component.FollowEntity;
|
||||
|
||||
// Frontier: ghost radar restrictions
|
||||
if (component.MaxIffRange != null)
|
||||
state.MaxIffRange = component.MaxIffRange.Value;
|
||||
|
||||
@@ -556,9 +556,7 @@ public sealed partial class ShuttleConsoleSystem : SharedShuttleConsoleSystem
|
||||
angle,
|
||||
docks,
|
||||
_shuttle.NfGetInertiaDampeningMode(entity), // Frontier: inertia dampening
|
||||
portNames,
|
||||
entity.Comp1.Pannable, // Mono
|
||||
entity.Comp1.RelativePanning); // Mono
|
||||
portNames);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -91,20 +91,19 @@ public sealed partial class GunSystem : SharedGunSystem
|
||||
}
|
||||
}
|
||||
|
||||
var fromMap = fromCoordinates.ToMap(EntityManager, TransformSystem);
|
||||
var toMap = toCoordinates.ToMapPos(EntityManager, TransformSystem);
|
||||
var fromMap = TransformSystem.ToMapCoordinates(fromCoordinates);
|
||||
var toMap = TransformSystem.ToMapCoordinates(toCoordinates).Position;
|
||||
var mapDirection = toMap - fromMap.Position;
|
||||
var mapAngle = mapDirection.ToAngle();
|
||||
|
||||
// If applicable, this ensures the projectile is parented to grid on spawn, instead of the map.
|
||||
var fromEnt = MapManager.TryFindGridAt(fromMap, out var gridUid, out var grid)
|
||||
? fromCoordinates.WithEntityId(gridUid, EntityManager)
|
||||
: new EntityCoordinates(MapManager.GetMapEntityId(fromMap.MapId), fromMap.Position);
|
||||
? _transform.WithEntityId(fromCoordinates, gridUid)
|
||||
: _transform.ToCoordinates(fromMap);
|
||||
|
||||
// get gun's local velocity
|
||||
// get gun's fromEnt-relative velocity
|
||||
var gunVelocity = Vector2.Zero;
|
||||
if (_physQuery.TryComp(gunUid, out var gunBody))
|
||||
gunVelocity = gunBody.LinearVelocity;
|
||||
gunVelocity = Physics.GetMapLinearVelocity(gunUid) - Physics.GetMapLinearVelocity(fromEnt);
|
||||
|
||||
// I must be high because this was getting tripped even when true.
|
||||
// DebugTools.Assert(direction != Vector2.Zero);
|
||||
@@ -239,7 +238,7 @@ public sealed partial class GunSystem : SharedGunSystem
|
||||
}
|
||||
|
||||
// Do a throw
|
||||
if (!HasComp<ProjectileComponent>(uid))
|
||||
if (!TryComp(uid, out ProjectileComponent? projectileComp))
|
||||
{
|
||||
RemoveShootable(uid);
|
||||
// TODO: Someone can probably yeet this a billion miles so need to pre-validate input somewhere up the call stack.
|
||||
@@ -255,6 +254,7 @@ public sealed partial class GunSystem : SharedGunSystem
|
||||
predicted.ClientEnt = user;
|
||||
}
|
||||
|
||||
projectileComp.Damage *= gun.DamageModifier;
|
||||
ShootProjectile(uid, mapDirection, gunVelocity, gunUid, user, gun.ProjectileSpeedModified, offset); // Mono - add offset
|
||||
if (HasComp<FireControllableComponent>(gunUid))
|
||||
{
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using Content.Server.Atmos.Rotting;
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Server.DoAfter;
|
||||
using Content.Server.EUI;
|
||||
using Content.Server.Ghost;
|
||||
using Content.Server.Nutrition.EntitySystems;
|
||||
using Content.Server.Popups;
|
||||
using Content.Shared.Atmos.Rotting;
|
||||
@@ -9,9 +11,11 @@ using Content.Shared.DoAfter;
|
||||
using Content.Shared.Inventory;
|
||||
|
||||
using Content.Shared.Medical.CPR;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Mobs;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.Traits.Assorted;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Server.Audio;
|
||||
using Robust.Shared.Audio;
|
||||
@@ -32,6 +36,8 @@ public sealed class CPRSystem : EntitySystem
|
||||
[Dependency] private readonly RottingSystem _rottingSystem = default!;
|
||||
[Dependency] private readonly InventorySystem _inventory = default!;
|
||||
[Dependency] private readonly AudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedMindSystem _mind = default!; // Mono
|
||||
[Dependency] private readonly EuiManager _euiManager = default!; // Mono
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -103,26 +109,41 @@ public sealed class CPRSystem : EntitySystem
|
||||
|
||||
private void OnCPRDoAfter(Entity<CPRTrainingComponent> performer, ref CPRDoAfterEvent args)
|
||||
{
|
||||
if (args.Cancelled || args.Handled || !args.Target.HasValue)
|
||||
if (args.Cancelled || args.Handled || args.Target is not { } target) // Mono: replaces args.Target with target, makes target not nullable
|
||||
{
|
||||
performer.Comp.CPRPlayingStream = _audio.Stop(performer.Comp.CPRPlayingStream);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!performer.Comp.CPRHealing.Empty)
|
||||
_damageable.TryChangeDamage(args.Target, performer.Comp.CPRHealing, true, origin: performer);
|
||||
_damageable.TryChangeDamage(target, performer.Comp.CPRHealing, true, origin: performer);
|
||||
|
||||
if (performer.Comp.RotReductionMultiplier > 0)
|
||||
_rottingSystem.ReduceAccumulator(
|
||||
(EntityUid)args.Target, performer.Comp.DoAfterDuration * performer.Comp.RotReductionMultiplier);
|
||||
|
||||
if (_robustRandom.Prob(performer.Comp.ResuscitationChance)
|
||||
&& _mobThreshold.TryGetThresholdForState((EntityUid)args.Target, MobState.Dead, out var threshold)
|
||||
&& TryComp<DamageableComponent>(args.Target, out var damageableComponent)
|
||||
&& TryComp<MobStateComponent>(args.Target, out var state)
|
||||
&& _mobThreshold.TryGetThresholdForState(target, MobState.Dead, out var threshold)
|
||||
&& TryComp<DamageableComponent>(target, out var damageableComponent)
|
||||
&& !HasComp<UnrevivableComponent>(target) // Mono: Checks unreviveability
|
||||
&& TryComp<MobStateComponent>(target, out var state)
|
||||
&& damageableComponent.TotalDamage < threshold)
|
||||
{
|
||||
_mobStateSystem.ChangeMobState(args.Target.Value, MobState.Critical, state, performer);
|
||||
|
||||
// Mono Edit: Informs the ghost they've been revived.
|
||||
if (_mind.TryGetMind(target, out _, out var mind) &&
|
||||
mind.Session is { } playerSession)
|
||||
{
|
||||
// notify them they're being revived.
|
||||
if (mind.CurrentEntity != target)
|
||||
{
|
||||
_euiManager.OpenEui(new ReturnToBodyEui(mind, _mind), playerSession);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var isAlive = _mobStateSystem.IsAlive(args.Target.Value);
|
||||
args.Repeat = !isAlive;
|
||||
if (isAlive)
|
||||
|
||||
@@ -147,7 +147,7 @@ public sealed class CompanyManager
|
||||
|
||||
await _db.RemoveCompanyMember(player, company);
|
||||
|
||||
if (_player.TryGetSessionById(new NetUserId(player), out var session))
|
||||
if (_player.TryGetSessionById(player, out var session))
|
||||
SendCompanyWhitelist(session.Channel);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ public sealed class ThermalSignatureSystem : EntitySystem
|
||||
|
||||
private const float HeatChangeThreshold = 1.02f;
|
||||
|
||||
private List<Entity<ThermalSignatureComponent>> _gridQueue = new();
|
||||
|
||||
private EntityQuery<ThermalSignatureComponent> _sigQuery;
|
||||
private EntityQuery<GunComponent> _gunQuery;
|
||||
private EntityQuery<MapGridComponent> _mapGridQuery;
|
||||
@@ -106,6 +108,7 @@ public sealed class ThermalSignatureSystem : EntitySystem
|
||||
gridSigComp.TotalHeat = 0f;
|
||||
}
|
||||
|
||||
_gridQueue.Clear();
|
||||
var query = EntityQueryEnumerator<ThermalSignatureComponent>();
|
||||
while (query.MoveNext(out var uid, out var sigComp))
|
||||
{
|
||||
@@ -117,15 +120,8 @@ public sealed class ThermalSignatureSystem : EntitySystem
|
||||
|
||||
if (_mapGridQuery.HasComp(uid))
|
||||
{
|
||||
sigComp.TotalHeat += sigComp.StoredHeat;
|
||||
|
||||
// don't sync it if it didn't change heat much since last time, we don't need to sync 500 cold asteroids every system update
|
||||
if (sigComp.TotalHeat <= sigComp.LastUpdateHeat * HeatChangeThreshold
|
||||
&& sigComp.TotalHeat >= sigComp.LastUpdateHeat / HeatChangeThreshold)
|
||||
continue;
|
||||
|
||||
sigComp.LastUpdateHeat = sigComp.TotalHeat;
|
||||
Dirty(uid, sigComp);
|
||||
_gridQueue.Add((uid, sigComp));
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -135,5 +131,17 @@ public sealed class ThermalSignatureSystem : EntitySystem
|
||||
gridSig.TotalHeat += sigComp.StoredHeat;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var ent in _gridQueue) {
|
||||
ent.Comp.TotalHeat += ent.Comp.StoredHeat;
|
||||
|
||||
// don't sync it if it didn't change heat much since last time, we don't need to sync 500 cold asteroids every system update
|
||||
if (ent.Comp.TotalHeat <= ent.Comp.LastUpdateHeat * HeatChangeThreshold
|
||||
&& ent.Comp.TotalHeat >= ent.Comp.LastUpdateHeat / HeatChangeThreshold)
|
||||
continue;
|
||||
|
||||
ent.Comp.LastUpdateHeat = ent.Comp.TotalHeat;
|
||||
Dirty(ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ public sealed partial class ShipSteererComponent : Component
|
||||
/// Try to evade collisions this far into the future even if stationary.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public float BaseEvasionTime = 10f;
|
||||
public float BaseEvasionTime = 4f;
|
||||
|
||||
/// <summary>
|
||||
/// How unwilling we are to use brake to adjust our velocity. Higher means less willing.
|
||||
@@ -88,7 +88,7 @@ public sealed partial class ShipSteererComponent : Component
|
||||
/// How much to enlarge grid search bounds for collision evasion.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public float GridSearchBuffer = 192f;
|
||||
public float GridSearchBuffer = 312f;
|
||||
|
||||
/// <summary>
|
||||
/// How much to enlarge grid search forward distance for collision evasion.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Content.Server._Mono.Projectiles.TargetSeeking;
|
||||
using Content.Server.Physics.Controllers;
|
||||
using Content.Server.Shuttles.Components;
|
||||
using Content.Shared._Mono;
|
||||
@@ -19,6 +20,7 @@ public sealed partial class ShipSteeringSystem : EntitySystem
|
||||
[Dependency] private readonly MoverController _mover = default!;
|
||||
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly TargetSeekingSystem _seeking = default!;
|
||||
|
||||
private EntityQuery<MapGridComponent> _gridQuery;
|
||||
private EntityQuery<ProjectileGridPhaseComponent> _phaseQuery;
|
||||
@@ -227,11 +229,12 @@ public sealed partial class ShipSteeringSystem : EntitySystem
|
||||
var avoidanceVec = CalculateAvoidanceVector(ctx, config, brakeCtx, navVec);
|
||||
|
||||
// use avoidance vector if available or proceed with thrust as normal
|
||||
var wasNav = navVec;
|
||||
var wishInputVec = avoidanceVec ?? navVec;
|
||||
|
||||
var rotWish = wishInputVec;
|
||||
if (avoidanceVec != null && config.AvoidanceNoRotate)
|
||||
rotWish = CalculateNavigationVector(ctx, brakeCtx);
|
||||
rotWish = wasNav;
|
||||
|
||||
// process angular input
|
||||
var rotControl = CalculateRotationControl(ctx, config, rotWish, ref rotationCompensation);
|
||||
@@ -344,6 +347,10 @@ public sealed partial class ShipSteeringSystem : EntitySystem
|
||||
var simTime = brake.BrakeAccel == 0f ? 10f : 2f * ctx.ShipBody.LinearVelocity.Length() / brake.BrakeAccel;
|
||||
simTime += config.BaseEvasionTime;
|
||||
|
||||
var forwardAccelVec = _mover.GetDirectionAccel(new Vector2(0f, 1f), ctx.Shuttle, ctx.ShipBody, ctx.ShipXform);
|
||||
var forwardAccelDir = NormalizedOrZero(forwardAccelVec);
|
||||
var forwardAccel = forwardAccelVec.Length();
|
||||
|
||||
_sectors.Clear();
|
||||
for (var i = 0; i < config.EvasionSectorCount; i++)
|
||||
{
|
||||
@@ -351,6 +358,9 @@ public sealed partial class ShipSteeringSystem : EntitySystem
|
||||
var dir = angle.ToVec();
|
||||
|
||||
var dirAccel = _mover.GetWorldDirectionAccel(dir, ctx.Shuttle, ctx.ShipBody, ctx.ShipXform);
|
||||
if (dirAccel.LengthSquared() == 0f) {
|
||||
dirAccel = dir * forwardAccel * (Vector2.Dot(dir, forwardAccelDir) + 1) * 0.5f;
|
||||
}
|
||||
|
||||
for (var depth = 1; depth <= config.EvasionSectorDepth; depth++)
|
||||
{
|
||||
@@ -372,59 +382,83 @@ public sealed partial class ShipSteeringSystem : EntitySystem
|
||||
var relVel = shipVel - obsVel;
|
||||
var toObsVec = obsPos - shipPos;
|
||||
var toObsDir = toObsVec.Normalized();
|
||||
// TODO: narrowphase avoidance if we overlap
|
||||
var obsDistance = MathF.Max(toObsVec.Length() - sumRadius, 1f);
|
||||
|
||||
var obsAccel = Vector2.Zero;
|
||||
if (_shuttleQuery.TryComp(obstacle.Ent, out var obsShuttle))
|
||||
obsAccel = obsShuttle.LastThrust;
|
||||
// Distances to bounding planes
|
||||
var obsDistanceFront = MathF.Max(toObsVec.Length() - sumRadius, 1f);
|
||||
var obsDistanceCenter = toObsVec.Length();
|
||||
|
||||
// get time-to-collide with the accel of each sector
|
||||
//
|
||||
// r = obsDistance
|
||||
// d = sumRadius
|
||||
// p = vt + at^2 / 2
|
||||
// solve for: dot(p, toObsDir) = r
|
||||
// condition for no hit: abs(dot(p, toObsVec.rotate(90))) > d
|
||||
// p = (x, y)
|
||||
// toObsDir = (u, v)
|
||||
// ux + vy = r
|
||||
// x = v_x*t + a_x * t^2 / 2
|
||||
// y = v_y*t + a_y * t^2 / 2
|
||||
// u(v_x*t + 0.5*a_x*t^2) + v(v_y*t + 0.5*a_y*t^2) = r
|
||||
// t^2 * (0.5*(u*a_x + v*a_y)) + t * (u*v_x + v*v_y) - r = 0
|
||||
// k = 0.5 * u*a_x + v*a_y = 0.5 * dot(toObsDir, a)
|
||||
// l = u*v_x + v*v_y = dot(toObsDir, vel)
|
||||
// m = -r
|
||||
// t = (-l + sqrt(l^2 - 4km)) / (2k)
|
||||
// if 4km > l^2, no hit
|
||||
// if t<0, no hit
|
||||
//
|
||||
// https://www.desmos.com/calculator/foyraxlzs7 graphed version
|
||||
var l = Vector2.Dot(toObsDir, relVel);
|
||||
for (var i = 0; i < _sectors.Count; i++)
|
||||
{
|
||||
var sector = _sectors[i];
|
||||
|
||||
var accel = sector.Accel - obsAccel; // account for relative accel
|
||||
var accel = sector.Accel;
|
||||
var k = 0.5f * Vector2.Dot(toObsDir, accel);
|
||||
var m = -obsDistance;
|
||||
float t;
|
||||
if (k*k < l*l / 1024f)
|
||||
t = l != 0f ? -m / l : -1f;
|
||||
|
||||
// 1. Solve crossing the Front Tangent Plane (Entering the obstacle bounds)
|
||||
float t_f;
|
||||
if (k * k < l * l / 1024f)
|
||||
t_f = l != 0f ? obsDistanceFront / l : -1f;
|
||||
else
|
||||
t = 4*k*m > l*l || k == 0f ? -1f : ((-l + MathF.Sqrt(l*l - 4*k*m)) * 0.5f / k);
|
||||
if (t < 0f || t > simTime)
|
||||
{
|
||||
var desc_f = l * l + 4f * k * obsDistanceFront;
|
||||
t_f = desc_f < 0f || k == 0f ? -1f : ((-l + MathF.Sqrt(desc_f)) * 0.5f / k);
|
||||
}
|
||||
|
||||
if (t_f < 0f || t_f > simTime)
|
||||
continue;
|
||||
|
||||
t = MathF.Max(0f, t - ctx.FrameTime);
|
||||
// 2. Resolve longitudinal exit/stop trajectory
|
||||
Vector2 p_end;
|
||||
if (k * k < l * l / 1024f)
|
||||
{
|
||||
float t_c = l != 0f ? obsDistanceCenter / l : -1f;
|
||||
if (t_c < 0f) t_c = t_f; // Failsafe bounds
|
||||
p_end = relVel * t_c + 0.5f * accel * t_c * t_c;
|
||||
}
|
||||
else
|
||||
{
|
||||
var desc_c = l * l + 4f * k * obsDistanceCenter;
|
||||
if (desc_c < 0f)
|
||||
{
|
||||
// The ship stops longitudinally inside the front half of the obstacle
|
||||
var t_stop = -l / (2f * k);
|
||||
p_end = relVel * t_stop + 0.5f * accel * t_stop * t_stop;
|
||||
}
|
||||
else
|
||||
{
|
||||
var t_c = ((-l + MathF.Sqrt(desc_c)) * 0.5f / k);
|
||||
if (t_c < 0f) t_c = t_f; // Failsafe bounds
|
||||
p_end = relVel * t_c + 0.5f * accel * t_c * t_c;
|
||||
}
|
||||
}
|
||||
|
||||
var endAt = relVel*t + 0.5f*accel*t*t;
|
||||
var proj = MathF.Abs(Vector2.Dot(endAt, new Vector2(-toObsDir.Y, toObsDir.X)));
|
||||
// Log.Info($"Avoid dir {aDir} time {t}, proj {proj} (k l m {k} {l} {m}) accel {accel}");
|
||||
if (proj > sumRadius)
|
||||
// 3. Line-segment to Circle-Center intersection.
|
||||
// Represents exact path traveled while navigating across the physical dimension of the obstacle.
|
||||
var p_start = relVel * t_f + 0.5f * accel * t_f * t_f;
|
||||
var seg = p_end - p_start;
|
||||
var l2 = seg.LengthSquared();
|
||||
var hits = false;
|
||||
|
||||
if (l2 == 0f)
|
||||
{
|
||||
if ((p_start - toObsVec).LengthSquared() <= sumRadius * sumRadius)
|
||||
hits = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find closest point on the segment to the obstacle's actual center point
|
||||
var t_seg = Math.Clamp(Vector2.Dot(toObsVec - p_start, seg) / l2, 0f, 1f);
|
||||
var proj = p_start + seg * t_seg;
|
||||
if ((proj - toObsVec).LengthSquared() <= sumRadius * sumRadius)
|
||||
hits = true;
|
||||
}
|
||||
|
||||
if (!hits)
|
||||
continue;
|
||||
|
||||
var t = MathF.Max(0f, t_f - ctx.FrameTime);
|
||||
|
||||
var ctime = sector.ImpactTime;
|
||||
if ((ctime == null || ctime > t) && (!sector.Priority || obstacle.IsGrid))
|
||||
{
|
||||
@@ -444,7 +478,7 @@ public sealed partial class ShipSteeringSystem : EntitySystem
|
||||
var sector = _sectors[i];
|
||||
if (sector.ImpactTime == null)
|
||||
{
|
||||
var toWishSq = (wishDir - NormalizedOrZero(sector.Accel)).LengthSquared();
|
||||
var toWishSq = (wishDir - NormalizedOrZero(sector.Accel) * sector.Scale).LengthSquared();
|
||||
if (toWishSq < closestDistance)
|
||||
{
|
||||
closestDistance = toWishSq;
|
||||
@@ -488,21 +522,19 @@ public sealed partial class ShipSteeringSystem : EntitySystem
|
||||
if (brake.LeftoverBrakePath > destDistance)
|
||||
return -linVelDir;
|
||||
|
||||
// mirror linVelDir in relation to toTargetDir
|
||||
var adjustVec = -(linVelDir - toDestDir * Vector2.Dot(linVelDir, toDestDir));
|
||||
var adjustDir = NormalizedOrZero(adjustVec);
|
||||
|
||||
var wishThrustDir = toDestDir + 2f * adjustVec;
|
||||
|
||||
var wishThrustVec = _mover.GetWorldDirectionAccel(wishThrustDir, ctx.Shuttle, ctx.ShipBody, ctx.ShipXform);
|
||||
var adjustAccel = Vector2.Dot(adjustDir, wishThrustVec);
|
||||
|
||||
var maxAdjust = Vector2.Dot(-adjustDir, relVel);
|
||||
|
||||
adjustVec *= adjustAccel == 0f ? 0f : float.Clamp(maxAdjust / (adjustAccel * ctx.FrameTime), 0f, 1f);
|
||||
var accelEstVec = _mover.GetWorldDirectionAccel(toDestVec, ctx.Shuttle, ctx.ShipBody, ctx.ShipXform);
|
||||
var accelEst = accelEstVec.Length();
|
||||
// fallback to forward accel
|
||||
if (accelEst == 0f)
|
||||
{
|
||||
var forwardAccelVec = _mover.GetDirectionAccel(new Vector2(0f, 1f), ctx.Shuttle, ctx.ShipBody, ctx.ShipXform);
|
||||
accelEst = forwardAccelVec.Length();
|
||||
}
|
||||
// takes target relative to us
|
||||
var wishAngle = _seeking.CalculateAdvancedTracking(toDestVec, -relVel, accelEst);
|
||||
|
||||
// do not yet process whether we can actually accelerate well in that direction
|
||||
return toDestDir + 2f * adjustVec;
|
||||
return wishAngle.ToWorldVec();
|
||||
}
|
||||
|
||||
private readonly record struct RotationResult(float RotationInput, float WishAngleVel);
|
||||
|
||||
@@ -310,8 +310,6 @@ public sealed class TargetSeekingSystem : EntitySystem
|
||||
// see: https://github.com/Ilya246/orbitfight/blob/master/src/entities.cpp for original
|
||||
public Angle ApplyAdvancedTracking(Entity<TargetSeekingComponent, PhysicsComponent, TransformComponent> ent, Entity<PhysicsComponent, TransformComponent> target, float frameTime)
|
||||
{
|
||||
const int guidanceIterations = 3;
|
||||
|
||||
var accel = ent.Comp1.Acceleration;
|
||||
|
||||
var ownVel = _physics.GetMapLinearVelocity(ent, ent.Comp2, ent.Comp3);
|
||||
@@ -321,14 +319,17 @@ public sealed class TargetSeekingSystem : EntitySystem
|
||||
var relVel = targetVel - ownVel;
|
||||
var relPos = targetPos - ownPos;
|
||||
|
||||
var dVx = relVel.X;
|
||||
var dVy = relVel.Y;
|
||||
var dX = relPos.X;
|
||||
var dY = relPos.Y;
|
||||
var refRot = MathF.Atan2(dVy, dVx);
|
||||
var vel = dVx / MathF.Cos(refRot);
|
||||
var projX = dX * MathF.Cos(refRot) + dY * MathF.Sin(refRot);
|
||||
var projY = dY * MathF.Cos(refRot) - dX * MathF.Sin(refRot);
|
||||
return CalculateAdvancedTracking(relPos, relVel, accel);
|
||||
}
|
||||
|
||||
public Angle CalculateAdvancedTracking(Vector2 relPos, Vector2 relVel, float accel)
|
||||
{
|
||||
const int guidanceIterations = 3;
|
||||
|
||||
var vel = relVel.Length();
|
||||
var refVec = vel == 0f ? new Vector2(1f, 0f) : relVel / vel;
|
||||
var projX = Vector2.Dot(relPos, refVec);
|
||||
var projY = relPos.Y * refVec.X - relPos.X * refVec.Y;
|
||||
var itime = GuessInterceptTime(0f, -projX, -vel, projY, accel);
|
||||
for (var i = 0; i < guidanceIterations; i++)
|
||||
itime = GuessInterceptTime(itime, -projX, -vel, projY, accel);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Shared.DoAfter;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
|
||||
namespace Content.Server.Botany.Components;
|
||||
|
||||
@@ -12,14 +13,8 @@ public sealed partial class PlantAnalyzerComponent : Component
|
||||
[DataDefinition]
|
||||
public partial struct PlantAnalyzerSetting
|
||||
{
|
||||
[DataField]
|
||||
public bool AdvancedScan;
|
||||
|
||||
[DataField]
|
||||
public float ScanDelay;
|
||||
|
||||
[DataField]
|
||||
public float AdvScanDelay;
|
||||
}
|
||||
|
||||
[DataField, ViewVariables]
|
||||
@@ -30,4 +25,10 @@ public sealed partial class PlantAnalyzerComponent : Component
|
||||
|
||||
[DataField]
|
||||
public SoundSpecifier? ScanningEndSound;
|
||||
|
||||
[DataField]
|
||||
public EntityUid? ScannedEntity;
|
||||
|
||||
[DataField]
|
||||
public float MaxScanRange = 2.5f;
|
||||
}
|
||||
|
||||
@@ -1,37 +1,47 @@
|
||||
using Content.Server.Botany.Components;
|
||||
using Content.Server.PowerCell;
|
||||
using Content.Shared._NF.PlantAnalyzer;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared._NF.PlantAnalyzer;
|
||||
using Content.Shared.Interaction.Events;
|
||||
using Content.Shared.Item.ItemToggle;
|
||||
using Content.Shared.Item.ItemToggle.Components;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Content.Shared.Atmos;
|
||||
|
||||
namespace Content.Server.Botany.Systems;
|
||||
|
||||
public sealed class PlantAnalyzerSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly PowerCellSystem _cell = default!;
|
||||
[Dependency] private readonly ItemToggleSystem _toggle = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
|
||||
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
|
||||
[Dependency] private readonly TransformSystem _transformSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<PlantAnalyzerComponent, AfterInteractEvent>(OnAfterInteract);
|
||||
SubscribeLocalEvent<PlantAnalyzerComponent, PlantAnalyzerDoAfterEvent>(OnDoAfter);
|
||||
SubscribeLocalEvent<PlantAnalyzerComponent, PlantAnalyzerSetMode>(OnModeSelected);
|
||||
SubscribeLocalEvent<PlantAnalyzerComponent, EntGotInsertedIntoContainerMessage>(OnInsertedIntoContainer);
|
||||
SubscribeLocalEvent<PlantAnalyzerComponent, ItemToggledEvent>(OnToggled);
|
||||
SubscribeLocalEvent<PlantAnalyzerComponent, DroppedEvent>(OnDropped);
|
||||
Subs.BuiEvents<PlantAnalyzerComponent>(PlantAnalyzerUiKey.Key, subs => { subs.Event<BoundUIClosedEvent>(OnPlantAnalyzerUiClosed); });
|
||||
}
|
||||
|
||||
private TimeSpan _nextUpdate = TimeSpan.Zero;
|
||||
private TimeSpan _updateInterval = TimeSpan.FromSeconds(1);
|
||||
|
||||
private void OnAfterInteract(Entity<PlantAnalyzerComponent> ent, ref AfterInteractEvent args)
|
||||
{
|
||||
if (args.Target == null || !args.CanReach || !_cell.HasActivatableCharge(ent, user: args.User))
|
||||
if (args.Target == null || !args.CanReach)
|
||||
return;
|
||||
|
||||
if (ent.Comp.DoAfter != null)
|
||||
@@ -39,52 +49,66 @@ public sealed class PlantAnalyzerSystem : EntitySystem
|
||||
|
||||
if (HasComp<SeedComponent>(args.Target) || TryComp<PlantHolderComponent>(args.Target, out var plantHolder) && plantHolder.Seed != null)
|
||||
{
|
||||
var doAfterArgs = new DoAfterArgs(EntityManager, args.User, ent.Comp.Settings.ScanDelay,
|
||||
new PlantAnalyzerDoAfterEvent(), ent, target: args.Target, used: ent)
|
||||
{
|
||||
NeedHand = true,
|
||||
BreakOnDamage = true,
|
||||
BreakOnMove = true,
|
||||
MovementThreshold = 0.01f
|
||||
};
|
||||
|
||||
_doAfterSystem.TryStartDoAfter(doAfterArgs, out ent.Comp.DoAfter);
|
||||
|
||||
if (ent.Comp.Settings.AdvancedScan)
|
||||
{
|
||||
var doAfterArgs = new DoAfterArgs(EntityManager, args.User, ent.Comp.Settings.AdvScanDelay, new PlantAnalyzerDoAfterEvent(), ent, target: args.Target, used: ent)
|
||||
{
|
||||
NeedHand = true,
|
||||
BreakOnDamage = true,
|
||||
BreakOnMove = true,
|
||||
MovementThreshold = 0.01f
|
||||
};
|
||||
_doAfterSystem.TryStartDoAfter(doAfterArgs, out ent.Comp.DoAfter);
|
||||
}
|
||||
else
|
||||
{
|
||||
var doAfterArgs = new DoAfterArgs(EntityManager, args.User, ent.Comp.Settings.ScanDelay, new PlantAnalyzerDoAfterEvent(), ent, target: args.Target, used: ent)
|
||||
{
|
||||
NeedHand = true,
|
||||
BreakOnDamage = true,
|
||||
BreakOnMove = true,
|
||||
MovementThreshold = 0.01f
|
||||
};
|
||||
_doAfterSystem.TryStartDoAfter(doAfterArgs, out ent.Comp.DoAfter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDoAfter(Entity<PlantAnalyzerComponent> ent, ref PlantAnalyzerDoAfterEvent args)
|
||||
{
|
||||
ent.Comp.DoAfter = null;
|
||||
// Double charge use for advanced scan.
|
||||
if (ent.Comp.Settings.AdvancedScan)
|
||||
{
|
||||
if (!_cell.TryUseActivatableCharge(ent, user: args.User))
|
||||
return;
|
||||
}
|
||||
if (args.Handled || args.Cancelled || args.Args.Target == null || !_cell.TryUseActivatableCharge(ent.Owner, user: args.User))
|
||||
|
||||
if (args.Handled || args.Cancelled || args.Args.Target == null)
|
||||
return;
|
||||
|
||||
_audio.PlayPvs(ent.Comp.ScanningEndSound, ent);
|
||||
|
||||
ent.Comp.ScannedEntity = args.Args.Target.Value;
|
||||
_nextUpdate = TimeSpan.Zero;
|
||||
|
||||
_toggle.TryActivate(ent.Owner);
|
||||
OpenUserInterface(args.User, ent);
|
||||
UpdateScannedUser(ent, args.Args.Target.Value);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnPlantAnalyzerUiClosed(EntityUid uid, PlantAnalyzerComponent comp, BoundUIClosedEvent args)
|
||||
{
|
||||
if (!args.UiKey.Equals(PlantAnalyzerUiKey.Key))
|
||||
return;
|
||||
|
||||
if (!_uiSystem.IsUiOpen(uid, PlantAnalyzerUiKey.Key))
|
||||
_toggle.TryDeactivate(uid);
|
||||
}
|
||||
|
||||
private void OnInsertedIntoContainer(Entity<PlantAnalyzerComponent> uid, ref EntGotInsertedIntoContainerMessage args)
|
||||
{
|
||||
if (uid.Comp.ScannedEntity is { } target)
|
||||
_toggle.TryDeactivate(uid.Owner);
|
||||
}
|
||||
|
||||
private void OnDropped(Entity<PlantAnalyzerComponent> uid, ref DroppedEvent args)
|
||||
{
|
||||
if (uid.Comp.ScannedEntity is { } target)
|
||||
_toggle.TryDeactivate(uid.Owner);
|
||||
}
|
||||
|
||||
private void OnToggled(Entity<PlantAnalyzerComponent> uid, ref ItemToggledEvent args)
|
||||
{
|
||||
if (!args.Activated && uid.Comp.ScannedEntity is { } target)
|
||||
StopAnalyzingEntity(uid, target);
|
||||
}
|
||||
|
||||
|
||||
private void OpenUserInterface(EntityUid user, EntityUid analyzer)
|
||||
{
|
||||
if (!TryComp<ActorComponent>(user, out var actor) || !_uiSystem.HasUi(analyzer, PlantAnalyzerUiKey.Key))
|
||||
@@ -92,6 +116,40 @@ public sealed class PlantAnalyzerSystem : EntitySystem
|
||||
|
||||
_uiSystem.OpenUi(analyzer, PlantAnalyzerUiKey.Key, actor.PlayerSession);
|
||||
}
|
||||
private void StopAnalyzingEntity(Entity<PlantAnalyzerComponent> ent, EntityUid target)
|
||||
{
|
||||
ent.Comp.ScannedEntity = null;
|
||||
_uiSystem.CloseUi(ent.Owner, PlantAnalyzerUiKey.Key);
|
||||
_toggle.TryDeactivate(ent.Owner);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
|
||||
if (_nextUpdate < _updateInterval)
|
||||
{
|
||||
_nextUpdate += TimeSpan.FromSeconds(frameTime);
|
||||
return;
|
||||
}
|
||||
|
||||
var query = EntityQueryEnumerator<PlantAnalyzerComponent, TransformComponent>();
|
||||
while (query.MoveNext(out var uid, out var comp, out var analyzer))
|
||||
{
|
||||
if (comp.ScannedEntity is not { } target)
|
||||
continue;
|
||||
|
||||
if (!HasComp<SeedComponent>(target) && !HasComp<PlantHolderComponent>(target) ||
|
||||
!_transformSystem.InRange(Transform(target).Coordinates, analyzer.Coordinates, comp.MaxScanRange))
|
||||
{
|
||||
StopAnalyzingEntity((uid, comp), target);
|
||||
continue;
|
||||
}
|
||||
|
||||
UpdateScannedUser((uid, comp), target);
|
||||
}
|
||||
_nextUpdate -= _updateInterval;
|
||||
}
|
||||
|
||||
|
||||
public void UpdateScannedUser(Entity<PlantAnalyzerComponent> ent, EntityUid target)
|
||||
{
|
||||
@@ -102,12 +160,12 @@ public sealed class PlantAnalyzerSystem : EntitySystem
|
||||
{
|
||||
if (seedComp.Seed != null)
|
||||
{
|
||||
var state = ObtainingGeneDataSeed(seedComp.Seed, target, false, ent.Comp.Settings.AdvancedScan);
|
||||
var state = ObtainingGeneDataSeed(seedComp.Seed, target, false);
|
||||
_uiSystem.ServerSendUiMessage(ent.Owner, PlantAnalyzerUiKey.Key, state);
|
||||
}
|
||||
else if (seedComp.SeedId != null && _prototypeManager.TryIndex(seedComp.SeedId, out SeedPrototype? protoSeed))
|
||||
{
|
||||
var state = ObtainingGeneDataSeed(protoSeed, target, false, ent.Comp.Settings.AdvancedScan);
|
||||
var state = ObtainingGeneDataSeed(protoSeed, target, false);
|
||||
_uiSystem.ServerSendUiMessage(ent.Owner, PlantAnalyzerUiKey.Key, state);
|
||||
}
|
||||
}
|
||||
@@ -115,7 +173,7 @@ public sealed class PlantAnalyzerSystem : EntitySystem
|
||||
{
|
||||
if (plantComp.Seed != null)
|
||||
{
|
||||
var state = ObtainingGeneDataSeed(plantComp.Seed, target, true, ent.Comp.Settings.AdvancedScan);
|
||||
var state = ObtainingGeneDataSeed(plantComp.Seed, target, true);
|
||||
_uiSystem.ServerSendUiMessage(ent.Owner, PlantAnalyzerUiKey.Key, state);
|
||||
}
|
||||
}
|
||||
@@ -124,7 +182,7 @@ public sealed class PlantAnalyzerSystem : EntitySystem
|
||||
/// <summary>
|
||||
/// Analysis of seed from prototype.
|
||||
/// </summary>
|
||||
public PlantAnalyzerScannedSeedPlantInformation ObtainingGeneDataSeed(SeedData seedData, EntityUid target, bool isTray, bool scanIsAdvanced)
|
||||
public PlantAnalyzerScannedSeedPlantInformation ObtainingGeneDataSeed(SeedData seedData, EntityUid target, bool isTray)
|
||||
{
|
||||
// Get trickier fields first.
|
||||
AnalyzerHarvestType harvestType = AnalyzerHarvestType.Unknown;
|
||||
@@ -169,29 +227,21 @@ public sealed class PlantAnalyzerSystem : EntitySystem
|
||||
Production = seedData.Production,
|
||||
GrowthStages = seedData.GrowthStages,
|
||||
SeedPotency = seedData.Potency,
|
||||
Speciation = mutationStrings.ToArray()
|
||||
Speciation = mutationStrings.ToArray(),
|
||||
NutrientConsumption = seedData.NutrientConsumption,
|
||||
WaterConsumption = seedData.WaterConsumption,
|
||||
IdealHeat = seedData.IdealHeat,
|
||||
HeatTolerance = seedData.HeatTolerance,
|
||||
IdealLight = seedData.IdealLight,
|
||||
LightTolerance = seedData.LightTolerance,
|
||||
ToxinsTolerance = seedData.ToxinsTolerance,
|
||||
LowPressureTolerance = seedData.LowPressureTolerance,
|
||||
HighPressureTolerance = seedData.HighPressureTolerance,
|
||||
PestTolerance = seedData.PestTolerance,
|
||||
WeedTolerance = seedData.WeedTolerance,
|
||||
Mutations = GetMutationFlags(seedData)
|
||||
};
|
||||
|
||||
if (scanIsAdvanced)
|
||||
{
|
||||
AdvancedScanInfo advancedInfo = new()
|
||||
{
|
||||
NutrientConsumption = seedData.NutrientConsumption,
|
||||
WaterConsumption = seedData.WaterConsumption,
|
||||
IdealHeat = seedData.IdealHeat,
|
||||
HeatTolerance = seedData.HeatTolerance,
|
||||
IdealLight = seedData.IdealLight,
|
||||
LightTolerance = seedData.LightTolerance,
|
||||
ToxinsTolerance = seedData.ToxinsTolerance,
|
||||
LowPressureTolerance = seedData.LowPressureTolerance,
|
||||
HighPressureTolerance = seedData.HighPressureTolerance,
|
||||
PestTolerance = seedData.PestTolerance,
|
||||
WeedTolerance = seedData.WeedTolerance,
|
||||
Mutations = GetMutationFlags(seedData)
|
||||
};
|
||||
|
||||
ret.AdvancedInfo = advancedInfo;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -202,6 +252,7 @@ public sealed class PlantAnalyzerSystem : EntitySystem
|
||||
if (plant.Seedless || plant.PermanentlySeedless) ret |= MutationFlags.Seedless;
|
||||
if (plant.Ligneous) ret |= MutationFlags.Ligneous;
|
||||
if (plant.CanScream) ret |= MutationFlags.CanScream;
|
||||
if (!plant.Viable) ret |= MutationFlags.Unviable;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -245,15 +296,4 @@ public sealed class PlantAnalyzerSystem : EntitySystem
|
||||
return gasFlags;
|
||||
}
|
||||
|
||||
private void OnModeSelected(Entity<PlantAnalyzerComponent> ent, ref PlantAnalyzerSetMode args)
|
||||
{
|
||||
SetMode(ent, args.AdvancedScan);
|
||||
}
|
||||
|
||||
public void SetMode(Entity<PlantAnalyzerComponent> ent, bool isAdvMode)
|
||||
{
|
||||
if (ent.Comp.DoAfter != null)
|
||||
return;
|
||||
ent.Comp.Settings.AdvancedScan = isAdvMode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,45 +45,44 @@ public sealed partial class IdCardConsoleComponent : Component
|
||||
[DataField, AutoNetworkedField]
|
||||
public List<ProtoId<AccessLevelPrototype>> AccessLevels = new()
|
||||
{
|
||||
"Armory",
|
||||
//"Atmospherics",
|
||||
"Bailiff", // Frontier
|
||||
//"Bar",
|
||||
"Brig",
|
||||
"Detective",
|
||||
"Captain",
|
||||
//"Cargo",
|
||||
//"Chapel",
|
||||
//"Chemistry",
|
||||
//"ChiefEngineer",
|
||||
//"ChiefMedicalOfficer",
|
||||
"Command",
|
||||
//"Cryogenics",
|
||||
//"Engineering",
|
||||
"External",
|
||||
"Frontier", // Frontier
|
||||
"HeadOfPersonnel",
|
||||
"HeadOfSecurity",
|
||||
//"Hydroponics",
|
||||
"Janitor",
|
||||
//"Kitchen",
|
||||
"Lawyer",
|
||||
"Mail", // Frontier
|
||||
"Maintenance",
|
||||
"Medical",
|
||||
"Mercenary", // Frontier
|
||||
//"Quartermaster",
|
||||
//"Research",
|
||||
//"ResearchDirector",
|
||||
//"Salvage",
|
||||
"Security",
|
||||
"Sergeant", // Frontier
|
||||
"Service",
|
||||
"StationTrafficController", // Frontier
|
||||
//"USSP", // Mono
|
||||
//"USSPHigh", // Mono
|
||||
//"USSPCommand", // Mono
|
||||
//"Theatre",
|
||||
"Armory", //Used by TSF, unknown purpose
|
||||
//"Atmospherics",
|
||||
//"Bar",
|
||||
"Brig",
|
||||
"Detective",
|
||||
"Captain",
|
||||
//"Cargo",
|
||||
//"Chapel",
|
||||
//"Chemistry",
|
||||
"Chemistry", // DO NOT HIDE, it prevents all cards with chemistry from getting additional access (Ex: TSF Captain)
|
||||
//"ChiefEngineer",
|
||||
//"ChiefMedicalOfficer",
|
||||
"ChiefMedicalOfficer", //DO NOT HIDE, required for DOC
|
||||
"Command",
|
||||
//"Cryogenics",
|
||||
//"Engineering",
|
||||
"External",
|
||||
"HeadOfPersonnel",
|
||||
//"Hydroponics",
|
||||
"Janitor",
|
||||
//"Kitchen",
|
||||
//"ResearchDirector",
|
||||
//"Salvage",
|
||||
"Security",
|
||||
"Service",
|
||||
"StationTrafficController", // Frontier
|
||||
//"USSP", // Mono
|
||||
//"USSPHigh", // Mono
|
||||
//"USSPCommand", // Mono
|
||||
//"Theatre",
|
||||
"Frontier", // Frontier //TSF Base access
|
||||
"Sergeant", // Frontier //TSF FTL access
|
||||
"Bailiff", // Frontier //TSF Command access
|
||||
"TsfmcEngineering", // Mono, TSF Engineering access
|
||||
"HeadOfSecurity", // TSF Colonel
|
||||
"Pirate", //Frontier //PDV base access
|
||||
"PDVCommand", //Mono, PDV leadership (Denasvar, Asvaran, Vizier)
|
||||
"GrandVizier",//Mono, PDV Vizier
|
||||
};
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Shared.Clothing.EntitySystems;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization;
|
||||
@@ -76,6 +77,19 @@ public sealed partial class ClothingComponent : Component
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public TimeSpan StripDelay = TimeSpan.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// Mono: Whitelist required to wear clothing. Checks the wearer for whitelist.
|
||||
/// Also checks organs for required components/tags if WhitelistCheckOrgan is true.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntityWhitelist? Whitelist = null;
|
||||
|
||||
/// <summary>
|
||||
/// Mono: Whether we should check organs for the whitelist in addition to the target.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool WhitelistCheckOrgans = false;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
|
||||
@@ -22,4 +22,10 @@ public sealed partial class MagbootsComponent : Component
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string Slot = "shoes";
|
||||
|
||||
/// <summary>
|
||||
/// Goobstation - EquippedPrefix for enabled state
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string? EnabledPrefix = "on";
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public sealed class SharedMagbootsSystem : EntitySystem
|
||||
UpdateMagbootEffects(container.Owner, ent, args.Activated);
|
||||
}
|
||||
|
||||
var prefix = args.Activated ? "on" : null;
|
||||
var prefix = args.Activated ? ent.Comp.EnabledPrefix : null; // Goob edit
|
||||
_item.SetHeldPrefix(ent, prefix);
|
||||
_clothing.SetEquippedPrefix(ent, prefix);
|
||||
}
|
||||
@@ -68,6 +68,10 @@ public sealed class SharedMagbootsSystem : EntitySystem
|
||||
_alerts.ShowAlert(user, ent.Comp.MagbootsAlert);
|
||||
else
|
||||
_alerts.ClearAlert(user, ent.Comp.MagbootsAlert);
|
||||
|
||||
// Mono
|
||||
var ev = new MagbootsToggledEvent(ent.Owner, state);
|
||||
RaiseLocalEvent(user, ref ev);
|
||||
}
|
||||
|
||||
private void OnIsWeightless(Entity<MagbootsComponent> ent, ref IsWeightlessEvent args)
|
||||
@@ -88,3 +92,6 @@ public sealed class SharedMagbootsSystem : EntitySystem
|
||||
OnIsWeightless(ent, ref args.Args);
|
||||
}
|
||||
}
|
||||
|
||||
[ByRefEvent]
|
||||
public record struct MagbootsToggledEvent(EntityUid Magboots, bool State); // Mono
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared.Armor;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Body.Systems;
|
||||
using Content.Shared.Clothing.Components;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Hands;
|
||||
@@ -35,6 +37,7 @@ public abstract partial class InventorySystem
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
[Dependency] private readonly SharedStrippableSystem _strippable = default!;
|
||||
[Dependency] private readonly SharedBodySystem _body = default!; // Mono
|
||||
|
||||
[ValidatePrototypeId<ItemSizePrototype>]
|
||||
private const string PocketableItemSize = "Small";
|
||||
@@ -281,6 +284,14 @@ public abstract partial class InventorySystem
|
||||
return false;
|
||||
}
|
||||
|
||||
// Mono: Clothing whitelists
|
||||
if (clothing != null && IsFailWhitelistClothing(itemUid, target, clothing))
|
||||
{
|
||||
reason = "inventory-component-can-equip-does-not-fit";
|
||||
return false;
|
||||
}
|
||||
// Mono End
|
||||
|
||||
var attemptEvent = new IsEquippingAttemptEvent(actor, target, itemUid, slotDefinition);
|
||||
RaiseLocalEvent(target, attemptEvent, true);
|
||||
if (attemptEvent.Cancelled)
|
||||
@@ -311,6 +322,26 @@ public abstract partial class InventorySystem
|
||||
return true;
|
||||
}
|
||||
|
||||
// Mono: Clothing whitelists
|
||||
public bool IsFailWhitelistClothing(EntityUid itemUid, EntityUid target, ClothingComponent clothing)
|
||||
{
|
||||
if (clothing.WhitelistCheckOrgans && TryComp<BodyComponent>(target, out var body))
|
||||
{
|
||||
var organs = _body.GetBodyOrgans(target, body);
|
||||
|
||||
foreach ((var id, var _) in organs)
|
||||
{
|
||||
if (_whitelistSystem.IsWhitelistPassOrNull(clothing.Whitelist, id))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_whitelistSystem.IsWhitelistFail(clothing.Whitelist, target))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryUnequip(
|
||||
EntityUid uid,
|
||||
string slot,
|
||||
|
||||
@@ -184,14 +184,17 @@ namespace Content.Shared.Lathe
|
||||
private static int NextIndex = 0; // Mono
|
||||
public int Index; // Mono - for de-queuing recipes to work properly
|
||||
public LatheRecipePrototype Recipe;
|
||||
public NetEntity? Actor; // Mono - Log the person who queued the recipe.
|
||||
public int ItemsPrinted;
|
||||
public int ItemsRequested;
|
||||
|
||||
public LatheRecipeBatch(LatheRecipePrototype recipe, int itemsPrinted, int itemsRequested)
|
||||
public LatheRecipeBatch(LatheRecipePrototype recipe, int itemsPrinted, int itemsRequested,
|
||||
NetEntity? actor) // Mono
|
||||
{
|
||||
Recipe = recipe;
|
||||
ItemsPrinted = itemsPrinted;
|
||||
ItemsRequested = itemsRequested;
|
||||
Actor = actor; // Mono
|
||||
Index = NextIndex++; // Mono
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,6 +384,10 @@ public abstract class SharedMechSystem : EntitySystem
|
||||
if (!Resolve(uid, ref component))
|
||||
return false;
|
||||
|
||||
// Mono: Ensures mechs can't be entered if broken
|
||||
if (component.Broken)
|
||||
return false;
|
||||
|
||||
return IsEmpty(component) && _actionBlocker.CanMove(toInsert);
|
||||
}
|
||||
|
||||
@@ -589,7 +593,7 @@ public abstract class SharedMechSystem : EntitySystem
|
||||
{
|
||||
args.Handled = true;
|
||||
|
||||
args.CanDrop |= !component.Broken && CanInsert(uid, args.Dragged, component);
|
||||
args.CanDrop |= CanInsert(uid, args.Dragged, component); // Mono: moved mech broken check to CanInsert
|
||||
}
|
||||
//private void OnEmagged(EntityUid uid, MechComponent component, ref GotEmaggedEvent args) // Goobstation
|
||||
//{
|
||||
|
||||
@@ -10,6 +10,7 @@ using Robust.Shared.Containers;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Physics.Systems;
|
||||
using Robust.Shared.Serialization;
|
||||
using Content.Shared.Clothing; // Mono
|
||||
|
||||
namespace Content.Shared.Movement.Systems;
|
||||
|
||||
@@ -22,6 +23,7 @@ public abstract class SharedJetpackSystem : EntitySystem
|
||||
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
||||
[Dependency] private readonly ActionContainerSystem _actionContainer = default!;
|
||||
[Dependency] private readonly IConfigurationManager _config = default!; // EE
|
||||
[Dependency] private readonly SharedGravitySystem _gravity = default!; // Mono
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -32,6 +34,7 @@ public abstract class SharedJetpackSystem : EntitySystem
|
||||
|
||||
SubscribeLocalEvent<JetpackUserComponent, RefreshWeightlessModifiersEvent>(OnJetpackUserWeightlessMovement);
|
||||
SubscribeLocalEvent<JetpackUserComponent, CanWeightlessMoveEvent>(OnJetpackUserCanWeightless);
|
||||
SubscribeLocalEvent<JetpackUserComponent, MagbootsToggledEvent>(OnJetpackUserMagbootsToggled); // Mono
|
||||
SubscribeLocalEvent<JetpackUserComponent, EntParentChangedMessage>(OnJetpackUserEntParentChanged);
|
||||
SubscribeLocalEvent<JetpackComponent, EntGotInsertedIntoContainerMessage>(OnJetpackMoved);
|
||||
|
||||
@@ -119,7 +122,8 @@ public abstract class SharedJetpackSystem : EntitySystem
|
||||
// https://discord.com/channels/310555209753690112/310555209753690112/1270067921682694234
|
||||
if (TryComp<JetpackComponent>(component.Jetpack, out var jetpack)
|
||||
&& (!CanEnableOnGrid(args.Transform.GridUid)
|
||||
|| !UserNotParented(uid, jetpack))) // EE
|
||||
|| !UserNotParented(uid, jetpack) // EE
|
||||
|| !_gravity.IsWeightless(uid))) // Mono
|
||||
{
|
||||
SetEnabled(component.Jetpack, jetpack, false, uid);
|
||||
|
||||
@@ -161,7 +165,8 @@ public abstract class SharedJetpackSystem : EntitySystem
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (TryComp(uid, out TransformComponent? xform) && !CanEnableOnGrid(xform.GridUid))
|
||||
if (TryComp(uid, out TransformComponent? xform) && !CanEnableOnGrid(xform.GridUid)
|
||||
|| !_gravity.IsWeightless(args.Performer)) // Mono
|
||||
{
|
||||
_popup.PopupClient(Loc.GetString("jetpack-no-station"), uid, args.Performer);
|
||||
|
||||
@@ -234,7 +239,7 @@ public abstract class SharedJetpackSystem : EntitySystem
|
||||
|
||||
protected virtual bool CanEnable(EntityUid uid, JetpackComponent component)
|
||||
{
|
||||
return true;
|
||||
return _gravity.IsWeightless(uid); // Mono
|
||||
}
|
||||
|
||||
// EE: check parent
|
||||
@@ -245,6 +250,17 @@ public abstract class SharedJetpackSystem : EntitySystem
|
||||
|| xform.ParentUid == xform.MapUid;
|
||||
}
|
||||
// End EE
|
||||
|
||||
// Mono
|
||||
private void OnJetpackUserMagbootsToggled(EntityUid uid, JetpackUserComponent component, ref MagbootsToggledEvent args)
|
||||
{
|
||||
if (!args.State || !IsEnabled(component.Jetpack) || _gravity.IsWeightless(uid) || !TryComp<JetpackComponent>(component.Jetpack, out var jetpack))
|
||||
return;
|
||||
|
||||
_popup.PopupClient(Loc.GetString("jetpack-to-grid"), uid, uid);
|
||||
SetEnabled(component.Jetpack, jetpack, false, uid);
|
||||
}
|
||||
// End Mono
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
|
||||
@@ -69,4 +69,10 @@ public sealed partial class RCDComponent : Component
|
||||
/// </remarks>
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
public Transform ConstructionTransform { get; private set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Mono - delay multiplier for the RCD
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public float DelayMultiplier = 1f;
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ public class RCDSystem : EntitySystem
|
||||
// </Mono>
|
||||
var ev = new RCDDoAfterEvent(GetNetCoordinates(mapGridData.Value.Location), component.ConstructionDirection, component.ProtoId, cost, EntityManager.GetNetEntity(effect));
|
||||
|
||||
var doAfterArgs = new DoAfterArgs(EntityManager, user, delay, ev, uid, target: args.Target, used: uid)
|
||||
var doAfterArgs = new DoAfterArgs(EntityManager, user, delay*component.DelayMultiplier, ev, uid, target: args.Target, used: uid) // Mono - add delay multiplier.
|
||||
{
|
||||
BreakOnDamage = true,
|
||||
BreakOnHandChange = true,
|
||||
|
||||
@@ -21,8 +21,6 @@ public sealed class NavInterfaceState
|
||||
|
||||
public Dictionary<NetEntity, List<DockingPortState>> Docks;
|
||||
|
||||
public bool RotateWithEntity = true;
|
||||
|
||||
/// <summary>
|
||||
/// Custom display names for network port buttons.
|
||||
/// Key is the port ID, value is the display name.
|
||||
@@ -46,18 +44,13 @@ public sealed class NavInterfaceState
|
||||
public bool HideCoords = false;
|
||||
// End Frontier fields
|
||||
|
||||
public bool Pannable = true; // Mono
|
||||
public bool RelativePanning = false; // Mono
|
||||
|
||||
public NavInterfaceState(
|
||||
float maxRange,
|
||||
NetCoordinates? coordinates,
|
||||
Angle? angle,
|
||||
Dictionary<NetEntity, List<DockingPortState>> docks,
|
||||
InertiaDampeningMode dampeningMode, // Frontier: add dampeningMode
|
||||
Dictionary<string, string>? networkPortNames = null,
|
||||
bool pannable = true, // Mono
|
||||
bool relativePan = false) // Mono
|
||||
Dictionary<string, string>? networkPortNames = null)
|
||||
{
|
||||
MaxRange = maxRange;
|
||||
Coordinates = coordinates;
|
||||
@@ -65,8 +58,6 @@ public sealed class NavInterfaceState
|
||||
Docks = docks;
|
||||
DampeningMode = dampeningMode; // Frontier
|
||||
NetworkPortNames = networkPortNames ?? new Dictionary<string, string>();
|
||||
Pannable = pannable; // Mono
|
||||
RelativePanning = relativePan; // Mono
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,26 @@ public sealed partial class RadarConsoleComponent : Component
|
||||
[DataField]
|
||||
public bool Pannable = true;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to still follow the console after being panned.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool RelativePanning = false;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to always face north-up.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool NoRotate = false;
|
||||
|
||||
// supported behavior modes:
|
||||
// | panned | unpanned | panned | unpanned | bool |
|
||||
// | rotation | rotation | anchor | anchor | settings |
|
||||
// |----------|----------|----------|----------|----------|
|
||||
// | north | north | follow | static | 00 |
|
||||
// | north | follow | static | follow | 01 |
|
||||
// | follow | follow | follow | follow | 10 |
|
||||
// | north | north | follow | follow | 11 |
|
||||
|
||||
// </Mono>
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@ public abstract class SharedDockingSystem : EntitySystem
|
||||
if (shuttle == null)
|
||||
return false;
|
||||
|
||||
if (TryComp<FTLComponent>(shuttle, out var ftl) && (ftl.State & (FTLState.Starting | FTLState.Travelling | FTLState.Arriving)) != 0)
|
||||
return false;
|
||||
|
||||
return !HasComp<PreventPilotComponent>(shuttle.Value);
|
||||
}
|
||||
|
||||
|
||||
@@ -300,6 +300,12 @@ public sealed partial class GunComponent : Component
|
||||
[DataField]
|
||||
public Angle MuzzleFlashRotationOffset;
|
||||
|
||||
/// <summary>
|
||||
/// This multiplier will apply per projectile fired by the weapon.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float DamageModifier = 1f;
|
||||
|
||||
/// <summary>
|
||||
/// Mono
|
||||
/// Recoil to incur per ammo shot, kg*m/s.
|
||||
|
||||
@@ -18,6 +18,11 @@ public abstract partial class SharedGunSystem
|
||||
{
|
||||
args.PushMarkup(Loc.GetString("gun-selected-mode-examine", ("color", ModeExamineColor),
|
||||
("mode", GetLocSelector(component.SelectedMode))));
|
||||
|
||||
if (component.DamageModifier != 1f)
|
||||
args.PushMarkup(Loc.GetString("gun-damage-modifier-examine", ("color", FireRateExamineColor),
|
||||
("damage", $"{component.DamageModifier.ToString("#.##")}")));
|
||||
|
||||
//args.PushMarkup(Loc.GetString("gun-fire-rate-examine", ("color", FireRateExamineColor), // Emberfall
|
||||
// ("fireRate", $"{component.FireRateModified:0.0}"))); // Emberfall
|
||||
}
|
||||
|
||||
@@ -592,6 +592,26 @@ public abstract partial class SharedGunSystem : EntitySystem
|
||||
return cartridge;
|
||||
}
|
||||
|
||||
// Mono
|
||||
public DamageSpecifier GetNextDamage(Entity<GunComponent?> gun)
|
||||
{
|
||||
if (!TryNextShootPrototype(gun, out var shoot))
|
||||
return new();
|
||||
|
||||
return GetBulletDamage(shoot);
|
||||
}
|
||||
|
||||
// Mono
|
||||
public DamageSpecifier GetBulletDamage(EntityPrototype bullet)
|
||||
{
|
||||
var shoot = GetBulletPrototype(bullet);
|
||||
if (shoot.TryGetComponent<HitscanBasicDamageComponent>(out var hitscan, Factory))
|
||||
return hitscan.Damage;
|
||||
if (shoot.TryGetComponent<ProjectileComponent>(out var proj, Factory))
|
||||
return proj.Damage;
|
||||
return new();
|
||||
}
|
||||
|
||||
// Mono - used for multiple-per-frame projectile offset
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Content.Shared.Store;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._Mono.Company;
|
||||
@@ -46,4 +47,11 @@ public sealed partial class CompanyPrototype : IPrototype
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string? Image { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The (typically Uplink) Currency Prototype bound to the Company.
|
||||
/// Used for handling printing contraband items.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public ProtoId<CurrencyPrototype>? CompanyUplinkCurrency { get; private set; }
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
using Content.Shared._Mono.Company; // Mono
|
||||
using Content.Shared.Contraband;
|
||||
using Content.Shared.Store; // Mono
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Prototypes; // Mono
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._NF.Contraband;
|
||||
@@ -12,6 +15,8 @@ public enum ContrabandPalletConsoleUiKey : byte
|
||||
|
||||
public abstract class SharedContrabandTurnInSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prot = default!;
|
||||
|
||||
public void ClearContrabandValue(EntityUid item)
|
||||
{
|
||||
// Clear contraband value for printed items
|
||||
@@ -35,4 +40,48 @@ public abstract class SharedContrabandTurnInSystem : EntitySystem
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mono: Remove Contraband currencies selectively
|
||||
public void HandleContrabandValueByCompany(EntityUid item, EntityUid? actor)
|
||||
{
|
||||
// Get the company of the person who queued the item. Checks for valid company prototype, as well as an uplink currency attached to the company.
|
||||
if (!TryComp<CompanyComponent>(actor, out var company)
|
||||
|| !_prot.Resolve(company.CompanyName, out var companyProto)
|
||||
|| companyProto.CompanyUplinkCurrency is not { } currency)
|
||||
{
|
||||
// Otherwise just remove all contraband rewards.
|
||||
ClearContrabandValue(item);
|
||||
return;
|
||||
}
|
||||
|
||||
CleanContrabandValueByCompany(item, currency);
|
||||
}
|
||||
|
||||
private void CleanContrabandValueByCompany(EntityUid item, ProtoId<CurrencyPrototype> currency)
|
||||
{
|
||||
// Clear contraband value for printed items
|
||||
if (TryComp<ContrabandComponent>(item, out var contraband))
|
||||
{
|
||||
foreach (var valueKey in contraband.TurnInValues.Keys)
|
||||
{
|
||||
// For faction members, remove the contra reward of your faction and keep contra rewards of other factions.
|
||||
if (valueKey.Id != currency.Id)
|
||||
continue;
|
||||
|
||||
contraband.TurnInValues[valueKey] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Recurse into contained entities
|
||||
if (TryComp<ContainerManagerComponent>(item, out var containers))
|
||||
{
|
||||
foreach (var container in containers.Containers.Values)
|
||||
{
|
||||
foreach (var ent in container.ContainedEntities)
|
||||
{
|
||||
CleanContrabandValueByCompany(ent, currency);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,28 +11,20 @@ public sealed class PlantAnalyzerScannedSeedPlantInformation : BoundUserInterfac
|
||||
public NetEntity? TargetEntity;
|
||||
public bool IsTray;
|
||||
|
||||
//Basic tab
|
||||
public string? SeedName;
|
||||
public string[]? SeedChem;
|
||||
public AnalyzerHarvestType HarvestType;
|
||||
public GasFlags ExudeGases;
|
||||
public GasFlags ConsumeGases;
|
||||
public float Endurance;
|
||||
public int SeedYield;
|
||||
public float SeedPotency;
|
||||
public AnalyzerHarvestType HarvestType;
|
||||
public float Lifespan;
|
||||
public float Maturation;
|
||||
public float Production;
|
||||
public int GrowthStages;
|
||||
public float SeedPotency;
|
||||
public string[]? Speciation; // Currently only available on server, we need to send strings to the client.
|
||||
public AdvancedScanInfo? AdvancedInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Information gathered in an advanced scan.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public struct AdvancedScanInfo
|
||||
{
|
||||
public float Endurance;
|
||||
public GasFlags ConsumeGases;
|
||||
public GasFlags ExudeGases;
|
||||
public string[]? SeedChem;
|
||||
//Tolerances tab
|
||||
public float NutrientConsumption;
|
||||
public float WaterConsumption;
|
||||
public float IdealHeat;
|
||||
@@ -44,6 +36,8 @@ public struct AdvancedScanInfo
|
||||
public float HighPressureTolerance;
|
||||
public float PestTolerance;
|
||||
public float WeedTolerance;
|
||||
//Mutations tab
|
||||
public string[]? Speciation; // Currently only available on server, we need to send strings to the client.
|
||||
public MutationFlags Mutations;
|
||||
}
|
||||
|
||||
@@ -56,6 +50,7 @@ public enum MutationFlags : byte
|
||||
Seedless = 2,
|
||||
Ligneous = 4,
|
||||
CanScream = 8,
|
||||
Unviable = 16,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
@@ -80,14 +75,3 @@ public enum AnalyzerHarvestType : byte
|
||||
NoRepeat,
|
||||
SelfHarvest
|
||||
}
|
||||
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class PlantAnalyzerSetMode : BoundUserInterfaceMessage
|
||||
{
|
||||
public bool AdvancedScan { get; }
|
||||
public PlantAnalyzerSetMode(bool advancedScan)
|
||||
{
|
||||
AdvancedScan = advancedScan;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19552,3 +19552,561 @@ Entries:
|
||||
id: 2156
|
||||
time: '2026-04-09T17:22:37.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3734
|
||||
- author: Redrover1760
|
||||
changes:
|
||||
- type: Fix
|
||||
message: Fixed oversights from ship HP changes.
|
||||
id: 2157
|
||||
time: '2026-04-09T17:40:26.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3735
|
||||
- author: Redrover1760
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: 12 gauge damage buff
|
||||
id: 2158
|
||||
time: '2026-04-09T18:21:28.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3528
|
||||
- author: Onezero0
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: Ported the ability for guns to have damage modifiers.
|
||||
id: 2159
|
||||
time: '2026-04-09T21:23:05.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3731
|
||||
- author: Ilya246
|
||||
changes:
|
||||
- type: Fix
|
||||
message: >-
|
||||
Fixed ship AI sitting around doing nothing when missing thrust
|
||||
directions, in particular, on Medusa.
|
||||
id: 2160
|
||||
time: '2026-04-10T10:18:45.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3743
|
||||
- author: tonotom1
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: >-
|
||||
Plant Analyzer QOL: No longer needs charging, can identify unviable
|
||||
mutation, no longer needs advanced scan, added a scrollbar for
|
||||
displaying many chems, made the scanner update in realtime, reduced scan
|
||||
time to match health analyzer (0.8s), simplified jargon words in
|
||||
attributes
|
||||
id: 2161
|
||||
time: '2026-04-10T12:25:02.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3586
|
||||
- author: AntoineXYZ
|
||||
changes:
|
||||
- type: Fix
|
||||
message: Fixed chat highlighting not working for radio messages
|
||||
id: 2162
|
||||
time: '2026-04-10T12:39:07.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3711
|
||||
- author: Ilya246
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: Gunnery console radar screens now always face north-up.
|
||||
id: 2163
|
||||
time: '2026-04-10T14:49:46.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3705
|
||||
- author: Ilya246
|
||||
changes:
|
||||
- type: Fix
|
||||
message: Potentially reduced autopilot/ship AI grid collision likelihood.
|
||||
id: 2164
|
||||
time: '2026-04-10T15:16:43.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3745
|
||||
- author: Ilya246
|
||||
changes:
|
||||
- type: Fix
|
||||
message: Fixed RSC company being unselectable.
|
||||
id: 2165
|
||||
time: '2026-04-10T18:58:20.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3746
|
||||
- author: Ilya246
|
||||
changes:
|
||||
- type: Fix
|
||||
message: >-
|
||||
Gunnery console rotation is no longer always north. Also fixed mech and
|
||||
other mass scanners.
|
||||
id: 2166
|
||||
time: '2026-04-11T06:05:04.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3748
|
||||
- author: Ilya246
|
||||
changes:
|
||||
- type: Fix
|
||||
message: Fixed shipguns sometimes not firing where you aim.
|
||||
id: 2167
|
||||
time: '2026-04-11T08:47:32.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3749
|
||||
- author: Ilya246
|
||||
changes:
|
||||
- type: Fix
|
||||
message: Guns on mechs or people now properly inherit velocity of the shooter.
|
||||
- type: Fix
|
||||
message: 'Fixed gunnery console on non-1x UI scale. '
|
||||
id: 2168
|
||||
time: '2026-04-11T15:45:12.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3753
|
||||
- author: Ilya246
|
||||
changes:
|
||||
- type: Fix
|
||||
message: >-
|
||||
Explosive shipgun projectiles no longer sink their explosion into one
|
||||
wall.
|
||||
id: 2169
|
||||
time: '2026-04-11T20:32:01.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3756
|
||||
- author: Ilya246
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: Made acceleration scaling affect low velocities less.
|
||||
- type: Fix
|
||||
message: >-
|
||||
Fixed oversight making ships 2x slower to accelerate in their velocity
|
||||
direction than intended.
|
||||
id: 2170
|
||||
time: '2026-04-12T09:27:05.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3764
|
||||
- author: Ilya246
|
||||
changes:
|
||||
- type: Fix
|
||||
message: You can no longer dock to grids while charging up FTL.
|
||||
id: 2171
|
||||
time: '2026-04-12T10:10:05.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3765
|
||||
- author: doublechest
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: Cargo order capacity in the Trade Mall was increased from 20 to 60
|
||||
id: 2172
|
||||
time: '2026-04-12T16:16:54.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3766
|
||||
- author: lopsidedmanboobs
|
||||
changes:
|
||||
- type: Add
|
||||
message: >-
|
||||
Congratulations! Any ships entering a 512 meter range of active combat
|
||||
do not require escalation and can be fired upon instantly now. Review
|
||||
Conflict Rule 1 for more information.
|
||||
id: 2173
|
||||
time: '2026-04-13T09:48:20.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3778
|
||||
- author: Corrupt142
|
||||
changes:
|
||||
- type: Remove
|
||||
message: the last Flashpoint has been shot dead in the colossus sector!
|
||||
id: 2174
|
||||
time: '2026-04-13T12:55:26.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3767
|
||||
- author: iramoye
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: >-
|
||||
The 'Expanding and Repairing Station' subsection of the 'Engineering'
|
||||
guidebook now mentions maintenance jacks as valid plating removal tools.
|
||||
id: 2175
|
||||
time: '2026-04-13T14:15:41.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3780
|
||||
- author: ToastEnjoyer
|
||||
changes:
|
||||
- type: Fix
|
||||
message: Vox neck accessories no longer have random pixels floating above them.
|
||||
id: 2176
|
||||
time: '2026-04-13T14:40:01.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3761
|
||||
- author: Corrupt142
|
||||
changes:
|
||||
- type: Add
|
||||
message: New SMG has appeared in the loadout menu! RS-2 Malandro
|
||||
id: 2177
|
||||
time: '2026-04-13T14:57:19.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3754
|
||||
- author: Corrupt142
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: Serkesh has recieved some QoL tweaks/optimised PD layout
|
||||
- type: Tweak
|
||||
message: >-
|
||||
Scallywag now has a boforos at the cost of its missiles, High power
|
||||
gunnery downgraded to medium.
|
||||
id: 2178
|
||||
time: '2026-04-13T15:00:42.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3751
|
||||
- author: Redrover1760
|
||||
changes:
|
||||
- type: Add
|
||||
message: Adds black cloth wraps.
|
||||
id: 2179
|
||||
time: '2026-04-13T15:25:26.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3741
|
||||
- author: Svarshik
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: >-
|
||||
Armor plates can be put in modsuits chestplate, increased modsuit
|
||||
storage to satchel.
|
||||
- type: Fix
|
||||
message: 'Fixed invisible modsuit magboots '
|
||||
id: 2180
|
||||
time: '2026-04-13T15:39:20.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3733
|
||||
- author: Ilya246
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: Turrets will now consider shooting through objects to attack you.
|
||||
id: 2181
|
||||
time: '2026-04-13T15:40:17.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3732
|
||||
- author: Redrover1760
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: Scythe range decreased from 1500 to 900.
|
||||
- type: Tweak
|
||||
message: Scythe firerate reduced to 0.5 bursts per second, 1.5 RPS
|
||||
- type: Tweak
|
||||
message: Scythe explosion reduced.
|
||||
id: 2182
|
||||
time: '2026-04-13T15:45:38.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3713
|
||||
- author: tonotom1
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: >-
|
||||
Anti Chimera spawncamp turrets can now be restored with a welder or
|
||||
nanite applicator.
|
||||
id: 2183
|
||||
time: '2026-04-13T15:46:56.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3712
|
||||
- author: Ghost581X
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: >-
|
||||
Camelot secured their military assembler and communication line with
|
||||
extra bolts.
|
||||
id: 2184
|
||||
time: '2026-04-13T17:10:17.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3702
|
||||
- author: Kiithnaras
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: Improves Tricordrazine with limitations.
|
||||
- type: Tweak
|
||||
message: Improves lifetime of many basic/common chems.
|
||||
- type: Add
|
||||
message: >-
|
||||
A Pre-Filled version of the Chemmaster is now available for sale at
|
||||
flatpack vendors!
|
||||
- type: Tweak
|
||||
message: Slightly improves Arithrazine effects.
|
||||
- type: Tweak
|
||||
message: Improves Epinephrine effects.
|
||||
id: 2185
|
||||
time: '2026-04-13T17:27:35.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3576
|
||||
- author: Onezero0
|
||||
changes:
|
||||
- type: Add
|
||||
message: Added the Large APC for mappers.
|
||||
id: 2186
|
||||
time: '2026-04-13T17:42:50.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3484
|
||||
- author: Mrrpip
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: Fabricators and servers from the USSP vendor are no longer limited.
|
||||
id: 2187
|
||||
time: '2026-04-13T17:43:55.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3441
|
||||
- author: chuga-git
|
||||
changes:
|
||||
- type: Add
|
||||
message: '"Entropy" electron torpedos (ADS Wyrm) have received a speed boost.'
|
||||
id: 2188
|
||||
time: '2026-04-13T18:02:20.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3710
|
||||
- author: thoughtlessuser
|
||||
changes:
|
||||
- type: Remove
|
||||
message: Removed the two letoferol syringes from Polaris virology.
|
||||
- type: Add
|
||||
message: >-
|
||||
Added a vault and research section to Polaris with letoferol and
|
||||
syndicate loot as the prize.
|
||||
id: 2189
|
||||
time: '2026-04-13T18:13:28.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3033
|
||||
- author: Mrrpip
|
||||
changes:
|
||||
- type: Add
|
||||
message: >-
|
||||
Adds stamps for various TSF and PDV command roles, alongside USSP and
|
||||
Winter Solstice variants.
|
||||
id: 2190
|
||||
time: '2026-04-13T18:31:12.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3736
|
||||
- author: Ilya246
|
||||
changes:
|
||||
- type: Fix
|
||||
message: Fixed thermal signatures not properly updating.
|
||||
id: 2191
|
||||
time: '2026-04-14T13:50:47.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3790
|
||||
- author: chuga-git
|
||||
changes:
|
||||
- type: Fix
|
||||
message: >-
|
||||
Reverts projectile explosion fix, pending a proper patch for off-grid
|
||||
explosions to make them not extremely inconsistent.
|
||||
id: 2192
|
||||
time: '2026-04-14T16:21:16.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3788
|
||||
- author: Redrover1760
|
||||
changes:
|
||||
- type: Fix
|
||||
message: >-
|
||||
Printed lathe gear is not worth FMC/DC unless a member of the
|
||||
corresponding faction prints it. Non-printed gear unchanged.
|
||||
id: 2193
|
||||
time: '2026-04-14T19:16:58.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3785
|
||||
- author: Redrover1760
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: >-
|
||||
Tarantula revamped with radar markings, large engines, and tile
|
||||
diagonalization.
|
||||
id: 2194
|
||||
time: '2026-04-14T21:01:36.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3276
|
||||
- author: JoeHammad
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: >-
|
||||
Tweaked sprite layers for balaclavas and neck items, increasing their
|
||||
priority
|
||||
id: 2195
|
||||
time: '2026-04-15T10:36:56.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3795
|
||||
- author: Redrover1760
|
||||
changes:
|
||||
- type: Fix
|
||||
message: Mechs can no longer be entered if they are destroyed mid-entering.
|
||||
id: 2196
|
||||
time: '2026-04-15T20:16:00.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3792
|
||||
- author: Redrover1760
|
||||
changes:
|
||||
- type: Fix
|
||||
message: CPRing now respects the unrevivable trait
|
||||
- type: Fix
|
||||
message: CPR revivals now notify the ghost they've been revived.
|
||||
id: 2197
|
||||
time: '2026-04-15T20:56:58.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3799
|
||||
- author: Redrover1760
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: >-
|
||||
TSF and PDV AI no longer require whitelist, instead require appropiate
|
||||
faction playtime.
|
||||
id: 2198
|
||||
time: '2026-04-15T22:26:12.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3800
|
||||
- author: Ilya246
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: >-
|
||||
Temporarily buffed shipgun explosions to compensate for explosion fix,
|
||||
pending rebalance.
|
||||
- type: Fix
|
||||
message: Fixed explosions that are slightly offgrid working not as expected.
|
||||
- type: Fix
|
||||
message: Reapplied raycasted projectile explosion fix.
|
||||
id: 2199
|
||||
time: '2026-04-16T12:45:27.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3789
|
||||
- author: Redrover1760
|
||||
changes:
|
||||
- type: Fix
|
||||
message: >-
|
||||
Yowie randomized last names are no longer are an invalid character and
|
||||
instead just don't exist
|
||||
id: 2200
|
||||
time: '2026-04-16T15:24:17.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3803
|
||||
- author: ziz11
|
||||
changes:
|
||||
- type: Add
|
||||
message: Added mode change buttons to radar interfaces.
|
||||
id: 2201
|
||||
time: '2026-04-16T15:55:16.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3794
|
||||
- author: doublechest
|
||||
changes:
|
||||
- type: Fix
|
||||
message: >-
|
||||
Fixed not being able to move when entering the grid with jetpacks and
|
||||
magboots enabled
|
||||
id: 2202
|
||||
time: '2026-04-16T16:04:10.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3781
|
||||
- author: Illumos
|
||||
changes:
|
||||
- type: Add
|
||||
message: Added yip & whine emote to Vulpkanin, from the fox sounds.
|
||||
- type: Tweak
|
||||
message: Old Vulpkanin whine is now called "whimper".
|
||||
id: 2203
|
||||
time: '2026-04-16T16:16:57.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3538
|
||||
- author: Mrrpip
|
||||
changes:
|
||||
- type: Fix
|
||||
message: Fixes the Sentinel's AME locker being unreachable by cyborgs.
|
||||
id: 2204
|
||||
time: '2026-04-16T16:18:43.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3531
|
||||
- author: NazrinNya
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: RCD have been severely buffed.
|
||||
- type: Tweak
|
||||
message: Super part rating has upped to 4, Advanced part rating has upped to 3.
|
||||
- type: Tweak
|
||||
message: Super parts now require fissile uranium to be produced.
|
||||
id: 2205
|
||||
time: '2026-04-16T16:35:54.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3804
|
||||
- author: DieselMohawkTheSequel
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: Faction Access added to ID consoles
|
||||
- type: Add
|
||||
message: ID box added to Vizier locker
|
||||
- type: Fix
|
||||
message: DoC can no longer steal from the CC bank and vice versa
|
||||
id: 2206
|
||||
time: '2026-04-16T18:27:44.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3454
|
||||
- author: TheRex191
|
||||
changes:
|
||||
- type: Fix
|
||||
message: Fixed portable gaslocks not docking.
|
||||
id: 2207
|
||||
time: '2026-04-16T19:32:26.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3807
|
||||
- author: NazrinNya
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: Overseer no longer requires whitelist to be played.
|
||||
id: 2208
|
||||
time: '2026-04-16T19:44:11.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3808
|
||||
- author: lopsidedmanboobs
|
||||
changes:
|
||||
- type: Add
|
||||
message: >-
|
||||
You cannot borg players during piracy unless they attack you, the
|
||||
pirate. Review rule 3 for changes.
|
||||
- type: Tweak
|
||||
message: >-
|
||||
Companies that are known pirates/antagonistic (Redsail Corsairs as an
|
||||
example) can be Killed on Sight. Review rule 1 for changes.
|
||||
id: 2209
|
||||
time: '2026-04-17T00:41:48.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3809
|
||||
- author: Ilya246
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: >-
|
||||
Significantly upgraded ship AI (autopilot) behavior. Should be less
|
||||
awkward and no longer make easily avoidable mistakes (will still make
|
||||
unavoidable mistakes, though, so don't go going 300 on a Serkesh).
|
||||
id: 2210
|
||||
time: '2026-04-17T14:52:16.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3811
|
||||
- author: Corrupt142
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: Tweaked wyvern to be boardable!
|
||||
id: 2211
|
||||
time: '2026-04-17T16:56:15.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3812
|
||||
- author: Redrover1760
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: Asakim clothing slowdown resistance lowered from 100% to 20%
|
||||
- type: Tweak
|
||||
message: Asakim suit now has 20% slowdown.
|
||||
- type: Tweak
|
||||
message: >-
|
||||
Lowered Asakim suit stam resist to 60% from 90%, to be in line with the
|
||||
cybersun jugsuit.
|
||||
- type: Tweak
|
||||
message: Asakim suit now requires an Asakim brain to wear.
|
||||
- type: Remove
|
||||
message: >-
|
||||
Brainswapping with Asakim is no longer considered an exploit in the
|
||||
rules.
|
||||
- type: Add
|
||||
message: Clothing whitelist mechanics.
|
||||
- type: Tweak
|
||||
message: >-
|
||||
Some Asakim abilities moved to new Asakim organs. Eyes give NVs, Lungs
|
||||
give bonus damage, Heart can process 5 reagents at once.
|
||||
- type: Tweak
|
||||
message: >-
|
||||
Removes handheld radio and storage implant from Asakim Loadout. Adds
|
||||
Cognizine bottle and empty syringe.
|
||||
id: 2212
|
||||
time: '2026-04-17T17:00:31.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3798
|
||||
- author: OneZerooo0
|
||||
changes:
|
||||
- type: Add
|
||||
message: Added a new guidebook page for the TSFMC.
|
||||
- type: Tweak
|
||||
message: Guidebook got a little bit more organized.
|
||||
id: 2213
|
||||
time: '2026-04-17T20:42:34.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3814
|
||||
- author: burrrkeye
|
||||
changes:
|
||||
- type: Fix
|
||||
message: Asakim now spawn with filled oxygen tank.
|
||||
id: 2214
|
||||
time: '2026-04-18T14:17:50.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3818
|
||||
- author: Onezero0
|
||||
changes:
|
||||
- type: Tweak
|
||||
message: Nerfed damage output of Annies/WSPR.
|
||||
- type: Tweak
|
||||
message: Sultan's Pulsar is now actually pump-action.
|
||||
- type: Tweak
|
||||
message: Nerfed PDV CV- armors slightly.
|
||||
- type: Tweak
|
||||
message: Reduced M92-x shield movespeed debuff.
|
||||
- type: Tweak
|
||||
message: DEW-Smilodon properly calibrates aim while firing.
|
||||
- type: Tweak
|
||||
message: 400thz boxes have doubled capacity but reduced damage.
|
||||
- type: Tweak
|
||||
message: Most heavy rifles now need wielding to fire.
|
||||
id: 2215
|
||||
time: '2026-04-18T14:20:18.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3815
|
||||
- author: DieselMohawkTheSequel
|
||||
changes:
|
||||
- type: Fix
|
||||
message: Gave DoC and Colonel back PTech access.
|
||||
id: 2216
|
||||
time: '2026-04-18T15:47:50.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3821
|
||||
- author: Mrrpip
|
||||
changes:
|
||||
- type: Fix
|
||||
message: Enables Osiris inhands.
|
||||
id: 2217
|
||||
time: '2026-04-19T02:04:24.0000000+00:00'
|
||||
url: https://github.com/Monolith-Station/Monolith/pull/3827
|
||||
|
||||
@@ -8,6 +8,6 @@ delta-chat-emote-name-rev = Rev
|
||||
delta-chat-emote-name-caw = Caw
|
||||
delta-chat-emote-name-bark = Bark
|
||||
delta-chat-emote-name-snarl = Snarl
|
||||
delta-chat-emote-name-whine = Whine
|
||||
delta-chat-emote-name-whine = Whimper
|
||||
delta-chat-emote-name-howl = Howl
|
||||
delta-chat-emote-name-awoo = Awoo
|
||||
|
||||
@@ -9,7 +9,6 @@ chat-emote-name-warble = Warble
|
||||
chat-emote-name-wurble = Wurble
|
||||
chat-emote-name-mars = Mars
|
||||
chat-emote-name-bagawk = Bagawk
|
||||
chat-emote-name-yip = Yip
|
||||
|
||||
# Message
|
||||
chat-emote-msg-trill = trills!
|
||||
@@ -17,4 +16,3 @@ chat-emote-msg-warble = warbles!
|
||||
chat-emote-msg-wurble = wurbles!
|
||||
chat-emote-msg-mars = mars.
|
||||
chat-emote-msg-bagawk = bagawks!
|
||||
chat-emote-msg-yip = Yips!
|
||||
@@ -50,7 +50,7 @@ The-Hive-description = Why perfect the old when you can become something new? Th
|
||||
|
||||
paycheck-bratva-description = The Paycheck Bratva are an organized crime network originating from USSP territory, having bled into Colossus sector ever since the space superpower moved there. It is mainly specialised in high profile drug trade, smuggling and big impact robberies, alongside hits on targets with various attached prices. Alongside this they operate on a simplistic code: Always shoot to kill if shots are fired, never partake in drugs much less their own, and kill the ones who spilled Paycheck Bratva blood. All and all an intimidating force, clad in kevlar vests and suit and ties and balaclavas or similar masks, a faction for thugs and professional robbers alike indeed.
|
||||
|
||||
viper-group-description = Formerly a Syndicate privateering company operating under the wing of Gorlex, domineered by military discipline with the sole mission of disrupting NT interstellar shipping routes along the fringes of NT space. After the Union of Soviet Socialist Planets declared its independence from the Confederacy, Viper Group saw an opportunity to exploit the nation's situation after the devastating corporate war and formed a branch office in USSP space as to facilitate local operations against TSF under the guise of "aiding" in the stabilization of USSP's borders against their former overlords, gaining respectable reputation amongst the USSP's early ranks and profit by selling looted ancient NT and syndicate equipment to the USSP's government and local blackmarkets. Post-Corporate war the Vipers had entirely migrated into USSP space with a PMC front, moving away from being associated publicly with the USSP's military and acting independently. With the USSP growing content with their sphere of influence amongst the stars following a series of devastating TSF incursions reclaiming territory from the USSP, the Vipers left their domain to prowl with their best virtue; Greed. The Vipers expanded their reach to target more opportunistic areas where one would not look twice their way upon catching their insignia, such as destabilized frontier planets and spacehubs of various groups of interest as they became notorious for conducting raids on supply and shipping routes; most notably those of the emergent TSF and PD. With leadership often violently switching hands once a Viper commander's fangs grow dull, the Vipers are seen as a wildcard whose only interest is credits and fullfilling contracts to the letter. Favorable relations with the Colossus' blackmarket expedited their arrival to the sector. For those whom yearn for danger and wealth, the Vipers bow to none; loyalty intertwined by brotherhood and fangs bared for credits.
|
||||
viper-group-description = Formerly a Syndicate privateering company operating under the wing of Gorlex with a rigid military doctrine, their sole designated mission being disrupting interstellar shipping routes along the fringes of NT territory. After the Union of Soviet Socialist Planets declared its independence from the Confederacy, Viper Group saw an opportunity to exploit the nation's situation after the devastating corporate war and formed a branch office in USSP space as to facilitate local operations against TSF under the guise of "aiding" in the stabilization of USSP's borders against their former overlords, gaining respectable reputation amongst the USSP's early ranks and profit by selling looted ancient NT and syndicate equipment to the USSP's government and local blackmarkets. Post-Corporate war the Vipers had entirely migrated into USSP space with a PMC front, moving away from being associated publicly with the USSP's military and acting independently. With the USSP growing content with their sphere of influence amongst the stars following a series of devastating TSF incursions reclaiming territory from the USSP, the Vipers left their domain to prowl with their best virtue; Greed. The Vipers expanded their reach to target more opportunistic areas where one would not look twice their way upon catching their insignia, such as destabilized frontier planets and spacehubs of various groups of interest as they became notorious for conducting raids on supply and shipping routes; most notably those of the emergent TSF and PD. With leadership often violently switching hands once a Viper commander's fangs grow dull, the Vipers are seen as a wildcard whose only interest is credits and fullfilling contracts to the letter. Favorable relations with the Colossus' blackmarket expedited their arrival to the sector. For those whom yearn for danger and wealth, the Vipers bow to none; loyalty intertwined by brotherhood and fangs bared for credits.
|
||||
|
||||
cerberus-surplus-provisions = The Cerberus, CSP, or provisionaries, are a black market company reigning from the Phaethon Dynasty's capital station Helios. From their "underground" headquarters the CSP conduct various operations within the criminal underworld to benefit the PD (Phaethon Dynasty) through means of trading any illegal substances, weaponry or general equipment that they can barter or find. The company maintains their utmost self-respect, keeping a strong and hospitable public image for potential buyers and business partners. The CSP will deal with anyone who is willing to take on a deal with the snake.
|
||||
|
||||
|
||||
@@ -1 +1,10 @@
|
||||
stamp-component-stamped-name-paycheck-bratva = Paycheck Bratva
|
||||
stamp-component-stamped-name-paycheck-bratva = Paycheck Bratva
|
||||
stamp-component-stamped-name-winter-solstice = Winter Solstice
|
||||
stamp-component-stamped-name-tsf-colonel = TSFMC Colonel
|
||||
stamp-component-stamped-name-tsf-captain = TSFMC Captain
|
||||
stamp-component-stamped-name-ussp-stratcomm = USSP STRATCOMM
|
||||
stamp-component-stamped-name-ussp = USSP
|
||||
stamp-component-stamped-name-pdv-overwatch = Phaethon Dynasty Local Overwatch
|
||||
stamp-component-stamped-name-pdv-vizier = The Sultan's Grand Vizier
|
||||
stamp-component-stamped-name-pdv-asvaran = The Sultan's Asvaran
|
||||
stamp-component-stamped-name-pdv-spasaka = The Sultan's Spasaka
|
||||
|
||||
@@ -1,2 +1,7 @@
|
||||
shuttle-console-autopilot-button = Autopilot
|
||||
shuttle-console-autopilot-popup-done = Autopilot Arrived
|
||||
|
||||
shuttle-console-button-azimuth = Toggle Azimuth Style
|
||||
shuttle-console-button-rotation = Toggle View Rotation
|
||||
shuttle-console-button-anchor = Toggle View Anchor
|
||||
shuttle-console-button-reset = Reset View
|
||||
|
||||
@@ -10,12 +10,12 @@ plant-analyzer-window-mode-off = Off
|
||||
plant-analyzer-window-label-name-scanned-plant = Scanned plant: {$seedName}
|
||||
plant-analyzer-window-label-name-scanned-seed = Scanned seed: {$seedName}
|
||||
plant-analyzer-unknown-plant = Unknown
|
||||
plant-analyzer-plant-endurance-text = Plant endurance: {$seedEndurance}
|
||||
plant-analyzer-plant-chemistry-text = Сontained substances: {$seedChem}
|
||||
plant-analyzer-plant-endurance-text = Endurance: {$seedEndurance}
|
||||
plant-analyzer-plant-chemistry-text = Reagents: {$seedChem}
|
||||
plant-analyzer-plant-gases-none = None
|
||||
plant-analyzer-plant-yield-text = Plant yield: {$seedYield}
|
||||
plant-analyzer-plant-yield-text = Yield: {$seedYield}
|
||||
plant-analyzer-plant-harvest-text = Harvest type: {$plantHarvestType}
|
||||
plant-analyzer-plant-potency-text = Plant potency: {$seedPotency}%
|
||||
plant-analyzer-plant-potency-text = Potency: {$seedPotency}%
|
||||
plant-analyzer-plant-exude-text = Emitted gases: {$gases}
|
||||
plant-analyzer-plant-consume-text = Consumed gases: {$gases}
|
||||
plant-analyzer-plant-lifespan-text = Lifespan: {$lifespan}
|
||||
@@ -30,8 +30,8 @@ plant-analyzer-tolerance-heat-tolerance = Heat tolerance: ±{$heatTolerance} K
|
||||
plant-analyzer-tolerance-ideal-light = Ideal light: {$idealLight} cd
|
||||
plant-analyzer-tolerance-light-tolerance = Light tolerance: ±{$lightTolerance} cd
|
||||
plant-analyzer-tolerance-toxin-tolerance = Toxin tolerance: {$toxinsTolerance}
|
||||
plant-analyzer-tolerance-low-pressure = Low pressure: {$lowPressureTolerance} kPa
|
||||
plant-analyzer-tolerance-high-pressure = High pressure: {$highPressureTolerance} kPa
|
||||
plant-analyzer-tolerance-low-pressure = Min pressure: {$lowPressureTolerance} kPa
|
||||
plant-analyzer-tolerance-high-pressure = Max pressure: {$highPressureTolerance} kPa
|
||||
plant-analyzer-tolerance-pest-tolerance = Pest tolerance: {$pestTolerance}
|
||||
plant-analyzer-tolerance-weed-tolerance = Weed tolerance: {$weedTolerance}
|
||||
|
||||
@@ -39,15 +39,15 @@ plant-analyzer-plant-mutations-text = Mutations: {$traits}
|
||||
plant-analyzer-plant-speciation-text = Possible subtypes: {$speciation}
|
||||
|
||||
plant-analyzer-mutation-unviable = Unviable
|
||||
plant-analyzer-mutation-turnintokudzu = Kudzufication
|
||||
plant-analyzer-mutation-turnintokudzu = Kudzu
|
||||
plant-analyzer-mutation-seedless = Seedless
|
||||
plant-analyzer-mutation-slip = Slippery
|
||||
plant-analyzer-mutation-sentient = Sentient
|
||||
plant-analyzer-mutation-ligneous = Ligneous
|
||||
plant-analyzer-mutation-bioluminescent = Bioluminescent
|
||||
plant-analyzer-mutation-canscream = Mandragora
|
||||
plant-analyzer-mutation-canscream = Screaming
|
||||
|
||||
plant-analyzer-harvest-Unknown = Unknown
|
||||
plant-analyzer-harvest-Repeat = Perennial
|
||||
plant-analyzer-harvest-NoRepeat = Ephemeral
|
||||
plant-analyzer-harvest-Repeat = Repeating
|
||||
plant-analyzer-harvest-NoRepeat = Single
|
||||
plant-analyzer-harvest-SelfHarvest = Self-harvesting
|
||||
|
||||
@@ -25,6 +25,7 @@ shuttle-console-signature-unknown =
|
||||
|
||||
# Network Port Buttons
|
||||
shuttle-console-network-ports = Network Ports
|
||||
shuttle-console-network-connect-tooltip = The buttons on the shuttle console send a signal when pressed, use a multitool on the console and connect it up to a device!
|
||||
|
||||
# Device Link Buttons
|
||||
shuttle-console-device-button-1 = Port 1
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
chat-emote-name-yip = Yip
|
||||
chat-emote-name-whine = Whine
|
||||
@@ -80,7 +80,7 @@ reagent-name-tranexamic-acid = tranexamic acid
|
||||
reagent-desc-tranexamic-acid = A blood-clotting medicine used to prevent profuse bleeding. Causes heavier bleeding on overdose. Commonly found in small doses within emergency medipens.
|
||||
|
||||
reagent-name-tricordrazine = tricordrazine
|
||||
reagent-desc-tricordrazine = A wide-spectrum stimulant, originally derived from cordrazine. Treats minor damage of all basic health types as long as the user is not heavily wounded. Best used as an additive to other chemicals.
|
||||
reagent-desc-tricordrazine = A wide-spectrum stimulant, originally derived from cordrazine. Treats damage of all basic health types, but is most effective on minor wounds. Best used as an additive to other chemicals and is very dangerous to overdose.
|
||||
|
||||
reagent-name-lipozine = lipozine
|
||||
reagent-desc-lipozine = A chemical that accelerates metabolism, causing the user to hunger faster.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
apc-menu-title = APC
|
||||
apc-menu-title = Area Power Controller
|
||||
apc-menu-breaker-label = BREAKER
|
||||
apc-menu-breaker-button = TOGGLE
|
||||
apc-menu-power-label = LOAD (W)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
gun-selected-mode-examine = Current selected fire mode is [color={$color}]{$mode}[/color].
|
||||
gun-fire-rate-examine = Fire rate is [color={$color}]{$fireRate}[/color] per second.
|
||||
gun-fire-rate-examine = Fire rate is [color={$color}]{$fireRate}[/color] rounds per minute.
|
||||
gun-damage-modifier-examine = Its shots deal [color={$color}]{$damage}x[/color] damage.
|
||||
gun-selector-verb = Change to {$mode}
|
||||
gun-selected-mode = Selected {$mode}
|
||||
gun-disabled = You can't use guns!
|
||||
@@ -52,4 +53,4 @@ gun-speedloader-empty = Speedloader empty
|
||||
|
||||
# GunSpreadModifier
|
||||
examine-gun-spread-modifier-reduction = The spread has been reduced by [color=yellow]{$percentage}%[/color].
|
||||
examine-gun-spread-modifier-increase = The spread has been increased by [color=yellow]{$percentage}%[/color].
|
||||
examine-gun-spread-modifier-increase = The spread has been increased by [color=yellow]{$percentage}%[/color].
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -35724,13 +35724,15 @@ entities:
|
||||
- type: Transform
|
||||
pos: -38.359024,21.641636
|
||||
parent: 1
|
||||
- proto: FactionLathe
|
||||
- proto: FactionLatheImmmovable
|
||||
entities:
|
||||
- uid: 5671
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -41.5,41.5
|
||||
parent: 1
|
||||
missingComponents:
|
||||
- Anchorable
|
||||
- proto: FaxMachineUSSP
|
||||
entities:
|
||||
- uid: 5672
|
||||
@@ -35738,6 +35740,8 @@ entities:
|
||||
- type: Transform
|
||||
pos: -37.5,30.5
|
||||
parent: 1
|
||||
missingComponents:
|
||||
- Anchorable
|
||||
- proto: FenceMetalCorner
|
||||
entities:
|
||||
- uid: 5674
|
||||
@@ -52379,6 +52383,8 @@ entities:
|
||||
- type: Transform
|
||||
pos: 2.5,25.5
|
||||
parent: 1
|
||||
missingComponents:
|
||||
- Anchorable
|
||||
- proto: MachineOutpostCore
|
||||
entities:
|
||||
- uid: 269
|
||||
|
||||
+20192
-14638
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,11 @@
|
||||
meta:
|
||||
format: 7
|
||||
category: Grid
|
||||
engineVersion: 264.0.0
|
||||
engineVersion: 271.2.0
|
||||
forkId: ""
|
||||
forkVersion: ""
|
||||
time: 10/28/2025 20:33:27
|
||||
entityCount: 822
|
||||
time: 03/30/2026 13:53:31
|
||||
entityCount: 829
|
||||
maps: []
|
||||
grids:
|
||||
- 1
|
||||
@@ -40,7 +40,7 @@ entities:
|
||||
chunks:
|
||||
-1,-1:
|
||||
ind: -1,-1
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAwAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAAFAAAAAAAABgAAAAAAAAEAAAAAAAABAAAAAAAABwAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAUAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAMAAAAAAAABAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAAGAAAAAAAAAQAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAACAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAABgAAAAAAAAEAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAYAAAAAAAABAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAQAAAAAAAAEAAAAAAAAGAAAAAAAAAQAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAABgAAAAAAAAYAAAAAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAwAAAAAAAA==
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAwAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAAFAAAAAAAABgAAAAAAAAEAAAAAAAABAAAAAAAABwAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAUAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAMAAAAAAAABAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAAGAAAAAAAAAQAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAACAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAABgAAAAAAAAEAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAYAAAAAAAABAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAQAAAAAAAAEAAAAAAAAGAAAAAAAAAQAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAABgAAAAAAAAYAAAAAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAABgAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAYAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAAGAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAEAAAAAAAABAAAAAAAABgAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAwAAAAAAAA==
|
||||
version: 7
|
||||
-1,0:
|
||||
ind: -1,0
|
||||
@@ -52,7 +52,7 @@ entities:
|
||||
version: 7
|
||||
0,-1:
|
||||
ind: 0,-1
|
||||
tiles: BQAAAAAAAAUAAAAAAAABAAAAAAAABwAAAAAAAAcAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAAHAAAAAAAAAwAAAAAAAAcAAAAAAAAIAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAABAAAAAAAABQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAQAAAAAAAAUAAAAAAAABAAAAAAAAAQAAAAAAAAIAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAAAABgAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
||||
tiles: BQAAAAAAAAUAAAAAAAABAAAAAAAABwAAAAAAAAcAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAAHAAAAAAAAAwAAAAAAAAcAAAAAAAAIAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAABAAAAAAAABQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAQAAAAAAAAUAAAAAAAABAAAAAAAAAQAAAAAAAAIAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAAAABgAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAAAAABAAAAAAAAAQAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
||||
version: 7
|
||||
0,-2:
|
||||
ind: 0,-2
|
||||
@@ -175,6 +175,14 @@ entities:
|
||||
id: DeliveryGreyscale
|
||||
decals:
|
||||
9: -6,-17
|
||||
- node:
|
||||
color: '#355A7396'
|
||||
id: ShiptestOverlayTrimlineEast
|
||||
decals:
|
||||
91: -2,-6
|
||||
92: -2,-5
|
||||
93: -2,-4
|
||||
94: -2,-3
|
||||
- node:
|
||||
color: '#EFB34196'
|
||||
id: ShiptestOverlayTrimlineEast
|
||||
@@ -233,6 +241,10 @@ entities:
|
||||
id: ShiptestOverlayTrimlineWest
|
||||
decals:
|
||||
33: 0,-17
|
||||
95: 0,-6
|
||||
96: 0,-5
|
||||
97: 0,-4
|
||||
98: 0,-3
|
||||
- node:
|
||||
color: '#FFFFFFFF'
|
||||
id: TechE
|
||||
@@ -322,6 +334,11 @@ entities:
|
||||
decals:
|
||||
73: 3,-18
|
||||
- type: SpreaderGrid
|
||||
spreadQueues:
|
||||
MetalFoam: []
|
||||
Smoke: []
|
||||
Kudzu: []
|
||||
Puddle: []
|
||||
- type: GridAtmosphere
|
||||
version: 2
|
||||
data:
|
||||
@@ -445,6 +462,10 @@ entities:
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- volume: 2500
|
||||
immutable: True
|
||||
moles:
|
||||
@@ -460,6 +481,10 @@ entities:
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- volume: 2500
|
||||
temperature: 293.15
|
||||
moles:
|
||||
@@ -475,6 +500,10 @@ entities:
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
chunkSize: 4
|
||||
- type: GasTileOverlay
|
||||
- type: RadiationGridResistance
|
||||
@@ -652,30 +681,34 @@ entities:
|
||||
- 381
|
||||
- proto: AmeController
|
||||
entities:
|
||||
- uid: 17
|
||||
- uid: 242
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,-22.5
|
||||
parent: 1
|
||||
- type: AmeController
|
||||
injectionAmount: 4
|
||||
injecting: True
|
||||
- type: ContainerContainer
|
||||
containers:
|
||||
fuelSlot: !type:ContainerSlot
|
||||
showEnts: False
|
||||
occludes: True
|
||||
ent: 18
|
||||
ent: 243
|
||||
- proto: AmeJar
|
||||
entities:
|
||||
- uid: 18
|
||||
- uid: 243
|
||||
components:
|
||||
- type: Transform
|
||||
parent: 17
|
||||
parent: 242
|
||||
- type: Physics
|
||||
canCollide: False
|
||||
- proto: AmeShielding
|
||||
entities:
|
||||
- uid: 17
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 0.5,-21.5
|
||||
parent: 1
|
||||
- uid: 19
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -712,25 +745,20 @@ entities:
|
||||
pos: -0.5,-22.5
|
||||
parent: 1
|
||||
- type: PointLight
|
||||
radius: 2
|
||||
radius: 1
|
||||
enabled: True
|
||||
- uid: 26
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -0.5,-21.5
|
||||
parent: 1
|
||||
- uid: 27
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 0.5,-21.5
|
||||
parent: 1
|
||||
- uid: 28
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -0.5,-23.5
|
||||
parent: 1
|
||||
- type: PointLight
|
||||
radius: 2
|
||||
radius: 1
|
||||
enabled: True
|
||||
- uid: 29
|
||||
components:
|
||||
@@ -759,18 +787,6 @@ entities:
|
||||
- SpaceArtilleryLoad
|
||||
- proto: APCBasic
|
||||
entities:
|
||||
- uid: 31
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 2.5,-20.5
|
||||
parent: 1
|
||||
- uid: 32
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -3.5,-20.5
|
||||
parent: 1
|
||||
- uid: 33
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -795,6 +811,18 @@ entities:
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -3.5,-8.5
|
||||
parent: 1
|
||||
- uid: 131
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -4.5,-19.5
|
||||
parent: 1
|
||||
- uid: 245
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 3.5,-19.5
|
||||
parent: 1
|
||||
- proto: AtmosDeviceFanDirectional
|
||||
entities:
|
||||
- uid: 37
|
||||
@@ -1248,6 +1276,11 @@ entities:
|
||||
parent: 1
|
||||
- proto: CableApcExtension
|
||||
entities:
|
||||
- uid: 31
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -4.5,-19.5
|
||||
parent: 1
|
||||
- uid: 124
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -1256,7 +1289,7 @@ entities:
|
||||
- uid: 125
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,-20.5
|
||||
pos: -3.5,-19.5
|
||||
parent: 1
|
||||
- uid: 126
|
||||
components:
|
||||
@@ -1283,11 +1316,6 @@ entities:
|
||||
- type: Transform
|
||||
pos: -2.5,-20.5
|
||||
parent: 1
|
||||
- uid: 131
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -3.5,-20.5
|
||||
parent: 1
|
||||
- uid: 132
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -1768,6 +1796,26 @@ entities:
|
||||
- type: Transform
|
||||
pos: -0.5,-12.5
|
||||
parent: 1
|
||||
- uid: 244
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -2.5,-19.5
|
||||
parent: 1
|
||||
- uid: 828
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,-19.5
|
||||
parent: 1
|
||||
- uid: 829
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,-19.5
|
||||
parent: 1
|
||||
- uid: 830
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 3.5,-19.5
|
||||
parent: 1
|
||||
- proto: CableHV
|
||||
entities:
|
||||
- uid: 228
|
||||
@@ -1817,6 +1865,11 @@ entities:
|
||||
parent: 1
|
||||
- proto: CableMV
|
||||
entities:
|
||||
- uid: 32
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -4.5,-19.5
|
||||
parent: 1
|
||||
- uid: 237
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -1842,26 +1895,6 @@ entities:
|
||||
- type: Transform
|
||||
pos: -0.5,-20.5
|
||||
parent: 1
|
||||
- uid: 242
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 0.5,-20.5
|
||||
parent: 1
|
||||
- uid: 243
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,-20.5
|
||||
parent: 1
|
||||
- uid: 244
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,-20.5
|
||||
parent: 1
|
||||
- uid: 245
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -3.5,-20.5
|
||||
parent: 1
|
||||
- uid: 246
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -2007,13 +2040,43 @@ entities:
|
||||
- type: Transform
|
||||
pos: -0.5,-12.5
|
||||
parent: 1
|
||||
- proto: CableTerminal
|
||||
entities:
|
||||
- uid: 275
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 3.141592653589793 rad
|
||||
pos: 1.5,-22.5
|
||||
pos: 0.5,-19.5
|
||||
parent: 1
|
||||
- uid: 823
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 3.5,-19.5
|
||||
parent: 1
|
||||
- uid: 824
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -3.5,-19.5
|
||||
parent: 1
|
||||
- uid: 825
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -2.5,-19.5
|
||||
parent: 1
|
||||
- uid: 826
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,-19.5
|
||||
parent: 1
|
||||
- uid: 827
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,-19.5
|
||||
parent: 1
|
||||
- proto: CableTerminal
|
||||
entities:
|
||||
- uid: 27
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 0.5,-20.5
|
||||
parent: 1
|
||||
- proto: Catwalk
|
||||
entities:
|
||||
@@ -3339,10 +3402,10 @@ entities:
|
||||
color: '#DD0075FF'
|
||||
- proto: GravityGeneratorMini
|
||||
entities:
|
||||
- uid: 468
|
||||
- uid: 18
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -2.5,-21.5
|
||||
pos: -4.5,-14.5
|
||||
parent: 1
|
||||
- proto: Grille
|
||||
entities:
|
||||
@@ -3454,7 +3517,7 @@ entities:
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 2.5,-22.5
|
||||
pos: 2.5,-20.5
|
||||
parent: 1
|
||||
- proto: LockerWallMedicalFilled
|
||||
entities:
|
||||
@@ -3819,10 +3882,10 @@ entities:
|
||||
parent: 1
|
||||
- proto: SMESAdvanced
|
||||
entities:
|
||||
- uid: 528
|
||||
- uid: 468
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,-21.5
|
||||
pos: -0.5,-20.5
|
||||
parent: 1
|
||||
- proto: SpawnPointLatejoin
|
||||
entities:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,11 @@
|
||||
meta:
|
||||
format: 7
|
||||
category: Grid
|
||||
engineVersion: 264.0.0
|
||||
engineVersion: 271.2.0
|
||||
forkId: ""
|
||||
forkVersion: ""
|
||||
time: 03/08/2026 21:15:39
|
||||
entityCount: 822
|
||||
time: 04/11/2026 10:19:25
|
||||
entityCount: 848
|
||||
maps: []
|
||||
grids:
|
||||
- 1
|
||||
@@ -84,10 +84,10 @@ entities:
|
||||
- type: OccluderTree
|
||||
- type: SpreaderGrid
|
||||
spreadQueues:
|
||||
MetalFoam: []
|
||||
Puddle: []
|
||||
Kudzu: []
|
||||
Smoke: []
|
||||
Puddle: []
|
||||
MetalFoam: []
|
||||
- type: Shuttle
|
||||
dampingModifier: 0.25
|
||||
- type: GridPathfinding
|
||||
@@ -363,6 +363,7 @@ entities:
|
||||
- type: RadiationGridResistance
|
||||
- type: ShipGridLock
|
||||
locked: False
|
||||
- type: ThermalSignature
|
||||
- proto: 150mmEmpShell
|
||||
entities:
|
||||
- uid: 2
|
||||
@@ -449,7 +450,7 @@ entities:
|
||||
pos: 0.5,4.5
|
||||
parent: 1
|
||||
- type: Door
|
||||
secondsUntilStateChange: -2757.981
|
||||
secondsUntilStateChange: -5412.908
|
||||
state: Opening
|
||||
- type: DeviceLinkSource
|
||||
lastSignals:
|
||||
@@ -474,7 +475,7 @@ entities:
|
||||
pos: 0.5,8.5
|
||||
parent: 1
|
||||
- type: Door
|
||||
secondsUntilStateChange: -3582.5486
|
||||
secondsUntilStateChange: -6237.4756
|
||||
state: Opening
|
||||
- type: DeviceLinkSource
|
||||
lastSignals:
|
||||
@@ -2109,6 +2110,102 @@ entities:
|
||||
rot: 3.141592653589793 rad
|
||||
pos: -5.5,6.5
|
||||
parent: 1
|
||||
- proto: DecalSpawnerBloodSplatters
|
||||
entities:
|
||||
- uid: 831
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,14.5
|
||||
parent: 1
|
||||
- uid: 832
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 3.5,10.5
|
||||
parent: 1
|
||||
- uid: 833
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,6.5
|
||||
parent: 1
|
||||
- uid: 834
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,6.5
|
||||
parent: 1
|
||||
- uid: 835
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,3.5
|
||||
parent: 1
|
||||
- proto: DecalSpawnerDirtNear
|
||||
entities:
|
||||
- uid: 823
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,6.5
|
||||
parent: 1
|
||||
- uid: 824
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,7.5
|
||||
parent: 1
|
||||
- uid: 825
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,5.5
|
||||
parent: 1
|
||||
- uid: 826
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,6.5
|
||||
parent: 1
|
||||
- uid: 827
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,10.5
|
||||
parent: 1
|
||||
- uid: 828
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,14.5
|
||||
parent: 1
|
||||
- uid: 829
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 0.5,13.5
|
||||
parent: 1
|
||||
- uid: 830
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 3.5,14.5
|
||||
parent: 1
|
||||
- proto: DecalSpawnerGraffiti
|
||||
entities:
|
||||
- uid: 816
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -0.5,25.5
|
||||
parent: 1
|
||||
- uid: 836
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 0.5,14.5
|
||||
parent: 1
|
||||
- uid: 837
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,6.5
|
||||
parent: 1
|
||||
- uid: 838
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 0.5,2.5
|
||||
parent: 1
|
||||
- uid: 839
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 4.5,26.5
|
||||
parent: 1
|
||||
- proto: DefibrillatorCabinetOpen
|
||||
entities:
|
||||
- uid: 320
|
||||
@@ -2782,7 +2879,7 @@ entities:
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: 0.5,20.5
|
||||
parent: 1
|
||||
- proto: GunneryServerHigh
|
||||
- proto: GunneryServerMedium
|
||||
entities:
|
||||
- uid: 404
|
||||
components:
|
||||
@@ -2792,7 +2889,7 @@ entities:
|
||||
- type: Battery
|
||||
startingCharge: 0
|
||||
- type: ApcPowerReceiver
|
||||
powerLoad: 20
|
||||
powerLoad: 10
|
||||
- proto: Gyroscope
|
||||
entities:
|
||||
- uid: 405
|
||||
@@ -2836,13 +2933,6 @@ entities:
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: -0.5,11.5
|
||||
parent: 1
|
||||
- proto: MachineFrameDestroyed
|
||||
entities:
|
||||
- uid: 409
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 3.5,7.5
|
||||
parent: 1
|
||||
- proto: MachineFTLDrive
|
||||
entities:
|
||||
- uid: 410
|
||||
@@ -4054,6 +4144,62 @@ entities:
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: -2.5,10.5
|
||||
parent: 1
|
||||
- proto: RandomSpawner100
|
||||
entities:
|
||||
- uid: 840
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,5.5
|
||||
parent: 1
|
||||
- uid: 841
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,6.5
|
||||
parent: 1
|
||||
- uid: 842
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,7.5
|
||||
parent: 1
|
||||
- uid: 843
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,5.5
|
||||
parent: 1
|
||||
- uid: 844
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 3.5,7.5
|
||||
parent: 1
|
||||
- proto: SalvageSpawnerScrapCommon75
|
||||
entities:
|
||||
- uid: 845
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,6.5
|
||||
parent: 1
|
||||
- uid: 846
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,7.5
|
||||
parent: 1
|
||||
- uid: 847
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,6.5
|
||||
parent: 1
|
||||
- uid: 848
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 3.5,7.5
|
||||
parent: 1
|
||||
- proto: ScrapFirelock2
|
||||
entities:
|
||||
- uid: 409
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 3.3815424,7.550204
|
||||
parent: 1
|
||||
- proto: SignalButton
|
||||
entities:
|
||||
- uid: 612
|
||||
@@ -4247,18 +4393,6 @@ entities:
|
||||
- type: Transform
|
||||
pos: 4.861307,26.787992
|
||||
parent: 1
|
||||
- proto: VehicleJanicartDestroyed
|
||||
entities:
|
||||
- uid: 641
|
||||
components:
|
||||
- type: Transform
|
||||
anchored: False
|
||||
pos: 1.846711,5.8817015
|
||||
parent: 1
|
||||
- type: Physics
|
||||
bodyType: Dynamic
|
||||
- type: Pullable
|
||||
prevFixedRotation: True
|
||||
- proto: WallPlastitanium
|
||||
entities:
|
||||
- uid: 643
|
||||
@@ -5234,6 +5368,14 @@ entities:
|
||||
- type: Transform
|
||||
pos: -1.5,14.5
|
||||
parent: 1
|
||||
- proto: WeaponTurretBofors
|
||||
entities:
|
||||
- uid: 818
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 3.141592653589793 rad
|
||||
pos: 2.5,23.5
|
||||
parent: 1
|
||||
- proto: WeaponTurretL85Autocannon
|
||||
entities:
|
||||
- uid: 783
|
||||
@@ -5282,6 +5424,16 @@ entities:
|
||||
parent: 1
|
||||
- proto: WeaponTurretSyndicateBroken
|
||||
entities:
|
||||
- uid: 641
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -3.5,19.5
|
||||
parent: 1
|
||||
- uid: 817
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 5.5,19.5
|
||||
parent: 1
|
||||
- uid: 821
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -5292,23 +5444,4 @@ entities:
|
||||
- type: Transform
|
||||
pos: 4.5,26.5
|
||||
parent: 1
|
||||
- uid: 823
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,23.5
|
||||
parent: 1
|
||||
- proto: WeaponTurretVespera
|
||||
entities:
|
||||
- uid: 824
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 3.141592653589793 rad
|
||||
pos: -3.5,19.5
|
||||
parent: 1
|
||||
- uid: 825
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 3.141592653589793 rad
|
||||
pos: 5.5,19.5
|
||||
parent: 1
|
||||
...
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -79,4 +79,21 @@
|
||||
- Atmospherics
|
||||
- Pilot
|
||||
|
||||
- type: accessGroup
|
||||
id: AllAccessMono
|
||||
tags:
|
||||
#- EmergencyShuttleRepealAll
|
||||
- Captain
|
||||
- Command
|
||||
- Security
|
||||
- Brig
|
||||
- Mail
|
||||
- Medical
|
||||
- Mercenary
|
||||
- Service
|
||||
- StationTrafficController
|
||||
- Maintenance
|
||||
- External
|
||||
- Janitor
|
||||
- Chemistry
|
||||
# Mono end
|
||||
|
||||
@@ -179,9 +179,6 @@
|
||||
tags:
|
||||
- HamsterWearable
|
||||
- WhitelistChameleon
|
||||
- type: GuideHelp
|
||||
guides:
|
||||
- Security
|
||||
# - Antagonists # Frontier: guidebook entry removed
|
||||
- type: IdentityBlocker
|
||||
coverage: EYES
|
||||
|
||||
@@ -432,9 +432,6 @@
|
||||
- type: Clothing
|
||||
sprite: Clothing/Hands/Gloves/forensic.rsi
|
||||
- type: FingerprintMask
|
||||
- type: GuideHelp
|
||||
guides:
|
||||
- Forensics
|
||||
|
||||
# TODO Make lubed items not slip in hands
|
||||
- type: entity
|
||||
|
||||
@@ -687,7 +687,7 @@
|
||||
Caustic: 0.5
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 0.9
|
||||
sprintModifier: 0.9
|
||||
sprintModifier: 0.85
|
||||
- type: HeldSpeedModifier
|
||||
- type: ToggleableClothing # Goobstation - Modsuits change - Mono - this is a solution for helmet attachment/cover to not fit on hardsuits
|
||||
requiredSlot: outerclothing
|
||||
@@ -768,7 +768,7 @@
|
||||
Blunt: 0.6
|
||||
Slash: 0.6
|
||||
Piercing: 0.6
|
||||
Heat: 0.2
|
||||
Heat: 0.35
|
||||
Radiation: 0.01
|
||||
Caustic: 0.5
|
||||
- type: Item
|
||||
|
||||
@@ -281,6 +281,7 @@
|
||||
toggleAction: ActionObserverShowRadar
|
||||
- type: RadarConsole
|
||||
followEntity: true
|
||||
noRotate: true
|
||||
- type: DetectionRangeMultiplier # same as mass scanner
|
||||
infraredMultiplier: 0.5
|
||||
visualMultiplier: 0.75
|
||||
|
||||
@@ -367,7 +367,7 @@
|
||||
treatments:
|
||||
Alive:
|
||||
reagent: Tricordrazine
|
||||
quantity: 30
|
||||
quantity: 10 # Mono: Reduced to prevent overdose
|
||||
minDamage: 0
|
||||
maxDamage: 50
|
||||
Critical:
|
||||
|
||||
@@ -577,6 +577,7 @@
|
||||
toggleAction: ActionObserverShowRadar
|
||||
- type: RadarConsole # Mono
|
||||
followEntity: true
|
||||
noRotate: true
|
||||
maxIffRange: 0
|
||||
hideCoords: false
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
toggleAction: ActionObserverShowRadar
|
||||
- type: RadarConsole # Mono
|
||||
followEntity: true
|
||||
noRotate: true # Mono
|
||||
maxIffRange: 0
|
||||
hideCoords: false
|
||||
- type: RandomSprite
|
||||
|
||||
@@ -119,6 +119,7 @@
|
||||
- type: RadarConsole
|
||||
followEntity: true
|
||||
hideCoords: true
|
||||
noRotate: true # Mono
|
||||
- type: ComplexInteraction # Needed to interact with innate radar console
|
||||
- type: ShipyardSellCondition # Teleport to shipyard console on sale
|
||||
preserveOnSale: true
|
||||
|
||||
@@ -90,7 +90,6 @@
|
||||
- map: [ "enum.HumanoidVisualLayers.RLeg" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.LLeg" ]
|
||||
- map: ["jumpsuit"]
|
||||
- map: [ "balaclava" ]
|
||||
- map: ["enum.HumanoidVisualLayers.LFoot"]
|
||||
- map: ["enum.HumanoidVisualLayers.RFoot"]
|
||||
- map: ["enum.HumanoidVisualLayers.LHand"]
|
||||
@@ -104,13 +103,14 @@
|
||||
- map: [ "belt" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.Tail" ] # Mentioned in moth code: This needs renaming lol.
|
||||
- map: [ "back" ]
|
||||
- map: [ "neck" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.FacialHair" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.Hair" ] # Do these need to be here? (arachnid hair arachnid hair)
|
||||
- map: [ "enum.HumanoidVisualLayers.HeadSide" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.HeadTop" ]
|
||||
- map: [ "balaclava" ]
|
||||
- map: [ "mask" ]
|
||||
- map: [ "head" ]
|
||||
- map: [ "neck" ]
|
||||
- map: [ "helmetcover" ]
|
||||
- map: [ "helmetattachment" ]
|
||||
- map: [ "pocket1" ]
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
- map: [ "enum.HumanoidVisualLayers.RLeg" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.LLeg" ]
|
||||
- map: ["jumpsuit"]
|
||||
- map: [ "balaclava" ]
|
||||
- map: ["enum.HumanoidVisualLayers.LFoot"]
|
||||
- map: ["enum.HumanoidVisualLayers.RFoot"]
|
||||
- map: ["enum.HumanoidVisualLayers.LHand"]
|
||||
@@ -34,15 +33,16 @@
|
||||
- map: [ "eyes" ]
|
||||
- map: [ "belt" ]
|
||||
- map: [ "back" ]
|
||||
- map: [ "neck" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.FacialHair" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.Hair" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.HeadSide" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.HeadTop" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.Tail" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.Wings" ] # For IPC wings porting from SimpleStation
|
||||
- map: [ "balaclava" ]
|
||||
- map: [ "mask" ]
|
||||
- map: [ "head" ]
|
||||
- map: [ "neck" ]
|
||||
- map: [ "helmetcover" ]
|
||||
- map: [ "helmetattachment" ]
|
||||
- map: [ "pocket1" ]
|
||||
|
||||
@@ -93,7 +93,6 @@
|
||||
- map: [ "enum.HumanoidVisualLayers.RLeg" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.LLeg" ]
|
||||
- map: [ "jumpsuit" ]
|
||||
- map: [ "balaclava" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.LHand" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.RHand" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.LFoot" ]
|
||||
@@ -112,13 +111,14 @@
|
||||
- map: [ "belt" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.Tail" ] #in the utopian future we should probably have a wings enum inserted here so everyhting doesn't break
|
||||
- map: [ "back" ]
|
||||
- map: [ "neck" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.FacialHair" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.Hair" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.HeadSide" ]
|
||||
- map: [ "enum.HumanoidVisualLayers.HeadTop" ]
|
||||
- map: [ "balaclava" ]
|
||||
- map: [ "mask" ]
|
||||
- map: [ "head" ]
|
||||
- map: [ "neck" ]
|
||||
- map: [ "helmetcover" ]
|
||||
- map: [ "helmetattachment" ]
|
||||
- map: [ "pocket1" ]
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
id: APCElectronics
|
||||
parent: BaseElectronics
|
||||
name: APC electronics
|
||||
description: Circuit used in APC construction.
|
||||
description: Circuit used in APC construction. Can be put into a machine frame to alternatively make a large APC.
|
||||
components:
|
||||
- type: ApcElectronics
|
||||
- type: Sprite
|
||||
@@ -16,6 +16,15 @@
|
||||
Silicon: 20
|
||||
- type: StaticPrice
|
||||
price: 34
|
||||
- type: MachineBoard # Mono - LAPC
|
||||
prototype: LargeAPC
|
||||
requirements:
|
||||
Capacitor: 6
|
||||
stackRequirements:
|
||||
Cable: 5
|
||||
CableHV: 5
|
||||
PlasmaGlass: 15
|
||||
MetalRod: 8
|
||||
|
||||
# Wallmount Substation
|
||||
- type: entity
|
||||
|
||||
@@ -90,9 +90,6 @@
|
||||
sprite: _NF/Structures/Doors/Airlocks/Standard/nfsd.rsi # Frontier: Swap security to NFSD
|
||||
state: closed
|
||||
- type: LogProbeCartridge
|
||||
- type: GuideHelp
|
||||
guides:
|
||||
- Forensics
|
||||
|
||||
- type: entity
|
||||
parent: NFBasePDACartridge # Frontier: BaseItem<NFBasePDACartridge
|
||||
|
||||
@@ -24,9 +24,6 @@
|
||||
enum.ForensicScannerUiKey.Key:
|
||||
type: ForensicScannerBoundUserInterface
|
||||
- type: ForensicScanner
|
||||
- type: GuideHelp
|
||||
guides:
|
||||
- Forensics
|
||||
- type: StealTarget
|
||||
stealGroup: ForensicScanner
|
||||
- type: Appearance # Frontier
|
||||
@@ -76,9 +73,6 @@
|
||||
backgroundPatchMargin: 6.0, 0.0, 6.0, 0.0
|
||||
contentMargin: 12.0, 0.0, 6.0, 0.0
|
||||
maxWritableArea: 368.0, 256.0
|
||||
- type: GuideHelp
|
||||
guides:
|
||||
- Forensics
|
||||
|
||||
- type: entity
|
||||
parent: ForensicReportPaper
|
||||
|
||||
@@ -249,9 +249,6 @@
|
||||
damage:
|
||||
types:
|
||||
Blunt: 6
|
||||
- type: GuideHelp
|
||||
guides:
|
||||
- Security
|
||||
# - Antagonists # Frontier: removed guidebook entry
|
||||
|
||||
- type: entity
|
||||
|
||||
@@ -37,10 +37,6 @@
|
||||
Blunt: 0
|
||||
- type: StaticPrice
|
||||
price: 19
|
||||
- type: GuideHelp
|
||||
guides:
|
||||
- Security
|
||||
# - Antagonists # Frontier: guidebook entry removed
|
||||
- type: UseDelay
|
||||
delay: 3
|
||||
|
||||
|
||||
@@ -15,6 +15,3 @@
|
||||
- type: Tag
|
||||
tags:
|
||||
- Document
|
||||
- type: GuideHelp
|
||||
guides:
|
||||
- Forensics
|
||||
|
||||
@@ -157,6 +157,7 @@
|
||||
# <Mono>
|
||||
- type: RadarConsole
|
||||
followEntity: true
|
||||
noRotate: true
|
||||
- type: Magboots
|
||||
# </Mono>
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
map: [ "enum.PowerDeviceVisualLayers.Powered" ]
|
||||
- type: RadarConsole
|
||||
followEntity: true
|
||||
noRotate: true # Mono
|
||||
# Mono
|
||||
- type: DetectionRangeMultiplier
|
||||
infraredMultiplier: 0.5
|
||||
|
||||
@@ -379,9 +379,16 @@
|
||||
- HVCable
|
||||
- CableTerminal
|
||||
- Deconstruct
|
||||
# mono start
|
||||
- WallReinforced
|
||||
- AirlockShuttle
|
||||
- AirlockGlassShuttle
|
||||
- SMES
|
||||
- Substation
|
||||
delayMultiplier: 0.65 # Mono
|
||||
- type: LimitedCharges
|
||||
maxCharges: 30
|
||||
charges: 30
|
||||
maxCharges: 125 # mono 30 -> 125
|
||||
charges: 125 # mono 30 -> 125
|
||||
- type: Sprite
|
||||
sprite: _NF/Objects/Tools/rcd.rsi # Frontier
|
||||
state: icon
|
||||
@@ -428,8 +435,8 @@
|
||||
suffix: AutoRecharge
|
||||
components:
|
||||
- type: LimitedCharges
|
||||
maxCharges: 20
|
||||
charges: 20
|
||||
maxCharges: 90 # mono 20 -> 90
|
||||
charges: 90 # mono 20 -> 90
|
||||
- type: AutoRecharge
|
||||
rechargeDuration: 10
|
||||
|
||||
@@ -451,7 +458,7 @@
|
||||
components:
|
||||
# Monolith changes start
|
||||
- type: LimitedChargesAmmo
|
||||
charges: 30
|
||||
charges: 125 # 30 -> 125
|
||||
whitelist:
|
||||
tags:
|
||||
- RapidConstructionTool
|
||||
@@ -468,7 +475,7 @@
|
||||
Plastic: 100
|
||||
- type: StaticPrice
|
||||
price: 30 # Frontier 60<30
|
||||
vendPrice: 1000 # Frontier
|
||||
vendPrice: 3000 # Frontier
|
||||
|
||||
- type: entity
|
||||
name: omnitool
|
||||
|
||||
@@ -643,10 +643,6 @@
|
||||
- type: ProjectileBatteryAmmoProvider
|
||||
proto: BulletDisabler
|
||||
fireCost: 50
|
||||
- type: GuideHelp
|
||||
guides:
|
||||
- Security
|
||||
# - Antagonists # Frontier: removed guidebook entry
|
||||
|
||||
- type: entity
|
||||
name: disabler SMG
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user