Compare commits

...

141 Commits

Author SHA1 Message Date
Redrover1760 aa8c6622b8 bazooka buffs 2026-04-22 22:18:15 -04:00
Redrover1760 bcc3402ef7 30 spread instead 2026-04-20 02:52:57 -04:00
Redrover1760 a8a3cec8e4 final changes 2026-04-20 02:47:05 -04:00
Redrover1760 e19e64b903 buff it actually 2026-04-20 02:43:01 -04:00
Redrover1760 5b6542720c some rebuffs 2026-04-20 02:37:20 -04:00
Redrover1760 db7066605a wa 2026-04-19 18:03:31 -04:00
Redrover1760 e14c8c0a8f tweaks 2026-04-19 18:02:29 -04:00
Redrover1760 c061eaf610 cuts marauder firerate to 1.25 2026-04-19 18:02:02 -04:00
Redrover1760 e56c2c5272 unnerfs metronome direct damage 2026-04-19 17:58:53 -04:00
Redrover1760 238d77ead3 final tweak 2026-04-19 15:22:55 -04:00
Redrover1760 dea4d76981 okay fair 2026-04-19 15:01:22 -04:00
Redrover1760 82b46194d1 coilgun nerf 2026-04-19 14:57:35 -04:00
Redrover1760 e6835a4934 mech weapons balance pass 2026-04-19 14:55:02 -04:00
Redrover1760 3d6597526b 1 2026-04-19 14:21:36 -04:00
monolith8319 8894d4e5ff Automated Changelog (#3827) 2026-04-19 02:04:51 +00:00
Mrrpip eef28959e2 Makes Osiris Inhands Visible. (#3827) 2026-04-18 22:04:23 -04:00
monolith8319 4ea83d389a Automated Changelog (#3821) 2026-04-18 15:48:18 +00:00
Diesel 02f74c26e9 Hot Fix - PTech Access Change (#3821) 2026-04-18 18:47:50 +03:00
monolith8319 c0ea5adf5d Automated Changelog (#3815) 2026-04-18 14:20:48 +00:00
significant harassment 6daf9f02e6 Various Ground Balancing Tweaks (#3815)
Co-authored-by: Onezero0 <onezero0@outlook.com>
2026-04-18 10:20:18 -04:00
monolith8319 afabe747f2 Automated Changelog (#3818) 2026-04-18 14:18:17 +00:00
burrrkeye 699232f653 Asakim Breathe Air Update (#3818) 2026-04-18 10:17:50 -04:00
monolith8319 262aa8cd4b Automated Changelog (#3814) 2026-04-17 20:43:04 +00:00
significant harassment bcb9440046 TSFMC Guidebook Slop (#3814)
Co-authored-by: Onezero0 <onezero0@outlook.com>
2026-04-17 16:42:34 -04:00
monolith8319 93bd8b8356 Automated Changelog (#3798) 2026-04-17 17:01:02 +00:00
Redrover1760 d14dd88149 Asakim Changes (#3798) 2026-04-17 13:00:31 -04:00
monolith8319 f520ddf911 Automated Changelog (#3812) 2026-04-17 16:56:49 +00:00
Corrupt c2ea1eaf94 Wyvern Tweaks! (#3812) 2026-04-17 12:56:15 -04:00
monolith8319 fc105b61fc Automated Changelog (#3811) 2026-04-17 14:52:46 +00:00
Ilya246 271c4e7efc Even More Ship HTN Upgrades (#3811) 2026-04-17 14:52:16 +00:00
monolith8319 a4138f4b11 Automated Changelog (#3809) 2026-04-17 00:42:16 +00:00
lopsidedmanboobs ff74cf3ae1 Brush up Rules (#3809) 2026-04-16 20:41:48 -04:00
monolith8319 663425a050 Automated Changelog (#3808) 2026-04-16 19:44:40 +00:00
NazrinNya b4e4a284bc De-WL Overseer (#3808)
Co-authored-by: NazrinNya <macrohard@macrohard.localhost>
2026-04-16 22:44:11 +03:00
monolith8319 3a8ac92ef8 Automated Changelog (#3807) 2026-04-16 19:32:57 +00:00
TheRex191 d3d3ab531e Gas Dock Not Docking, Now Docking. (#3807) 2026-04-16 22:32:26 +03:00
monolith8319 71cf5f42c7 Automated Changelog (#3454) 2026-04-16 18:28:15 +00:00
Diesel fce9e95910 Faction ID Console Compatibility and Fixes Company Banks (#3454)
Co-authored-by: Redrover1760 <39284090+Redrover1760@users.noreply.github.com>
2026-04-16 21:27:44 +03:00
monolith8319 ee337596d6 Automated Changelog (#3804) 2026-04-16 16:36:28 +00:00
NazrinNya a2b3ddecdf Components Adjustment, RCD Buff. (#3804)
Co-authored-by: NazrinNya <macrohard@macrohard.localhost>
2026-04-16 19:35:53 +03:00
monolith8319 0939533dc1 Automated Changelog (#3531) 2026-04-16 16:19:14 +00:00
Mrrpip 42f6f53be9 Sentinel Fuel Locker Hotfix. (#3531) 2026-04-16 19:18:43 +03:00
monolith8319 2651c00cfd Automated Changelog (#3538) 2026-04-16 16:17:32 +00:00
Lily Autumn a462d09fb9 Yip Woof Bark (#3538) 2026-04-16 19:16:57 +03:00
monolith8319 ce617c185e Automated Changelog (#3781) 2026-04-16 16:04:47 +00:00
doublechest 131c5e79a5 Auto Disable Jetpack when Entering Grid with Enabled Magboots (#3781)
Co-authored-by: Redrover1760 <39284090+Redrover1760@users.noreply.github.com>
2026-04-16 19:04:09 +03:00
monolith8319 86c9a843b1 Automated Changelog (#3794) 2026-04-16 15:55:59 +00:00
Ssar’keth of the First Clutch dd910f1550 Add Radar Mode Toggles and UI Injection Wrapper (#3794)
Co-authored-by: Ssar'keth of the First Clutch <ziz11@users.noreply.github.com>
Co-authored-by: Ilya246 <ilyukarno@gmail.com>
2026-04-16 18:55:16 +03:00
monolith8319 cd8d59c095 Automated Changelog (#3803) 2026-04-16 15:24:48 +00:00
Redrover1760 20bc7af2a4 Unbreaks Yowie Randomized Last Names (#3803) 2026-04-16 18:24:17 +03:00
monolith8319 65ea89b673 Automated Changelog (#3789) 2026-04-16 12:46:01 +00:00
Ilya246 44445f3d2a Explosions Tempbuff (#3789)
Co-authored-by: significant harassment <moguls-charade4n@icloud.com>
2026-04-16 12:45:27 +00:00
monolith8319 648cc99aff Automated Changelog (#3800) 2026-04-15 22:26:41 +00:00
Redrover1760 e8c2b72aa0 Dewhitelists Faction AIs (#3800) 2026-04-15 18:26:12 -04:00
monolith8319 7d85dbca00 Automated Changelog (#3799) 2026-04-15 20:57:28 +00:00
Redrover1760 85e0cb1c76 CPRing Now Checks for Unrevivable + CPR Revivals Now Notify Ghost (#3799) 2026-04-15 16:56:57 -04:00
monolith8319 3c32d2f6f5 Automated Changelog (#3792) 2026-04-15 20:16:30 +00:00
Redrover1760 9d8d0b9016 Ensures Mechs Can't Be Entered if Broken (#3792) 2026-04-15 16:15:59 -04:00
monolith8319 02e72a4c1d Automated Changelog (#3795) 2026-04-15 10:37:26 +00:00
PunishedJoe 5fac554802 Fixes Balaclava and Neck Layers (#3795) 2026-04-15 19:36:56 +09:00
Redrover1760 bc62bf3700 Close Prs on Master (#3793) 2026-04-14 19:55:45 -04:00
monolith8319 accb1404b0 Automated Changelog (#3276) 2026-04-14 21:02:17 +00:00
Redrover1760 326440aa22 Tarantula Revamp (#3276)
Co-authored-by: UnicornOnLSD <149102472+UnicornOnLSD@users.noreply.github.com>
2026-04-14 17:01:36 -04:00
monolith8319 b4fe4ab5e7 Automated Changelog (#3785) 2026-04-14 19:17:32 +00:00
Redrover1760 8ff52fcd7b Infinite FMC/DC Contra Lathe Fix (#3785) 2026-04-14 15:16:58 -04:00
monolith8319 e8a620e044 Automated Changelog (#3788) 2026-04-14 16:21:49 +00:00
chuga-git 9ea80d6405 Revert "Fix Projectile Raycast" (#3788) 2026-04-14 12:21:16 -04:00
monolith8319 abec847ca3 Automated Changelog (#3790) 2026-04-14 13:51:22 +00:00
Ilya246 36214087e9 Fix Thermal Signatures (#3790) 2026-04-14 13:50:47 +00:00
monolith8319 2b4f4f2ba0 Automated Changelog (#3736) 2026-04-13 18:31:43 +00:00
Mrrpip 258bc12f16 WOE, YE FIEND. STAMPS UPON YE. (#3736)
Co-authored-by: NazrinNya <137837419+NazrinNya@users.noreply.github.com>
2026-04-13 21:31:11 +03:00
monolith8319 d73cf7aeaf Automated Changelog (#3033) 2026-04-13 18:14:00 +00:00
thoughtlessuser b1e200408d Polaris Re-Evil-Ening (#3033)
Co-authored-by: Redrover1760 <39284090+Redrover1760@users.noreply.github.com>
2026-04-13 21:13:27 +03:00
monolith8319 95227750d9 Automated Changelog (#3710) 2026-04-13 18:03:18 +00:00
chuga-git 34f71b59b9 Buffs "Entropy" Electron Torpedo Speed (#3710)
Co-authored-by: NazrinNya <137837419+NazrinNya@users.noreply.github.com>
2026-04-13 21:02:19 +03:00
monolith8319 547420d4bc Automated Changelog (#3441) 2026-04-13 17:44:48 +00:00
Mrrpip 510434fb65 Unlimited Mil-Fabs and Servers in the USSPvend (#3441) 2026-04-13 20:43:55 +03:00
monolith8319 862ce8352c Automated Changelog (#3484) 2026-04-13 17:43:20 +00:00
significant harassment 552ab5718a Large APC (#3484)
Co-authored-by: Onezero0 <onezero0@outlook.com>
2026-04-13 20:42:50 +03:00
monolith8319 2bacec206b Automated Changelog (#3576) 2026-04-13 17:28:12 +00:00
Kiithnaras bd8ae0ec9b Medicine Improvement Attempt (#3576)
Co-authored-by: Redrover1760 <39284090+Redrover1760@users.noreply.github.com>
2026-04-13 20:27:35 +03:00
monolith8319 6ba17c6e1b Automated Changelog (#3702) 2026-04-13 17:10:50 +00:00
Ghost581 50d7de7818 Bolt Down Camelot's Military Assembler + Fax + Silo (#3702) 2026-04-13 20:10:17 +03:00
monolith8319 02348e780e Automated Changelog (#3712) 2026-04-13 15:47:27 +00:00
tonotom1 80cc460d69 Repairable CC Turret (#3712) 2026-04-13 18:46:56 +03:00
monolith8319 e95a87a1d8 Automated Changelog (#3713) 2026-04-13 15:46:07 +00:00
Redrover1760 78ecd13c0a Scythe Nerfs (#3713) 2026-04-13 18:45:38 +03:00
Ghost581 9eb4c8333c Fix some Wording in VG's Description (#3724) 2026-04-13 18:42:24 +03:00
monolith8319 882b1acae7 Automated Changelog (#3732) 2026-04-13 15:40:49 +00:00
Ilya246 df39f7bd6d Turret Shootthrough (#3732) 2026-04-13 18:40:17 +03:00
monolith8319 c68d329dd2 Automated Changelog (#3733) 2026-04-13 15:39:50 +00:00
Svarshik 5a2341407b Modsuits Yml Cleanup and Minor Buff (#3733) 2026-04-13 18:39:20 +03:00
monolith8319 b4b49016d9 Automated Changelog (#3741) 2026-04-13 15:25:57 +00:00
Redrover1760 53a40c6c3c Black Cloth Wraps (#3741) 2026-04-13 18:25:26 +03:00
monolith8319 fbf93d50be Automated Changelog (#3751) 2026-04-13 15:01:14 +00:00
Corrupt 68144857e8 RSC Ship Tweaks (#3751) 2026-04-13 18:00:42 +03:00
monolith8319 820a70c695 Automated Changelog (#3754) 2026-04-13 14:57:51 +00:00
Corrupt bff7436490 RS-2 Malandro (#3754) 2026-04-13 17:57:19 +03:00
monolith8319 2b76b0a55a Automated Changelog (#3761) 2026-04-13 14:40:32 +00:00
ToastEnjoyer fa61e959fb Fix Vox Neck Displacements (#3761) 2026-04-13 17:40:01 +03:00
ondrej008 b427f087b0 Adds Missing Locale Strings (#3775) 2026-04-13 17:19:10 +03:00
monolith8319 7a8b90339f Automated Changelog (#3780) 2026-04-13 14:16:14 +00:00
iramoye cecc52bff9 Adds Maintenance Jack to 'Expanding and Repairing Station' Guidebook (#3780) 2026-04-13 17:15:41 +03:00
monolith8319 378592a0ba Automated Changelog (#3767) 2026-04-13 12:55:55 +00:00
Corrupt 89dff2ec03 Remove Flashpoint (#3767) 2026-04-13 14:55:26 +02:00
monolith8319 4faad89b0c Automated Changelog (#3778) 2026-04-13 09:48:48 +00:00
lopsidedmanboobs 8f8b94862a I HATE ALL MEDICS (#3778) 2026-04-13 11:48:20 +02:00
monolith8319 7c29b33d27 Automated Changelog (#3766) 2026-04-12 16:17:24 +00:00
doublechest 8180e5d436 Increase Cargo Order Capacity From 20 to 60 in the Trade Mall (#3766) 2026-04-12 12:16:54 -04:00
monolith8319 e081dd59c6 Automated Changelog (#3765) 2026-04-12 10:10:37 +00:00
Ilya246 295ef88a95 Fix Poi Ftling (#3765) 2026-04-12 10:10:05 +00:00
monolith8319 39292553b3 Automated Changelog (#3764) 2026-04-12 09:27:34 +00:00
Ilya246 2652423c4d Fix New Ship Speed (#3764) 2026-04-12 09:27:05 +00:00
monolith8319 fb836a0ee7 Automated Changelog (#3756) 2026-04-11 20:32:31 +00:00
Ilya246 7a63aba489 Fix Projectile Raycast (#3756) 2026-04-11 16:32:01 -04:00
monolith8319 7ec10d578c Automated Changelog (#3753) 2026-04-11 15:45:44 +00:00
Ilya246 91f4eb7b51 More Gun Fixes (#3753) 2026-04-11 15:45:12 +00:00
Ssar’keth of the First Clutch e552e2498f Add Compass and Azimuth Ring to Shuttle Radar (#3737)
Co-authored-by: Ssar'keth of the First Clutch <ziz11@users.noreply.github.com>
2026-04-11 12:01:06 +00:00
Ilya246 ef34f255bf Also Fix Borg Mass Scanner (#3750) 2026-04-11 11:43:08 +00:00
monolith8319 0f3390aba8 Automated Changelog (#3749) 2026-04-11 08:48:00 +00:00
Ilya246 25033ae9c1 Shipgun Aiming Hotfix (#3749) 2026-04-11 08:47:32 +00:00
monolith8319 d32fd9dd0a Automated Changelog (#3748) 2026-04-11 06:05:33 +00:00
Ilya246 728c10974e Fix Scanner Rotation Stuff (#3748) 2026-04-11 06:05:04 +00:00
monolith8319 50c5891b4e Automated Changelog (#3746) 2026-04-10 18:58:54 +00:00
Ilya246 51818f6dc3 Companies Fix (#3746) 2026-04-10 18:58:20 +00:00
monolith8319 dcaefa16d7 Automated Changelog (#3745) 2026-04-10 15:17:15 +00:00
Ilya246 15936634b1 Increase Shiphtn Grid Evasion Buffer (#3745) 2026-04-10 15:16:43 +00:00
monolith8319 574bb25522 Automated Changelog (#3705) 2026-04-10 14:50:16 +00:00
Ilya246 1125715a3f No Gunnery Rotation (#3705)
Co-authored-by: Redrover1760 <39284090+Redrover1760@users.noreply.github.com>
2026-04-10 14:49:46 +00:00
monolith8319 9e3a270988 Automated Changelog (#3711) 2026-04-10 12:39:36 +00:00
Antoine bf1a02bfcb Fixed Radio Highlighting (#3711) 2026-04-10 21:39:07 +09:00
monolith8319 57c59e3684 Automated Changelog (#3586) 2026-04-10 12:25:32 +00:00
tonotom1 0e31d3885f Plant Analyzer Friction Deletion (#3586) 2026-04-10 15:25:02 +03:00
monolith8319 27b05a3b75 Automated Changelog (#3743) 2026-04-10 10:19:13 +00:00
Ilya246 f99e36e101 Ship Htn Hotfix (#3743) 2026-04-10 10:18:45 +00:00
monolith8319 5a17e7781f Automated Changelog (#3731) 2026-04-09 21:23:34 +00:00
significant harassment 98f8d334a1 Gun-Based Damage Modifier Port (#3731)
Co-authored-by: VMSolidus <evilexecutive@gmail.com>
Co-authored-by: Onezero0 <onezero0@outlook.com>
2026-04-09 17:23:05 -04:00
monolith8319 c9bba3367d Automated Changelog (#3528) 2026-04-09 18:21:59 +00:00
Redrover1760 4ac8f937fb 12 Gauge Buff (#3528) 2026-04-09 14:21:28 -04:00
monolith8319 9648f54fc3 Automated Changelog (#3735) 2026-04-09 17:40:58 +00:00
Redrover1760 33e0bf8293 Gun Health Oversights (#3735) 2026-04-09 13:40:26 -04:00
268 changed files with 39815 additions and 41635 deletions
+12 -12
View File
@@ -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>
+15 -6
View File
@@ -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'}"
+4 -3
View File
@@ -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;
}
+15 -5
View File
@@ -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";
}
+8 -1
View File
@@ -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,
+4 -1
View File
@@ -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;
}
+1 -1
View File
@@ -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;
}
}
+558
View File
@@ -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
+1 -1
View File
@@ -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 -1
View File
@@ -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
+7 -1
View File
@@ -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
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+127 -64
View File
@@ -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
+180 -47
View File
@@ -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
+17
View File
@@ -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