Compare commits
313 Commits
v0.8.2
...
prototype-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d49075a970 | ||
|
|
a67acd453c | ||
|
|
b540f04a7a | ||
|
|
bcaa7001ad | ||
|
|
3f0fba7b4e | ||
|
|
d7d7a53045 | ||
|
|
40daba9adf | ||
|
|
5665f8eb1c | ||
|
|
8f0d562f3e | ||
|
|
f3950e940e | ||
|
|
3fdca65cc9 | ||
|
|
23d0b8a555 | ||
|
|
452b03d5a6 | ||
|
|
c8f2dab381 | ||
|
|
7409df07f8 | ||
|
|
973406b91d | ||
|
|
2e646fe2b6 | ||
|
|
6b902d22d4 | ||
|
|
83e6d52e58 | ||
|
|
025fdcd0b3 | ||
|
|
fe3ace92bd | ||
|
|
317070f167 | ||
|
|
3524363ad4 | ||
|
|
90287dbb09 | ||
|
|
9a2f35f2d3 | ||
|
|
3f10dbe770 | ||
|
|
8fcba93ada | ||
|
|
35366b5bc1 | ||
|
|
d8bf31ecc4 | ||
|
|
de4d255841 | ||
|
|
ec768c563f | ||
|
|
2114d2bc67 | ||
|
|
43478d0e45 | ||
|
|
561699b26e | ||
|
|
460923e54d | ||
|
|
c299104f0c | ||
|
|
224bebeeb5 | ||
|
|
52c8e8ecdf | ||
|
|
ac636b2703 | ||
|
|
a892f9ac99 | ||
|
|
2ebee8f40c | ||
|
|
43741dc5fc | ||
|
|
da9467b678 | ||
|
|
8f24a7b4fc | ||
|
|
ff48959e97 | ||
|
|
09e648d086 | ||
|
|
1d1db2e109 | ||
|
|
6a902286cd | ||
|
|
933724e4ee | ||
|
|
53034e6f05 | ||
|
|
6a31c5649c | ||
|
|
7bd90578dc | ||
|
|
c076be95a6 | ||
|
|
7b732dd68a | ||
|
|
3e34b1414e | ||
|
|
8456cd90d1 | ||
|
|
d716e1ff62 | ||
|
|
8e9acc9191 | ||
|
|
773a068b7d | ||
|
|
b37bfff155 | ||
|
|
a14cce222b | ||
|
|
c077e09436 | ||
|
|
213955566b | ||
|
|
b98cd3e6e1 | ||
|
|
987c8e8229 | ||
|
|
fcbb97ec55 | ||
|
|
c1ac7aebdb | ||
|
|
e4b0d1a03c | ||
|
|
f13f9dc5cd | ||
|
|
1f6170c000 | ||
|
|
53c7ec8ddc | ||
|
|
e438e53d36 | ||
|
|
792608f0d0 | ||
|
|
7b5678fd0f | ||
|
|
88c328a636 | ||
|
|
f9573530a8 | ||
|
|
c1df7dcca7 | ||
|
|
f141a0033e | ||
|
|
227d047584 | ||
|
|
73b73cd9da | ||
|
|
66be082bdb | ||
|
|
ac43cf0de1 | ||
|
|
fb41601d9f | ||
|
|
f35dda3fb3 | ||
|
|
7ee14f6f4f | ||
|
|
97920b42ee | ||
|
|
8ace0ec254 | ||
|
|
a3606f1098 | ||
|
|
616d379902 | ||
|
|
a27f475715 | ||
|
|
6ee76e8f46 | ||
|
|
891c30c9be | ||
|
|
9757a4c3b6 | ||
|
|
5be2f610cd | ||
|
|
35324e0853 | ||
|
|
ac753cdb93 | ||
|
|
3edd39f0eb | ||
|
|
8f790c28be | ||
|
|
c253afaf8e | ||
|
|
a6ac1dced0 | ||
|
|
d1e0f2cd94 | ||
|
|
af861d289a | ||
|
|
753f3f8c0f | ||
|
|
5c2a5741ee | ||
|
|
26941a2013 | ||
|
|
fad4c20da2 | ||
|
|
2b79ef301d | ||
|
|
014491e674 | ||
|
|
2e70cd4f2e | ||
|
|
689e1baa12 | ||
|
|
c34e84378a | ||
|
|
9a44becc73 | ||
|
|
d324d9fcf3 | ||
|
|
74cd48401c | ||
|
|
43081c57e7 | ||
|
|
b80a51d03f | ||
|
|
e90d5e4977 | ||
|
|
979034906a | ||
|
|
9e4fd2905b | ||
|
|
914c269411 | ||
|
|
2cacc4cd49 | ||
|
|
3024094584 | ||
|
|
4c66451324 | ||
|
|
7e7d808c90 | ||
|
|
0538e89948 | ||
|
|
6376f7c35d | ||
|
|
37721f2327 | ||
|
|
b0d2404644 | ||
|
|
5f76cb4819 | ||
|
|
427a54fc67 | ||
|
|
1cd1fb905d | ||
|
|
33333f87d2 | ||
|
|
4e5b8ec1e2 | ||
|
|
007feb76b7 | ||
|
|
d34dcb81fb | ||
|
|
8abb366903 | ||
|
|
3e7ba7ca28 | ||
|
|
14d52a9da9 | ||
|
|
847f8d1fee | ||
|
|
0c8d7adf37 | ||
|
|
d68d803709 | ||
|
|
13ef514d3e | ||
|
|
e20cd248a0 | ||
|
|
b8a3bda31d | ||
|
|
001493d984 | ||
|
|
013a3e3e8c | ||
|
|
4c2d984835 | ||
|
|
21bb0f15e0 | ||
|
|
8d5162ef8d | ||
|
|
257913ac0e | ||
|
|
c90dfccbf4 | ||
|
|
9c7dc8876f | ||
|
|
fc8cbdf01f | ||
|
|
5af4bfa912 | ||
|
|
0c5a47ff9d | ||
|
|
b4b4a3864f | ||
|
|
dca8561881 | ||
|
|
ee58b5299d | ||
|
|
7868b12279 | ||
|
|
42e91e8c4d | ||
|
|
28c9326305 | ||
|
|
40b8772980 | ||
|
|
b6a548629a | ||
|
|
291a37924d | ||
|
|
0b5eccd60a | ||
|
|
866a324922 | ||
|
|
baf48a8dc1 | ||
|
|
a85b2dd43c | ||
|
|
43059b3985 | ||
|
|
4d6183d6af | ||
|
|
79f87f03ce | ||
|
|
01ede29fc4 | ||
|
|
fb54d0df1c | ||
|
|
5b65495fbc | ||
|
|
cec3a8c1c2 | ||
|
|
8bd0b459b9 | ||
|
|
7da50516f9 | ||
|
|
6cbb2135b8 | ||
|
|
66dbc05022 | ||
|
|
18cc385c70 | ||
|
|
384f672eec | ||
|
|
f49a29cfb3 | ||
|
|
e8b70877cf | ||
|
|
9b084ea6a9 | ||
|
|
51f2fc4259 | ||
|
|
bb27482e9f | ||
|
|
75912896c9 | ||
|
|
6e0632ae1b | ||
|
|
7c90da0402 | ||
|
|
313a3eb7f2 | ||
|
|
cb054f0761 | ||
|
|
579b21716d | ||
|
|
3ffdc8cc2d | ||
|
|
e68af15b40 | ||
|
|
8e5fafaf05 | ||
|
|
95f9418e56 | ||
|
|
23af814ebc | ||
|
|
ae7dda9dab | ||
|
|
c5899944a2 | ||
|
|
c0e0f65ebe | ||
|
|
3bdce98964 | ||
|
|
478ab3bec4 | ||
|
|
ae77ee3df4 | ||
|
|
86e4a558c5 | ||
|
|
15c1e8f7bf | ||
|
|
f38770dbb5 | ||
|
|
75d37f8309 | ||
|
|
ed641c8cc8 | ||
|
|
069ebbc8d0 | ||
|
|
720f33a12a | ||
|
|
08f1cfbc79 | ||
|
|
9896697919 | ||
|
|
057d50b60b | ||
|
|
e3dc446e9e | ||
|
|
c529f756af | ||
|
|
c07eaecacb | ||
|
|
ddc03a1d62 | ||
|
|
ca59cff07f | ||
|
|
df4ddfdf25 | ||
|
|
c667a326a3 | ||
|
|
0099442852 | ||
|
|
eecb104cc5 | ||
|
|
a54283e637 | ||
|
|
ed06107a9f | ||
|
|
2d833daa57 | ||
|
|
67dd0a9433 | ||
|
|
fcc16d67f7 | ||
|
|
394f51f70d | ||
|
|
538627328e | ||
|
|
b5a21ccc4d | ||
|
|
2d331ff786 | ||
|
|
9d9ad15274 | ||
|
|
114ec2e493 | ||
|
|
2fb45da0d7 | ||
|
|
54a693dfa7 | ||
|
|
4be572ba58 | ||
|
|
e22d6ea65c | ||
|
|
baf86b5b83 | ||
|
|
e56c77319c | ||
|
|
a170dbd716 | ||
|
|
b821833437 | ||
|
|
1bb9b8cae3 | ||
|
|
1e32eb135d | ||
|
|
b695ce581e | ||
|
|
8138fc5fa2 | ||
|
|
0b2693cb98 | ||
|
|
3d959c98ed | ||
|
|
0ccee0b496 | ||
|
|
b7b2a0ab5e | ||
|
|
375402c455 | ||
|
|
03505da382 | ||
|
|
f56219746b | ||
|
|
116c3e491c | ||
|
|
e94c2f039c | ||
|
|
2fd52ef3eb | ||
|
|
29659536aa | ||
|
|
338a2831ee | ||
|
|
c64c1aca5b | ||
|
|
0dd72f4434 | ||
|
|
891d1da208 | ||
|
|
f8e903c422 | ||
|
|
b373824cf5 | ||
|
|
6c3c51e816 | ||
|
|
9abc3fbee2 | ||
|
|
9f20c325ab | ||
|
|
e7308efdd7 | ||
|
|
c2113b5719 | ||
|
|
c43f7ea861 | ||
|
|
5fac3f4adb | ||
|
|
7a31525c3c | ||
|
|
1613f5e982 | ||
|
|
b6907e999d | ||
|
|
c73077014b | ||
|
|
ce9bf26204 | ||
|
|
85f716ef03 | ||
|
|
fba696ad6d | ||
|
|
ed4267df50 | ||
|
|
1afeac4b95 | ||
|
|
1c761737b6 | ||
|
|
a159db74f6 | ||
|
|
ac781e51ec | ||
|
|
e050af31af | ||
|
|
9ca1b8dae0 | ||
|
|
a59ab44199 | ||
|
|
45d4a67ff4 | ||
|
|
97f5131ce0 | ||
|
|
2d4ddd8bd1 | ||
|
|
c94e49ed08 | ||
|
|
30a72b1227 | ||
|
|
b5ac7752d4 | ||
|
|
04ed7e14e2 | ||
|
|
d168926f98 | ||
|
|
2a8887d0b4 | ||
|
|
f7f6b74fd3 | ||
|
|
7609a49c17 | ||
|
|
213db08566 | ||
|
|
ba2fbd99a8 | ||
|
|
8ed681d82e | ||
|
|
1032f10d85 | ||
|
|
4fc46ac814 | ||
|
|
1611fb00d8 | ||
|
|
57a1f2743e | ||
|
|
fd1a1d326c | ||
|
|
ca7fdacfeb | ||
|
|
80f05d7467 | ||
|
|
e84604f7e3 | ||
|
|
66c3013e39 | ||
|
|
717802fe54 | ||
|
|
977a840253 | ||
|
|
6051d4d358 | ||
|
|
0a00a8a109 | ||
|
|
9d1aff3a75 | ||
|
|
3332279e75 |
19
.github/CODEOWNERS
vendored
@@ -1,7 +1,20 @@
|
||||
# Last match in file takes precedence.
|
||||
|
||||
# Ping for all PRs
|
||||
* @Acruid @PJB3005 @Silvertorch5
|
||||
|
||||
/Robust.*/Audio/Midi/ @Zumorica
|
||||
|
||||
/Robust.Client.NameGenerator @PaulRitter
|
||||
/Robust.Client.Injectors @PaulRitter
|
||||
/Robust.Generators @PaulRitter
|
||||
/Robust.Analyzers @PaulRitter
|
||||
/Robust.*/GameStates @PaulRitter
|
||||
/Robust.Shared/Analyzers @PaulRitter
|
||||
/Robust.*/Serialization @PaulRitter
|
||||
/Robust.*/Prototypes @PaulRitter
|
||||
/Robust.Shared/GameObjects/ComponentDependencies @PaulRitter
|
||||
/Robust.*/Containers @PaulRitter
|
||||
|
||||
# Be they Fluent translations or Freemarker templates, I know them both!
|
||||
*.ftl @RemieRichards
|
||||
|
||||
# Ping for all PRs
|
||||
* @Acruid @PJB3005 @Silvertorch5
|
||||
22
.gitignore
vendored
@@ -41,18 +41,6 @@ _ReSharper*/
|
||||
|
||||
# Resources
|
||||
*.resources
|
||||
/Resources/textures/Animations/*.*
|
||||
/Resources/ResourcePack.zip
|
||||
/Resources/textures/*_Animations.png
|
||||
/Resources/textures/*_Decals.png
|
||||
/Resources/textures/*_Effects.png
|
||||
/Resources/textures/*_Items.png
|
||||
/Resources/textures/*_Objects.png
|
||||
/Resources/textures/*_Tiles.png
|
||||
/Resources/textures/*_UserInterface.png
|
||||
/Resources/textures/*.TAI
|
||||
/Resources/SpriteRenderer/Ogre.log
|
||||
/Resources/Spriterenderer/output
|
||||
/Media
|
||||
/setenv.bat
|
||||
|
||||
@@ -78,16 +66,6 @@ project.lock.json
|
||||
# Created by NUnit.
|
||||
TestResult.xml
|
||||
|
||||
NetSerializerDebug.dll
|
||||
|
||||
# We're not gonna ship Mac extlibs with the repo due to size. (11 MB)
|
||||
Third-Party/extlibs/Mac/
|
||||
# Or the automatically-fetched Windows natives, for that matter.
|
||||
Third-Party/extlibs/Windows/
|
||||
|
||||
# Actually I'll make this folder because SS14.Shared.Bsdiff isn't third-party is it?
|
||||
Dependencies/
|
||||
|
||||
# Python stuff
|
||||
__pycache__
|
||||
.mypy_cache
|
||||
|
||||
3
.gitmodules
vendored
@@ -13,9 +13,6 @@
|
||||
[submodule "ManagedHttpListener"]
|
||||
path = ManagedHttpListener
|
||||
url = https://github.com/space-wizards/ManagedHttpListener.git
|
||||
[submodule "Linguini"]
|
||||
path = Linguini
|
||||
url = https://github.com/space-wizards/Linguini
|
||||
[submodule "cefglue"]
|
||||
path = cefglue
|
||||
url = https://github.com/space-wizards/cefglue.git
|
||||
|
||||
1
Linguini
@@ -1,4 +1,4 @@
|
||||
<Project>
|
||||
<!-- This file automatically reset by Tools/version.py -->
|
||||
<PropertyGroup><Version>0.8.2</Version></PropertyGroup>
|
||||
<PropertyGroup><Version>0.8.52</Version></PropertyGroup>
|
||||
</Project>
|
||||
|
||||
8
Resources/.gitignore
vendored
@@ -1,8 +0,0 @@
|
||||
# .import files are made by Godot because the assets are exposed if using symlinks.
|
||||
# IF you need to persist a .import file because of something used Godot-side (GUI-side),
|
||||
# you can do a negation with !.
|
||||
*.import
|
||||
# Negation would be like this:
|
||||
#!/Textures/UserInterface/1pxwhite.png.import
|
||||
!/Scenes/SS14Window/closewindow.png.import
|
||||
/I_MADE_THE_SYMLINK
|
||||
1
Resources/Locale/en-US/defaultwindow.ftl
Normal file
@@ -0,0 +1 @@
|
||||
defaultwindow-placeholder-title = Exemplary Window Title Here
|
||||
@@ -1 +0,0 @@
|
||||
ss14window-placeholder-title = Exemplary Window Title Here
|
||||
|
Before Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 927 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 14 KiB |
@@ -1,2 +0,0 @@
|
||||
sample:
|
||||
filter: true
|
||||
@@ -1,152 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="113.67364mm"
|
||||
height="56.37999mm"
|
||||
viewBox="0 0 113.67364 56.37999"
|
||||
version="1.1"
|
||||
id="svg3223"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="logo.svg"
|
||||
inkscape:export-filename="/home/pj/Projects/space-station-14/RobustToolbox/Resources/Textures/Logo/logo.png"
|
||||
inkscape:export-xdpi="67.034012"
|
||||
inkscape:export-ydpi="67.034012">
|
||||
<defs
|
||||
id="defs3217" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.98994949"
|
||||
inkscape:cx="159.25688"
|
||||
inkscape:cy="149.8376"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:pagecheckerboard="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1043"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata3220">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-56.556041,-109.30405)">
|
||||
<g
|
||||
transform="translate(-3.7799155,-23.482217)"
|
||||
id="g2559">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path148"
|
||||
style="fill:#e23229;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.34773216"
|
||||
d="m 143.44393,145.03077 0.1484,-0.70241 5.14257,-0.35974 -6.23062,29.75753 -0.69199,0.0483 6.08255,-29.05476 z m 1.18682,31.16724 7.31835,-35.07438 -10.43302,0.72923 -1.28514,6.12249 4.45021,-0.31125 -6.03235,28.95253 z" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccccccccccccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path152"
|
||||
style="fill:#e23229;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.34773216"
|
||||
d="m 169.25392,142.53363 -3.53672,16.8925 4.79124,-0.32874 -0.15681,0.75402 -4.79234,0.32881 -2.53549,12.11072 -0.75405,0.052 2.53724,-12.11108 -11.37332,0.78724 z m -18.98495,21.327 11.37324,-0.78724 -2.5247,12.11146 5.98312,-0.41839 2.52513,-12.10406 4.82658,-0.33116 1.26721,-6.07903 -4.82564,0.33109 3.52398,-16.89101 -4.56014,0.33565 -16.70168,19.60839 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path156"
|
||||
style="fill:#fefefe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.34773216"
|
||||
d="m 88.591903,151.83158 -2.595368,0.18103 0.741705,-3.62685 2.595079,-0.182 z m -4.581719,-6.72375 -3.99857,19.05572 3.468889,-0.24195 1.774487,-8.38766 6.064403,-0.42299 2.224789,-10.66981 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path160"
|
||||
style="fill:#fefefe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.34773216"
|
||||
d="m 100.85029,147.82177 2.83371,-0.19837 -0.74166,3.60045 -2.83371,0.19836 z m -6.726869,15.77696 3.469312,-0.24198 1.774487,-8.38695 2.8337,-0.19837 -1.77453,8.38695 3.46938,-0.24296 3.99895,-19.05608 -9.771974,0.68329 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path164"
|
||||
style="fill:#fefefe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.34773216"
|
||||
d="m 108.80467,162.68768 9.74554,-0.68118 1.377,-6.50502 -3.4693,0.24296 -0.63527,2.9832 -2.80718,0.19654 2.51548,-12.01379 2.80731,-0.19754 -0.50239,2.4195 3.46902,-0.24294 1.24513,-5.93998 -9.74589,0.68119 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path168"
|
||||
style="fill:#fefefe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.34773216"
|
||||
d="m 135.66767,145.61788 0.7409,-3.5211 -8.95132,0.6259 -3.99824,19.0564 8.95097,-0.62626 0.74082,-3.52077 -5.4816,0.383 1.03272,-4.89224 3.78675,-0.26474 0.74189,-3.52113 -3.78675,0.26474 0.74081,-3.6011 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path172"
|
||||
style="fill:#d5d5d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.34773216"
|
||||
d="m 71.070134,172.95255 -4.734664,0.33077 0.57447,-2.73456 2.139294,-0.14973 -0.376241,1.80924 2.595442,-0.18103 0.930868,-4.44332 -7.330114,0.5118 -1.66358,8.00131 4.734672,-0.33077 -0.773014,3.62025 -2.119829,0.1484 0.475696,-2.23174 -2.614982,0.18237 -1.030327,4.86616 7.330104,-0.5118 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path176"
|
||||
style="fill:#d5d5d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.34773216"
|
||||
d="m 74.794828,169.99754 2.496095,-0.17422 -2.436556,11.62085 2.595151,-0.182 2.436903,-11.62086 2.496023,-0.17421 0.554678,-2.63441 -7.587516,0.53064 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path180"
|
||||
style="fill:#d5d5d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.34773216"
|
||||
d="m 87.573322,171.75893 0.554606,-2.69318 2.119754,-0.1484 -0.554978,2.69354 z m 2.832629,8.59803 2.991888,-14.25529 -7.310379,0.51154 -2.99153,14.25493 2.595227,-0.18201 1.327293,-6.27378 2.11968,-0.14839 -1.327288,6.27414 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path184"
|
||||
style="fill:#d5d5d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.34773216"
|
||||
d="m 98.977684,179.78056 2.436926,-11.62086 2.49608,-0.1752 0.55493,-2.63374 -7.587518,0.53065 -0.554634,2.63373 2.495947,-0.17421 -2.436599,11.6212 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path188"
|
||||
style="fill:#d5d5d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.34773216"
|
||||
d="m 104.62426,179.38562 2.5951,-0.18101 2.9915,-14.25528 -2.59522,0.182 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path192"
|
||||
style="fill:#d5d5d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.34773216"
|
||||
d="m 115.73198,167.18138 2.11975,-0.14839 -1.88236,8.98749 -2.11949,0.14838 z m -5.03203,11.80203 7.31001,-0.51042 2.99153,-14.25494 -7.31028,0.51044 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path196"
|
||||
style="fill:#d5d5d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.34773216"
|
||||
d="m 124.08538,178.07141 1.36653,-6.47511 1.18856,6.29603 2.25853,-0.15792 2.99192,-14.25493 -2.59522,0.18201 -1.36734,6.57353 -1.18854,-6.39514 -2.25854,0.15791 -2.99084,14.25493 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path200"
|
||||
style="fill:#fefefe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.34773216"
|
||||
d="m 66.677649,158.65784 -1.377018,6.50538 9.798398,-0.68471 2.489415,-11.87958 -6.329111,0.44214 0.767747,-3.65465 2.860076,-0.20018 -0.503204,2.41917 3.469299,-0.24297 1.244526,-5.93996 -4.328229,0.30289 -8.728772,0.56991 2.909827,1.489 -1.87565,9.01912 6.329037,-0.44213 -1.032406,4.83973 -2.833645,0.19738 0.635302,-2.98354 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path204"
|
||||
style="fill:#e23229;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.34773216"
|
||||
d="m 70.519326,139.92277 -0.277457,1.36553 103.473271,-7.11317 0.29445,-1.38886 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path208"
|
||||
style="fill:#e23229;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.34773216"
|
||||
d="m 60.335956,189.16626 103.473274,-7.11356 0.29444,-1.38885 -103.489968,7.13649 z" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1772"
|
||||
d="m 167.92741,145.26275 -12.87687,14.89523 9.91366,-0.68019 z m -3.743,7.27758 -1.02896,4.93612 -3.51544,0.2412 z"
|
||||
style="fill:#e23229;fill-opacity:1;stroke:none;stroke-width:0.2626844px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 8.4 KiB |
@@ -1,10 +1,14 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace Robust.Generators
|
||||
namespace Robust.Analyzers;
|
||||
|
||||
public static class Diagnostics
|
||||
{
|
||||
public static class Diagnostics
|
||||
{
|
||||
public static SuppressionDescriptor MeansImplicitAssignment =>
|
||||
new SuppressionDescriptor("RADC1000", "CS0649", "Marked as implicitly assigned.");
|
||||
}
|
||||
public const string IdExplicitInterface = "RA0000";
|
||||
public const string IdSerializable = "RA0001";
|
||||
public const string IdFriend = "RA0002";
|
||||
public const string IdExplicitVirtual = "RA0003";
|
||||
|
||||
public static SuppressionDescriptor MeansImplicitAssignment =>
|
||||
new SuppressionDescriptor("RADC1000", "CS0649", "Marked as implicitly assigned.");
|
||||
}
|
||||
|
||||
@@ -24,14 +24,14 @@ namespace Robust.Analyzers
|
||||
SyntaxKind.OverrideKeyword
|
||||
};
|
||||
|
||||
public const string DiagnosticId = "RA0000";
|
||||
|
||||
private const string Title = "No explicit interface specified";
|
||||
private const string MessageFormat = "No explicit interface specified";
|
||||
private const string Description = "Make sure to specify the interface in your method-declaration.";
|
||||
private const string Category = "Usage";
|
||||
|
||||
[SuppressMessage("ReSharper", "RS2008")] private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, isEnabledByDefault: true, description: Description);
|
||||
[SuppressMessage("ReSharper", "RS2008")] private static readonly DiagnosticDescriptor Rule = new(
|
||||
Diagnostics.IdExplicitInterface,
|
||||
"No explicit interface specified",
|
||||
"No explicit interface specified",
|
||||
"Usage",
|
||||
DiagnosticSeverity.Warning,
|
||||
isEnabledByDefault: true,
|
||||
description: "Make sure to specify the interface in your method-declaration.");
|
||||
|
||||
private const string RequiresExplicitImplementationAttributeMetadataName =
|
||||
"Robust.Shared.Analyzers.RequiresExplicitImplementationAttribute";
|
||||
|
||||
176
Robust.Analyzers/ExplicitVirtualAnalyzer.cs
Normal file
@@ -0,0 +1,176 @@
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
|
||||
namespace Robust.Analyzers;
|
||||
|
||||
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||
public sealed class ExplicitVirtualAnalyzer : DiagnosticAnalyzer
|
||||
{
|
||||
internal const string Attribute = "Robust.Shared.Analyzers.VirtualAttribute";
|
||||
|
||||
[SuppressMessage("ReSharper", "RS2008")]
|
||||
private static readonly DiagnosticDescriptor Rule = new(
|
||||
Diagnostics.IdExplicitVirtual,
|
||||
"Class must be explicitly marked as [Virtual], abstract, static or sealed",
|
||||
"Class must be explicitly marked as [Virtual], abstract, static or sealed",
|
||||
"Usage",
|
||||
DiagnosticSeverity.Warning,
|
||||
isEnabledByDefault: true,
|
||||
description: "Class must be explicitly marked as [Virtual], abstract, static or sealed.");
|
||||
|
||||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);
|
||||
|
||||
public override void Initialize(AnalysisContext context)
|
||||
{
|
||||
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
|
||||
context.EnableConcurrentExecution();
|
||||
context.RegisterSyntaxNodeAction(AnalyzeNode, SyntaxKind.ClassDeclaration);
|
||||
}
|
||||
|
||||
private static bool HasAttribute(INamedTypeSymbol namedTypeSymbol, INamedTypeSymbol attrSymbol)
|
||||
{
|
||||
return namedTypeSymbol.GetAttributes()
|
||||
.Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, attrSymbol));
|
||||
}
|
||||
|
||||
private static void AnalyzeNode(SyntaxNodeAnalysisContext context)
|
||||
{
|
||||
var attrSymbol = context.Compilation.GetTypeByMetadataName(Attribute);
|
||||
var classDecl = (ClassDeclarationSyntax)context.Node;
|
||||
var classSymbol = context.SemanticModel.GetDeclaredSymbol(classDecl);
|
||||
if (classSymbol == null)
|
||||
return;
|
||||
|
||||
if (classSymbol.IsSealed || classSymbol.IsAbstract || classSymbol.IsStatic)
|
||||
return;
|
||||
|
||||
if (HasAttribute(classSymbol, attrSymbol))
|
||||
return;
|
||||
|
||||
var diag = Diagnostic.Create(Rule, classDecl.Keyword.GetLocation());
|
||||
context.ReportDiagnostic(diag);
|
||||
}
|
||||
}
|
||||
|
||||
// Doesn't work as I'd hoped: Roslyn doesn't provide an API for global usings and I can't get batch changes to work.
|
||||
/*
|
||||
[ExportCodeFixProvider(LanguageNames.CSharp)]
|
||||
public sealed class ExplicitVirtualCodeFixProvider : CodeFixProvider
|
||||
{
|
||||
private const string TitleSealed = "Annotate class as sealed.";
|
||||
private const string TitleVirtual = "Annotate class as [Virtual].";
|
||||
private const string TitleAbstract = "Annotate class as abstract.";
|
||||
private const string TitleStatic = "Annotate class as static.";
|
||||
|
||||
public override async Task RegisterCodeFixesAsync(CodeFixContext context)
|
||||
{
|
||||
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken);
|
||||
|
||||
foreach (var diagnostic in context.Diagnostics)
|
||||
{
|
||||
var span = diagnostic.Location.SourceSpan;
|
||||
var classDecl = root.FindToken(span.Start).Parent.AncestorsAndSelf().OfType<ClassDeclarationSyntax>()
|
||||
.First();
|
||||
|
||||
context.RegisterCodeFix(
|
||||
CodeAction.Create(
|
||||
TitleVirtual,
|
||||
c => FixVirtualAsync(context.Document, classDecl, c),
|
||||
TitleVirtual),
|
||||
diagnostic);
|
||||
|
||||
context.RegisterCodeFix(
|
||||
CodeAction.Create(
|
||||
TitleStatic,
|
||||
c => FixStaticAsync(context.Document, classDecl, c),
|
||||
TitleStatic),
|
||||
diagnostic);
|
||||
|
||||
context.RegisterCodeFix(
|
||||
CodeAction.Create(
|
||||
TitleSealed,
|
||||
c => FixSealedAsync(context.Document, classDecl, c),
|
||||
TitleSealed),
|
||||
diagnostic);
|
||||
|
||||
context.RegisterCodeFix(
|
||||
CodeAction.Create(
|
||||
TitleAbstract,
|
||||
c => FixAbstractAsync(context.Document, classDecl, c),
|
||||
TitleAbstract),
|
||||
diagnostic);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<Document> FixVirtualAsync(
|
||||
Document document,
|
||||
ClassDeclarationSyntax classDecl,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var ns = "Robust.Shared.Analyzers";
|
||||
var attrib = SyntaxFactory.Attribute(SyntaxFactory.ParseName("Virtual"));
|
||||
|
||||
var newClassDecl = classDecl.AddAttributeLists(
|
||||
SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList(new[] { attrib })));
|
||||
|
||||
var root = (CompilationUnitSyntax)await document.GetSyntaxRootAsync(cancellationToken);
|
||||
root = root.ReplaceNode(classDecl, newClassDecl);
|
||||
|
||||
var options = await document.GetOptionsAsync(cancellationToken);
|
||||
|
||||
if (root.Usings.All(u => u.Name.ToString() != ns))
|
||||
{
|
||||
root = root.AddUsings(SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(ns)));
|
||||
}
|
||||
|
||||
return document.WithSyntaxRoot(root);
|
||||
}
|
||||
|
||||
private async Task<Document> FixStaticAsync(
|
||||
Document document,
|
||||
ClassDeclarationSyntax classDecl,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var newClassDecl = classDecl.AddModifiers(SyntaxFactory.Token(SyntaxKind.StaticKeyword));
|
||||
|
||||
var root = (CompilationUnitSyntax)await document.GetSyntaxRootAsync(cancellationToken);
|
||||
root = root.ReplaceNode(classDecl, newClassDecl);
|
||||
|
||||
return document.WithSyntaxRoot(root);
|
||||
}
|
||||
|
||||
private async Task<Document> FixAbstractAsync(
|
||||
Document document,
|
||||
ClassDeclarationSyntax classDecl,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var newClassDecl = classDecl.AddModifiers(SyntaxFactory.Token(SyntaxKind.AbstractKeyword));
|
||||
|
||||
var root = (CompilationUnitSyntax)await document.GetSyntaxRootAsync(cancellationToken);
|
||||
root = root.ReplaceNode(classDecl, newClassDecl);
|
||||
|
||||
return document.WithSyntaxRoot(root);
|
||||
}
|
||||
|
||||
private async Task<Document> FixSealedAsync(
|
||||
Document document,
|
||||
ClassDeclarationSyntax classDecl,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var newClassDecl = classDecl.AddModifiers(SyntaxFactory.Token(SyntaxKind.SealedKeyword));
|
||||
|
||||
var root = (CompilationUnitSyntax)await document.GetSyntaxRootAsync(cancellationToken);
|
||||
root = root.ReplaceNode(classDecl, newClassDecl);
|
||||
|
||||
return document.WithSyntaxRoot(root);
|
||||
}
|
||||
|
||||
public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
|
||||
public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(Diagnostics.IdExplicitVirtual);
|
||||
}
|
||||
*/
|
||||
@@ -14,15 +14,15 @@ namespace Robust.Analyzers
|
||||
{
|
||||
const string FriendAttribute = "Robust.Shared.Analyzers.FriendAttribute";
|
||||
|
||||
public const string DiagnosticId = "RA0002";
|
||||
|
||||
private const string Title = "Tried to access friend-only member";
|
||||
private const string MessageFormat = "Tried to access member \"{0}\" in class \"{1}\" which can only be accessed by friend classes";
|
||||
private const string Description = "Make sure to specify the accessing class in the friends attribute.";
|
||||
private const string Category = "Usage";
|
||||
|
||||
[SuppressMessage("ReSharper", "RS2008")]
|
||||
private static readonly DiagnosticDescriptor Rule = new (DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Error, true, Description);
|
||||
private static readonly DiagnosticDescriptor Rule = new (
|
||||
Diagnostics.IdFriend,
|
||||
"Tried to access friend-only member",
|
||||
"Tried to access member \"{0}\" in class \"{1}\" which can only be accessed by friend classes",
|
||||
"Usage",
|
||||
DiagnosticSeverity.Error,
|
||||
true,
|
||||
"Make sure to specify the accessing class in the friends attribute.");
|
||||
|
||||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Robust.Generators;
|
||||
|
||||
namespace Robust.Analyzers
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<LangVersion>9</LangVersion>
|
||||
<LangVersion>10</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -17,19 +17,21 @@ namespace Robust.Analyzers
|
||||
public class SerializableAnalyzer : DiagnosticAnalyzer
|
||||
{
|
||||
// Metadata of the analyzer
|
||||
public const string DiagnosticId = "RA0001";
|
||||
|
||||
// You could use LocalizedString but it's a little more complicated for this sample
|
||||
private const string Title = "Class not marked as (Net)Serializable";
|
||||
private const string MessageFormat = "Class not marked as (Net)Serializable";
|
||||
private const string Description = "The class should be marked as (Net)Serializable.";
|
||||
private const string Category = "Usage";
|
||||
|
||||
private const string RequiresSerializableAttributeMetadataName = "Robust.Shared.Analyzers.RequiresSerializableAttribute";
|
||||
private const string SerializableAttributeMetadataName = "System.SerializableAttribute";
|
||||
private const string NetSerializableAttributeMetadataName = "Robust.Shared.Serialization.NetSerializableAttribute";
|
||||
|
||||
[SuppressMessage("ReSharper", "RS2008")] private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, isEnabledByDefault: true, description: Description);
|
||||
[SuppressMessage("ReSharper", "RS2008")] private static readonly DiagnosticDescriptor Rule = new(
|
||||
Diagnostics.IdSerializable,
|
||||
"Class not marked as (Net)Serializable",
|
||||
"Class not marked as (Net)Serializable",
|
||||
"Usage",
|
||||
DiagnosticSeverity.Warning,
|
||||
isEnabledByDefault: true,
|
||||
description: "The class should be marked as (Net)Serializable.");
|
||||
|
||||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);
|
||||
|
||||
@@ -139,7 +141,8 @@ namespace Robust.Analyzers
|
||||
return document.WithSyntaxRoot(root);
|
||||
}
|
||||
|
||||
public sealed override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(SerializableAnalyzer.DiagnosticId);
|
||||
public sealed override ImmutableArray<string> FixableDiagnosticIds
|
||||
=> ImmutableArray.Create(Diagnostics.IdSerializable);
|
||||
|
||||
public override FixAllProvider GetFixAllProvider()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Robust.Shared.Analyzers;
|
||||
|
||||
namespace Robust.Benchmarks.NumericsHelpers
|
||||
{
|
||||
[Virtual]
|
||||
public class AddBenchmark
|
||||
{
|
||||
[Params(32, 128)]
|
||||
|
||||
@@ -4,7 +4,7 @@ using System;
|
||||
|
||||
namespace Robust.Benchmarks
|
||||
{
|
||||
internal class Program
|
||||
internal static class Program
|
||||
{
|
||||
// --allCategories=ctg1,ctg2
|
||||
// --anyCategories=ctg1,ctg2
|
||||
|
||||
@@ -9,7 +9,7 @@ using Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||
|
||||
namespace Robust.Benchmarks.Serialization
|
||||
{
|
||||
public class BenchmarkIntSerializer : ITypeSerializer<int, ValueDataNode>
|
||||
public sealed class BenchmarkIntSerializer : ITypeSerializer<int, ValueDataNode>
|
||||
{
|
||||
public ValidationNode Validate(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, ISerializationContext? context = null)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Linq;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Robust.Benchmarks.Serialization.Definitions;
|
||||
using Robust.Shared.Analyzers;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
@@ -13,6 +14,7 @@ using YamlDotNet.RepresentationModel;
|
||||
namespace Robust.Benchmarks.Serialization.Copy
|
||||
{
|
||||
[MemoryDiagnoser]
|
||||
[Virtual]
|
||||
public class SerializationCopyBenchmark : SerializationBenchmark
|
||||
{
|
||||
public SerializationCopyBenchmark()
|
||||
|
||||
@@ -3,7 +3,7 @@ using Robust.Shared.Serialization;
|
||||
|
||||
namespace Robust.Benchmarks.Serialization.Definitions
|
||||
{
|
||||
public class BenchmarkFlags
|
||||
public sealed class BenchmarkFlags
|
||||
{
|
||||
public const int Zero = 1 << 0;
|
||||
public const int ThirtyOne = 1 << 31;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Analyzers;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
namespace Robust.Benchmarks.Serialization.Definitions
|
||||
{
|
||||
[DataDefinition]
|
||||
[Virtual]
|
||||
public class DataDefinitionWithString
|
||||
{
|
||||
[DataField("string")]
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Robust.Benchmarks.Serialization.Definitions
|
||||
/// Taken from content.
|
||||
/// </summary>
|
||||
[Prototype("seed")]
|
||||
public class SeedDataDefinition : IPrototype
|
||||
public sealed class SeedDataDefinition : IPrototype
|
||||
{
|
||||
public const string Prototype = @"
|
||||
- type: seed
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Robust.Shared.Analyzers;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
|
||||
namespace Robust.Benchmarks.Serialization.Initialize
|
||||
{
|
||||
[MemoryDiagnoser]
|
||||
[Virtual]
|
||||
public class SerializationInitializeBenchmark : SerializationBenchmark
|
||||
{
|
||||
[IterationCleanup]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.IO;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Robust.Benchmarks.Serialization.Definitions;
|
||||
using Robust.Shared.Analyzers;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
@@ -12,6 +13,7 @@ using YamlDotNet.RepresentationModel;
|
||||
namespace Robust.Benchmarks.Serialization.Read
|
||||
{
|
||||
[MemoryDiagnoser]
|
||||
[Virtual]
|
||||
public class SerializationReadBenchmark : SerializationBenchmark
|
||||
{
|
||||
public SerializationReadBenchmark()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Robust.Benchmarks.Serialization.Definitions;
|
||||
using Robust.Shared.Analyzers;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -7,6 +8,7 @@ using Robust.Shared.Serialization.Markdown.Value;
|
||||
namespace Robust.Benchmarks.Serialization
|
||||
{
|
||||
[MemoryDiagnoser]
|
||||
[Virtual]
|
||||
public class SerializationArrayBenchmark : SerializationBenchmark
|
||||
{
|
||||
public SerializationArrayBenchmark()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.IO;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Robust.Benchmarks.Serialization.Definitions;
|
||||
using Robust.Shared.Analyzers;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
@@ -13,6 +14,7 @@ using YamlDotNet.RepresentationModel;
|
||||
namespace Robust.Benchmarks.Serialization.Write
|
||||
{
|
||||
[MemoryDiagnoser]
|
||||
[Virtual]
|
||||
public class SerializationWriteBenchmark : SerializationBenchmark
|
||||
{
|
||||
public SerializationWriteBenchmark()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Robust.Shared.ContentPack;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
@@ -10,6 +11,8 @@ namespace Robust.Client.WebView.Cef
|
||||
{
|
||||
internal partial class WebViewManagerCef : IWebViewManagerImpl
|
||||
{
|
||||
private static readonly string BasePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location!)!;
|
||||
|
||||
private CefApp _app = default!;
|
||||
|
||||
[Dependency] private readonly IDependencyCollection _dependencyCollection = default!;
|
||||
@@ -27,7 +30,7 @@ namespace Robust.Client.WebView.Cef
|
||||
else
|
||||
throw new NotSupportedException("Unsupported platform for CEF!");
|
||||
|
||||
var subProcessPath = PathHelpers.ExecutableRelativeFile(subProcessName);
|
||||
var subProcessPath = Path.Combine(BasePath, subProcessName);
|
||||
var cefResourcesPath = LocateCefResources();
|
||||
|
||||
// System.Console.WriteLine(AppContext.GetData("NATIVE_DLL_SEARCH_DIRECTORIES"));
|
||||
@@ -60,7 +63,7 @@ namespace Robust.Client.WebView.Cef
|
||||
|
||||
private static string? LocateCefResources()
|
||||
{
|
||||
if (ProbeDir(PathHelpers.GetExecutableDirectory(), out var path))
|
||||
if (ProbeDir(BasePath, out var path))
|
||||
return path;
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2020.3.0" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="5.0.2" />
|
||||
<PackageReference Include="Robust.Natives.Cef" Version="95.7.14" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ using Robust.Shared.Animations;
|
||||
|
||||
namespace Robust.Client.Animations
|
||||
{
|
||||
public class AnimationTrackControlProperty : AnimationTrackProperty
|
||||
public sealed class AnimationTrackControlProperty : AnimationTrackProperty
|
||||
{
|
||||
public string? Property { get; set; }
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace Robust.Client.Audio.Midi
|
||||
void Shutdown();
|
||||
}
|
||||
|
||||
internal class MidiManager : IMidiManager
|
||||
internal sealed class MidiManager : IMidiManager
|
||||
{
|
||||
[Dependency] private readonly IEyeManager _eyeManager = default!;
|
||||
[Dependency] private readonly IResourceManagerInternal _resourceManager = default!;
|
||||
@@ -293,60 +293,50 @@ namespace Robust.Client.Audio.Midi
|
||||
}
|
||||
|
||||
MapCoordinates? mapPos = null;
|
||||
var trackingEntity = renderer.TrackingEntity != null && !_entityManager.Deleted(renderer.TrackingEntity);
|
||||
if (trackingEntity)
|
||||
{
|
||||
renderer.TrackingCoordinates = _entityManager.GetComponent<TransformComponent>(renderer.TrackingEntity!.Value).Coordinates;
|
||||
}
|
||||
|
||||
if (renderer.TrackingCoordinates != null)
|
||||
{
|
||||
mapPos = renderer.TrackingCoordinates.Value.ToMap(_entityManager);
|
||||
}
|
||||
else if (renderer.TrackingEntity != null)
|
||||
{
|
||||
mapPos = _entityManager.GetComponent<TransformComponent>(renderer.TrackingEntity.Value).MapPosition;
|
||||
}
|
||||
|
||||
if (mapPos != null)
|
||||
if (mapPos != null && mapPos.Value.MapId == _eyeManager.CurrentMap)
|
||||
{
|
||||
var pos = mapPos.Value;
|
||||
if (pos.MapId != _eyeManager.CurrentMap)
|
||||
{
|
||||
renderer.Source.SetVolume(-10000000);
|
||||
}
|
||||
else
|
||||
{
|
||||
var sourceRelative = _eyeManager.CurrentEye.Position.Position - pos.Position;
|
||||
var occlusion = 0f;
|
||||
if (sourceRelative.Length > 0)
|
||||
{
|
||||
occlusion = _broadPhaseSystem.IntersectRayPenetration(
|
||||
pos.MapId,
|
||||
new CollisionRay(
|
||||
pos.Position,
|
||||
sourceRelative.Normalized,
|
||||
OcclusionCollisionMask),
|
||||
sourceRelative.Length,
|
||||
renderer.TrackingEntity);
|
||||
}
|
||||
|
||||
renderer.Source.SetOcclusion(occlusion);
|
||||
var sourceRelative = _eyeManager.CurrentEye.Position.Position - pos.Position;
|
||||
var occlusion = 0f;
|
||||
if (sourceRelative.Length > 0)
|
||||
{
|
||||
occlusion = _broadPhaseSystem.IntersectRayPenetration(
|
||||
pos.MapId,
|
||||
new CollisionRay(
|
||||
pos.Position,
|
||||
sourceRelative.Normalized,
|
||||
OcclusionCollisionMask),
|
||||
sourceRelative.Length,
|
||||
renderer.TrackingEntity);
|
||||
}
|
||||
|
||||
if (renderer.Source.SetPosition(pos.Position))
|
||||
renderer.Source.SetOcclusion(occlusion);
|
||||
|
||||
if (!renderer.Source.SetPosition(pos.Position))
|
||||
{
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
if (renderer.TrackingEntity != null)
|
||||
if (trackingEntity)
|
||||
{
|
||||
renderer.Source.SetVelocity(renderer.TrackingEntity.Value.GlobalLinearVelocity());
|
||||
renderer.Source.SetVelocity(renderer.TrackingEntity!.Value.GlobalLinearVelocity());
|
||||
}
|
||||
|
||||
if (float.IsNaN(pos.Position.X) || float.IsNaN(pos.Position.Y))
|
||||
{
|
||||
// just duck out instead of move to NaN
|
||||
renderer.Source.SetOcclusion(float.MaxValue);
|
||||
continue;
|
||||
}
|
||||
|
||||
_midiSawmill?.Warning("Interrupting positional audio, can't set position.");
|
||||
renderer.Source.StopPlaying();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderer.Source.SetOcclusion(float.MaxValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,7 +392,7 @@ namespace Robust.Client.Audio.Midi
|
||||
/// <summary>
|
||||
/// This class is used to load soundfonts.
|
||||
/// </summary>
|
||||
private class ResourceLoaderCallbacks : SoundFontLoaderCallbacks
|
||||
private sealed class ResourceLoaderCallbacks : SoundFontLoaderCallbacks
|
||||
{
|
||||
private readonly Dictionary<int, Stream> _openStreams = new();
|
||||
private int _nextStreamId = 1;
|
||||
|
||||
@@ -180,7 +180,7 @@ namespace Robust.Client.Audio.Midi
|
||||
internal void InternalDispose();
|
||||
}
|
||||
|
||||
internal class MidiRenderer : IMidiRenderer
|
||||
internal sealed class MidiRenderer : IMidiRenderer
|
||||
{
|
||||
[Dependency] private readonly IClydeAudio _clydeAudio = default!;
|
||||
[Dependency] private readonly ITaskManager _taskManager = default!;
|
||||
|
||||
@@ -20,7 +20,7 @@ using Robust.Shared.Utility;
|
||||
namespace Robust.Client
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public class BaseClient : IBaseClient
|
||||
public sealed class BaseClient : IBaseClient
|
||||
{
|
||||
[Dependency] private readonly IClientNetManager _net = default!;
|
||||
[Dependency] private readonly IPlayerManager _playMan = default!;
|
||||
@@ -291,7 +291,7 @@ namespace Robust.Client
|
||||
/// <summary>
|
||||
/// Event arguments for when something changed with the player.
|
||||
/// </summary>
|
||||
public class PlayerEventArgs : EventArgs
|
||||
public sealed class PlayerEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The session that triggered the event.
|
||||
@@ -310,7 +310,7 @@ namespace Robust.Client
|
||||
/// <summary>
|
||||
/// Event arguments for when the RunLevel has changed in the BaseClient.
|
||||
/// </summary>
|
||||
public class RunLevelChangedEventArgs : EventArgs
|
||||
public sealed class RunLevelChangedEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// RunLevel that the BaseClient switched from.
|
||||
@@ -335,7 +335,7 @@ namespace Robust.Client
|
||||
/// <summary>
|
||||
/// Info about the server and player that is sent to the client while connecting.
|
||||
/// </summary>
|
||||
public class ServerInfo
|
||||
public sealed class ServerInfo
|
||||
{
|
||||
public ServerInfo(string serverName)
|
||||
{
|
||||
|
||||
@@ -43,9 +43,9 @@ namespace Robust.Client
|
||||
IoCManager.Register<IGameTiming, ClientGameTiming>();
|
||||
IoCManager.Register<IClientGameTiming, ClientGameTiming>();
|
||||
IoCManager.Register<IPrototypeManager, ClientPrototypeManager>();
|
||||
IoCManager.Register<IMapManager, ClientMapManager>();
|
||||
IoCManager.Register<IMapManagerInternal, ClientMapManager>();
|
||||
IoCManager.Register<IClientMapManager, ClientMapManager>();
|
||||
IoCManager.Register<IMapManager, NetworkedMapManager>();
|
||||
IoCManager.Register<IMapManagerInternal, NetworkedMapManager>();
|
||||
IoCManager.Register<INetworkedMapManager, NetworkedMapManager>();
|
||||
IoCManager.Register<IEntityManager, ClientEntityManager>();
|
||||
IoCManager.Register<IEntityLookup, EntityLookup>();
|
||||
IoCManager.Register<IReflectionManager, ClientReflectionManager>();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Robust.Client.Console
|
||||
{
|
||||
public class ClientConGroupController : IClientConGroupController
|
||||
public sealed class ClientConGroupController : IClientConGroupController
|
||||
{
|
||||
private IClientConGroupImplementation? _implementation;
|
||||
public event Action? ConGroupUpdated;
|
||||
@@ -23,7 +23,7 @@ namespace Robust.Client.Console
|
||||
|
||||
public bool CanCommand(string cmdName)
|
||||
{
|
||||
return _implementation?.CanCommand(cmdName) ?? false;
|
||||
return _implementation?.CanCommand(cmdName) ?? true;
|
||||
}
|
||||
|
||||
public bool CanViewVar()
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Robust.Client.Log;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Network.Messages;
|
||||
@@ -11,7 +14,7 @@ using Robust.Shared.Utility;
|
||||
|
||||
namespace Robust.Client.Console
|
||||
{
|
||||
public class AddStringArgs : EventArgs
|
||||
public sealed class AddStringArgs : EventArgs
|
||||
{
|
||||
public string Text { get; }
|
||||
|
||||
@@ -27,7 +30,7 @@ namespace Robust.Client.Console
|
||||
}
|
||||
}
|
||||
|
||||
public class AddFormattedMessageArgs : EventArgs
|
||||
public sealed class AddFormattedMessageArgs : EventArgs
|
||||
{
|
||||
public readonly FormattedMessage Message;
|
||||
|
||||
@@ -38,8 +41,10 @@ namespace Robust.Client.Console
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IClientConsoleHost" />
|
||||
internal class ClientConsoleHost : ConsoleHost, IClientConsoleHost
|
||||
internal sealed class ClientConsoleHost : ConsoleHost, IClientConsoleHost
|
||||
{
|
||||
[Dependency] private readonly IClientConGroupController _conGroup = default!;
|
||||
|
||||
private bool _requestedCommands;
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -103,6 +108,14 @@ namespace Robust.Client.Console
|
||||
|
||||
if (AvailableCommands.ContainsKey(commandName))
|
||||
{
|
||||
var playerManager = IoCManager.Resolve<IPlayerManager>();
|
||||
|
||||
if (!_conGroup.CanCommand(commandName) && playerManager.LocalPlayer?.Session.Status > SessionStatus.Connecting)
|
||||
{
|
||||
WriteError(null, $"Insufficient perms for command: {commandName}");
|
||||
return;
|
||||
}
|
||||
|
||||
var command1 = AvailableCommands[commandName];
|
||||
args.RemoveAt(0);
|
||||
var shell = new ConsoleShell(this, null);
|
||||
@@ -196,7 +209,7 @@ namespace Robust.Client.Console
|
||||
/// These dummies are made purely so list and help can list server-side commands.
|
||||
/// </summary>
|
||||
[Reflect(false)]
|
||||
internal class ServerDummyCommand : IConsoleCommand
|
||||
internal sealed class ServerDummyCommand : IConsoleCommand
|
||||
{
|
||||
internal ServerDummyCommand(string command, string help, string description)
|
||||
{
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
public class SaveConfig : IConsoleCommand
|
||||
public sealed class SaveConfig : IConsoleCommand
|
||||
{
|
||||
public string Command => "saveconfig";
|
||||
public string Description => "Saves the client configuration to the config file";
|
||||
|
||||
@@ -6,7 +6,7 @@ using Robust.Shared.Console;
|
||||
|
||||
namespace Robust.Client.Console.Commands
|
||||
{
|
||||
class ClearCommand : IConsoleCommand
|
||||
sealed class ClearCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "cls";
|
||||
public string Help => "Clears the debug console of all messages.";
|
||||
@@ -18,7 +18,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
class FillCommand : IConsoleCommand
|
||||
sealed class FillCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "fill";
|
||||
public string Help => "Fills the console with some nonsense for debugging.";
|
||||
|
||||
@@ -30,7 +30,7 @@ using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||
|
||||
namespace Robust.Client.Console.Commands
|
||||
{
|
||||
internal class DumpEntitiesCommand : IConsoleCommand
|
||||
internal sealed class DumpEntitiesCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "dumpentities";
|
||||
public string Help => "Dump entity list";
|
||||
@@ -47,7 +47,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class GetComponentRegistrationCommand : IConsoleCommand
|
||||
internal sealed class GetComponentRegistrationCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "getcomponentregistration";
|
||||
public string Help => "Usage: getcomponentregistration <componentName>";
|
||||
@@ -93,7 +93,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class ToggleMonitorCommand : IConsoleCommand
|
||||
internal sealed class ToggleMonitorCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "monitor";
|
||||
|
||||
@@ -148,7 +148,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class ExceptionCommand : IConsoleCommand
|
||||
internal sealed class ExceptionCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "fuck";
|
||||
public string Help => "Throws an exception";
|
||||
@@ -160,7 +160,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class ShowPositionsCommand : IConsoleCommand
|
||||
internal sealed class ShowPositionsCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "showpos";
|
||||
public string Help => "";
|
||||
@@ -173,7 +173,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class ShowRayCommand : IConsoleCommand
|
||||
internal sealed class ShowRayCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "showrays";
|
||||
public string Help => "Usage: showrays <raylifetime>";
|
||||
@@ -200,7 +200,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class DisconnectCommand : IConsoleCommand
|
||||
internal sealed class DisconnectCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "disconnect";
|
||||
public string Help => "";
|
||||
@@ -212,7 +212,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class EntityInfoCommand : IConsoleCommand
|
||||
internal sealed class EntityInfoCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "entfo";
|
||||
|
||||
@@ -264,7 +264,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class SnapGridGetCell : IConsoleCommand
|
||||
internal sealed class SnapGridGetCell : IConsoleCommand
|
||||
{
|
||||
public string Command => "sggcell";
|
||||
public string Help => "sggcell <gridID> <vector2i>\nThat vector2i param is in the form x<int>,y<int>.";
|
||||
@@ -313,7 +313,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class SetPlayerName : IConsoleCommand
|
||||
internal sealed class SetPlayerName : IConsoleCommand
|
||||
{
|
||||
public string Command => "overrideplayername";
|
||||
public string Description => "Changes the name used when attempting to connect to the server.";
|
||||
@@ -333,7 +333,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class LoadResource : IConsoleCommand
|
||||
internal sealed class LoadResource : IConsoleCommand
|
||||
{
|
||||
public string Command => "ldrsc";
|
||||
public string Description => "Pre-caches a resource.";
|
||||
@@ -370,7 +370,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class ReloadResource : IConsoleCommand
|
||||
internal sealed class ReloadResource : IConsoleCommand
|
||||
{
|
||||
public string Command => "rldrsc";
|
||||
public string Description => "Reloads a resource.";
|
||||
@@ -404,7 +404,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class GridTileCount : IConsoleCommand
|
||||
internal sealed class GridTileCount : IConsoleCommand
|
||||
{
|
||||
public string Command => "gridtc";
|
||||
public string Description => "Gets the tile count of a grid";
|
||||
@@ -438,7 +438,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class GuiDumpCommand : IConsoleCommand
|
||||
internal sealed class GuiDumpCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "guidump";
|
||||
public string Description => "Dump GUI tree to /guidump.txt in user data.";
|
||||
@@ -449,15 +449,13 @@ namespace Robust.Client.Console.Commands
|
||||
var uiMgr = IoCManager.Resolve<IUserInterfaceManager>();
|
||||
var res = IoCManager.Resolve<IResourceManager>();
|
||||
|
||||
using (var stream = res.UserData.Create(new ResourcePath("/guidump.txt")))
|
||||
using (var writer = new StreamWriter(stream, EncodingHelpers.UTF8))
|
||||
using var writer = res.UserData.OpenWriteText(new ResourcePath("/guidump.txt"));
|
||||
|
||||
foreach (var root in uiMgr.AllRoots)
|
||||
{
|
||||
foreach (var root in uiMgr.AllRoots)
|
||||
{
|
||||
writer.WriteLine($"ROOT: {root}");
|
||||
_writeNode(root, 0, writer);
|
||||
writer.WriteLine("---------------");
|
||||
}
|
||||
writer.WriteLine($"ROOT: {root}");
|
||||
_writeNode(root, 0, writer);
|
||||
writer.WriteLine("---------------");
|
||||
}
|
||||
|
||||
shell.WriteLine("Saved guidump");
|
||||
@@ -514,7 +512,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class UITestCommand : IConsoleCommand
|
||||
internal sealed class UITestCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "uitest";
|
||||
public string Description => "Open a dummy UI testing window";
|
||||
@@ -522,7 +520,7 @@ namespace Robust.Client.Console.Commands
|
||||
|
||||
public void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
var window = new SS14Window { MinSize = (500, 400)};
|
||||
var window = new DefaultWindow { MinSize = (500, 400)};
|
||||
var tabContainer = new TabContainer();
|
||||
window.Contents.AddChild(tabContainer);
|
||||
var scroll = new ScrollContainer();
|
||||
@@ -646,7 +644,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class SetClipboardCommand : IConsoleCommand
|
||||
internal sealed class SetClipboardCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "setclipboard";
|
||||
public string Description => "Sets the system clipboard";
|
||||
@@ -659,7 +657,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class GetClipboardCommand : IConsoleCommand
|
||||
internal sealed class GetClipboardCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "getclipboard";
|
||||
public string Description => "Gets the system clipboard";
|
||||
@@ -672,7 +670,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class ToggleLight : IConsoleCommand
|
||||
internal sealed class ToggleLight : IConsoleCommand
|
||||
{
|
||||
public string Command => "togglelight";
|
||||
public string Description => "Toggles light rendering.";
|
||||
@@ -686,7 +684,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class ToggleFOV : IConsoleCommand
|
||||
internal sealed class ToggleFOV : IConsoleCommand
|
||||
{
|
||||
public string Command => "togglefov";
|
||||
public string Description => "Toggles fov for client.";
|
||||
@@ -700,7 +698,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class ToggleHardFOV : IConsoleCommand
|
||||
internal sealed class ToggleHardFOV : IConsoleCommand
|
||||
{
|
||||
public string Command => "togglehardfov";
|
||||
public string Description => "Toggles hard fov for client (for debugging space-station-14#2353).";
|
||||
@@ -714,7 +712,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class ToggleShadows : IConsoleCommand
|
||||
internal sealed class ToggleShadows : IConsoleCommand
|
||||
{
|
||||
public string Command => "toggleshadows";
|
||||
public string Description => "Toggles shadow rendering.";
|
||||
@@ -727,7 +725,7 @@ namespace Robust.Client.Console.Commands
|
||||
mgr.DrawShadows = !mgr.DrawShadows;
|
||||
}
|
||||
}
|
||||
internal class ToggleLightBuf : IConsoleCommand
|
||||
internal sealed class ToggleLightBuf : IConsoleCommand
|
||||
{
|
||||
public string Command => "togglelightbuf";
|
||||
public string Description => "Toggles lighting rendering. This includes shadows but not FOV.";
|
||||
@@ -741,7 +739,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class GcCommand : IConsoleCommand
|
||||
internal sealed class GcCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "gc";
|
||||
public string Description => "Run the GC.";
|
||||
@@ -763,7 +761,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class GcFullCommand : IConsoleCommand
|
||||
internal sealed class GcFullCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "gcf";
|
||||
public string Description => "Run the GC, fully, compacting LOH and everything.";
|
||||
@@ -776,7 +774,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class GcModeCommand : IConsoleCommand
|
||||
internal sealed class GcModeCommand : IConsoleCommand
|
||||
{
|
||||
|
||||
public string Command => "gc_mode";
|
||||
@@ -818,7 +816,7 @@ namespace Robust.Client.Console.Commands
|
||||
|
||||
}
|
||||
|
||||
internal class SerializeStatsCommand : IConsoleCommand
|
||||
internal sealed class SerializeStatsCommand : IConsoleCommand
|
||||
{
|
||||
|
||||
public string Command => "szr_stats";
|
||||
@@ -838,7 +836,7 @@ namespace Robust.Client.Console.Commands
|
||||
|
||||
}
|
||||
|
||||
internal class ChunkInfoCommand : IConsoleCommand
|
||||
internal sealed class ChunkInfoCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "chunkinfo";
|
||||
public string Description => "Gets info about a chunk under your mouse cursor.";
|
||||
@@ -867,7 +865,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class ReloadShadersCommand : IConsoleCommand
|
||||
internal sealed class ReloadShadersCommand : IConsoleCommand
|
||||
{
|
||||
|
||||
public string Command => "rldshader";
|
||||
@@ -1038,7 +1036,7 @@ namespace Robust.Client.Console.Commands
|
||||
|
||||
}
|
||||
|
||||
internal class ClydeDebugLayerCommand : IConsoleCommand
|
||||
internal sealed class ClydeDebugLayerCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "cldbglyr";
|
||||
public string Description => "Toggle fov and light debug layers";
|
||||
@@ -1063,7 +1061,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class GetKeyInfoCommand : IConsoleCommand
|
||||
internal sealed class GetKeyInfoCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "keyinfo";
|
||||
public string Description => "Keys key info for a key";
|
||||
|
||||
@@ -4,7 +4,7 @@ using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Robust.Client.Console.Commands
|
||||
{
|
||||
public class GridChunkBBCommand : IConsoleCommand
|
||||
public sealed class GridChunkBBCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "showchunkbb";
|
||||
public string Description => "Displays chunk bounds for the purposes of rendering";
|
||||
|
||||
@@ -5,7 +5,7 @@ using Robust.Shared.Network;
|
||||
|
||||
namespace Robust.Client.Console.Commands
|
||||
{
|
||||
class HelpCommand : IConsoleCommand
|
||||
sealed class HelpCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "help";
|
||||
public string Help => "When no arguments are provided, displays a generic help text. When an argument is passed, display the help text for the command with that name.";
|
||||
@@ -44,7 +44,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
class ListCommand : IConsoleCommand
|
||||
sealed class ListCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "list";
|
||||
public string Help => "Usage: list [filter]\n" +
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
#if !FULL_RELEASE
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.IoC;
|
||||
@@ -22,44 +20,38 @@ namespace Robust.Client.Console.Commands
|
||||
var wantName = args.Length > 0 ? args[0] : null;
|
||||
|
||||
var basePath = Path.GetDirectoryName(UserDataDir.GetUserDataDir())!;
|
||||
var cfgPath = Path.Combine(basePath, "launcher", "launcher_config.json");
|
||||
var dbPath = Path.Combine(basePath, "launcher", "settings.db");
|
||||
|
||||
var data = JsonSerializer.Deserialize<LauncherConfig>(File.ReadAllText(cfgPath))!;
|
||||
using var con = new SqliteConnection($"Data Source={dbPath};Mode=ReadOnly");
|
||||
con.Open();
|
||||
using var cmd = con.CreateCommand();
|
||||
cmd.CommandText = "SELECT UserId, UserName, Token FROM Login WHERE Expires > datetime('NOW')";
|
||||
|
||||
var login = wantName != null
|
||||
? data.Logins.FirstOrDefault(p => p.Username == wantName)
|
||||
: data.Logins.FirstOrDefault();
|
||||
if (wantName != null)
|
||||
{
|
||||
cmd.CommandText += " AND UserName = @userName";
|
||||
cmd.Parameters.AddWithValue("@userName", wantName);
|
||||
}
|
||||
|
||||
if (login == null)
|
||||
cmd.CommandText += " LIMIT 1;";
|
||||
|
||||
using var reader = cmd.ExecuteReader();
|
||||
|
||||
if (!reader.Read())
|
||||
{
|
||||
shell.WriteLine("Unable to find a matching login");
|
||||
return;
|
||||
}
|
||||
|
||||
var token = login.Token.Token;
|
||||
var userId = login.UserId;
|
||||
var userId = Guid.Parse(reader.GetString(0));
|
||||
var userName = reader.GetString(1);
|
||||
var token = reader.GetString(2);
|
||||
|
||||
var cfg = IoCManager.Resolve<IAuthManager>();
|
||||
cfg.Token = token;
|
||||
cfg.UserId = new NetUserId(Guid.Parse(userId));
|
||||
}
|
||||
cfg.UserId = new NetUserId(userId);
|
||||
|
||||
private sealed class LauncherConfig
|
||||
{
|
||||
[JsonInclude] [JsonPropertyName("logins")]
|
||||
public LauncherLogin[] Logins = default!;
|
||||
}
|
||||
|
||||
private sealed class LauncherLogin
|
||||
{
|
||||
[JsonInclude] public string Username = default!;
|
||||
[JsonInclude] public string UserId = default!;
|
||||
[JsonInclude] public LauncherToken Token = default!;
|
||||
}
|
||||
|
||||
private sealed class LauncherToken
|
||||
{
|
||||
[JsonInclude] public string Token = default!;
|
||||
shell.WriteLine($"Logged into account {userName}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ using Robust.Shared.Console;
|
||||
|
||||
namespace Robust.Client.Console.Commands
|
||||
{
|
||||
class LogSetLevelCommand : IConsoleCommand
|
||||
sealed class LogSetLevelCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "loglevel";
|
||||
public string Description => "Changes the log level for a provided sawmill.";
|
||||
@@ -40,7 +40,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
class TestLog : IConsoleCommand
|
||||
sealed class TestLog : IConsoleCommand
|
||||
{
|
||||
public string Command => "testlog";
|
||||
public string Description => "Writes a test log to a sawmill.";
|
||||
|
||||
@@ -4,7 +4,7 @@ using Robust.Shared.IoC;
|
||||
|
||||
namespace Robust.Client.Console.Commands
|
||||
{
|
||||
class HardQuitCommand : IConsoleCommand
|
||||
sealed class HardQuitCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "hardquit";
|
||||
public string Description => "Kills the game client instantly.";
|
||||
@@ -16,7 +16,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
class QuitCommand : IConsoleCommand
|
||||
sealed class QuitCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "quit";
|
||||
public string Description => "Shuts down the game client gracefully.";
|
||||
|
||||
@@ -6,7 +6,7 @@ using Robust.Shared.IoC;
|
||||
namespace Robust.Client.Console.Commands
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class SetInputContextCommand : IConsoleCommand
|
||||
public sealed class SetInputContextCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "setinputcontext";
|
||||
public string Description => "Sets the active input context.";
|
||||
|
||||
@@ -4,7 +4,7 @@ using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Robust.Client.Console.Commands
|
||||
{
|
||||
public class VelocitiesCommand : IConsoleCommand
|
||||
public sealed class VelocitiesCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "showvelocities";
|
||||
public string Description => "Displays your angular and linear velocities";
|
||||
|
||||
@@ -11,7 +11,7 @@ using static Robust.Shared.Network.Messages.MsgScriptCompletionResponse;
|
||||
|
||||
namespace Robust.Client.Console
|
||||
{
|
||||
public class Completions : SS14Window
|
||||
public sealed class Completions : DefaultWindow
|
||||
{
|
||||
private HistoryLineEdit _textBar;
|
||||
private ScrollContainer _suggestPanel = new()
|
||||
@@ -75,7 +75,7 @@ namespace Robust.Client.Console
|
||||
}
|
||||
|
||||
// Label and ghetto button.
|
||||
public class Entry : RichTextLabel
|
||||
public sealed class Entry : RichTextLabel
|
||||
{
|
||||
public readonly LiteResult Result;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ using Robust.Shared.Network.Messages;
|
||||
|
||||
namespace Robust.Client.Console
|
||||
{
|
||||
public partial class ScriptClient : IScriptClient
|
||||
public sealed partial class ScriptClient : IScriptClient
|
||||
{
|
||||
[Dependency] private readonly IClientConGroupController _conGroupController = default!;
|
||||
[Dependency] private readonly IClientNetManager _netManager = default!;
|
||||
|
||||
@@ -210,6 +210,23 @@ namespace Robust.Client.Console
|
||||
vvm.OpenVV(a);
|
||||
}
|
||||
|
||||
protected override void WriteSyntax(object toString)
|
||||
{
|
||||
var code = toString.ToString();
|
||||
|
||||
if (code == null)
|
||||
return;
|
||||
|
||||
var options = ScriptInstanceShared.GetScriptOptions(_owner._reflectionManager).AddReferences(typeof(Image).Assembly);
|
||||
var script = CSharpScript.Create(code, options, typeof(ScriptGlobals));
|
||||
script.Compile();
|
||||
|
||||
var syntax = new FormattedMessage();
|
||||
ScriptInstanceShared.AddWithSyntaxHighlighting(script, syntax, code, _owner._highlightWorkspace);
|
||||
|
||||
_owner.OutputPanel.AddMessage(syntax);
|
||||
}
|
||||
|
||||
public override void write(object toString)
|
||||
{
|
||||
_owner.OutputPanel.AddText(toString?.ToString() ?? "");
|
||||
|
||||
@@ -15,7 +15,7 @@ using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||
|
||||
namespace Robust.Client.Console
|
||||
{
|
||||
public class WatchWindow : SS14Window
|
||||
public sealed class WatchWindow : DefaultWindow
|
||||
{
|
||||
private readonly IReflectionManager _reflectionManager;
|
||||
|
||||
@@ -155,6 +155,11 @@ namespace Robust.Client.Console
|
||||
IoCManager.InjectDependencies(this);
|
||||
}
|
||||
|
||||
protected override void WriteSyntax(object toString)
|
||||
{
|
||||
// No-op: nothing to write to.
|
||||
}
|
||||
|
||||
public override void write(object toString)
|
||||
{
|
||||
// No-op: nothing to write to.
|
||||
|
||||
@@ -7,7 +7,7 @@ using Robust.Shared.Maths;
|
||||
namespace Robust.Client.Debugging
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public class DebugDrawing : IDebugDrawing
|
||||
public sealed class DebugDrawing : IDebugDrawing
|
||||
{
|
||||
[Dependency] private readonly IOverlayManager _overlayManager = default!;
|
||||
[Dependency] private readonly IEyeManager _eyeManager = default!;
|
||||
|
||||
@@ -207,10 +207,10 @@ namespace Robust.Client.Debugging
|
||||
|
||||
const float AlphaModifier = 0.2f;
|
||||
|
||||
foreach (var fixture in physBody.Fixtures)
|
||||
foreach (var fixture in _entityManager.GetComponent<FixturesComponent>(physBody.Owner).Fixtures.Values)
|
||||
{
|
||||
// Invalid shape - Box2D doesn't check for IsSensor
|
||||
if (physBody.BodyType == BodyType.Dynamic && fixture.Mass == 0f)
|
||||
// Invalid shape - Box2D doesn't check for IsSensor but we will for sanity.
|
||||
if (physBody.BodyType == BodyType.Dynamic && fixture.Mass == 0f && fixture.Hard)
|
||||
{
|
||||
DrawShape(worldHandle, fixture, xform, Color.Red.WithAlpha(AlphaModifier));
|
||||
}
|
||||
@@ -274,7 +274,7 @@ namespace Robust.Client.Debugging
|
||||
const float AlphaModifier = 0.2f;
|
||||
Box2? aabb = null;
|
||||
|
||||
foreach (var fixture in physBody.Fixtures)
|
||||
foreach (var fixture in _entityManager.GetComponent<FixturesComponent>(physBody.Owner).Fixtures.Values)
|
||||
{
|
||||
for (var i = 0; i < fixture.Shape.ChildCount; i++)
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Robust.Client
|
||||
{
|
||||
internal partial class GameController
|
||||
{
|
||||
internal class LoaderEntryPoint : ILoaderEntryPoint
|
||||
internal sealed class LoaderEntryPoint : ILoaderEntryPoint
|
||||
{
|
||||
public void Main(IMainArgs args)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Loader;
|
||||
using Robust.Client.WebViewHook;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -8,12 +10,8 @@ namespace Robust.Client
|
||||
{
|
||||
internal sealed partial class GameController
|
||||
{
|
||||
private void LoadOptionalRobustModules(GameController.DisplayMode mode)
|
||||
private void LoadOptionalRobustModules(DisplayMode mode, ResourceManifestData manifest)
|
||||
{
|
||||
// In the future, this manifest should be loaded somewhere else and used for more parts of init.
|
||||
// For now, this is fine.
|
||||
var manifest = LoadResourceManifest();
|
||||
|
||||
foreach (var module in manifest.Modules)
|
||||
{
|
||||
switch (module)
|
||||
@@ -32,7 +30,8 @@ namespace Robust.Client
|
||||
{
|
||||
Logger.Debug("Loading Robust.Client.WebView");
|
||||
|
||||
var assembly = LoadRobustModuleAssembly("Robust.Client.WebView");
|
||||
var alc = CreateModuleLoadContext("Robust.Client.WebView");
|
||||
var assembly = alc.LoadFromAssemblyName(new AssemblyName("Robust.Client.WebView"));
|
||||
var attribute = assembly.GetCustomAttribute<WebViewManagerImplAttribute>()!;
|
||||
DebugTools.AssertNotNull(attribute);
|
||||
|
||||
@@ -43,10 +42,52 @@ namespace Robust.Client
|
||||
Logger.Debug("Done initializing Robust.Client.WebView");
|
||||
}
|
||||
|
||||
private Assembly LoadRobustModuleAssembly(string assemblyName)
|
||||
/// <summary>
|
||||
/// Creates an <see cref="AssemblyLoadContext"/> that loads from an engine module directory.
|
||||
/// </summary>
|
||||
private AssemblyLoadContext CreateModuleLoadContext(string moduleName)
|
||||
{
|
||||
// TODO: Launcher distribution and all that stuff.
|
||||
return Assembly.Load(assemblyName);
|
||||
var sawmill = _logManager.GetSawmill("robust.mod");
|
||||
|
||||
var alc = new AssemblyLoadContext(moduleName);
|
||||
var envVarName = $"ROBUST_MODULE_{moduleName.ToUpperInvariant().Replace('.', '_')}";
|
||||
var envVar = Environment.GetEnvironmentVariable(envVarName);
|
||||
if (string.IsNullOrEmpty(envVar))
|
||||
{
|
||||
sawmill.Debug("Module {ModuleName} has no path override specified", moduleName);
|
||||
return alc;
|
||||
}
|
||||
|
||||
sawmill.Debug("Path for module {ModuleName} is {ModulePath}", moduleName, envVar);
|
||||
|
||||
alc.Resolving += (_, name) =>
|
||||
{
|
||||
sawmill.Debug("Loading {AssemblyName} from module {ModuleName}", name.ToString(), moduleName);
|
||||
var assemblyPath = Path.Combine(envVar, $"{name.Name}.dll");
|
||||
if (!File.Exists(assemblyPath))
|
||||
return null;
|
||||
|
||||
return alc.LoadFromAssemblyPath(assemblyPath);
|
||||
};
|
||||
|
||||
_modLoader.ExtraModuleLoaders += name =>
|
||||
{
|
||||
foreach (var assembly in alc.Assemblies)
|
||||
{
|
||||
var assemblyName = assembly.GetName();
|
||||
if (assemblyName.Name == name.Name)
|
||||
{
|
||||
sawmill.Debug("Resolved {ResolvingAssembly} as assembly {ResolvedAssembly} from {ModuleName}", name.ToString(), assemblyName.ToString(), moduleName);
|
||||
return assembly;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
_modLoader.AddEngineModuleDirectory(envVar);
|
||||
|
||||
return alc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,6 +79,8 @@ namespace Robust.Client
|
||||
public GameControllerOptions Options { get; private set; } = new();
|
||||
public InitialLaunchState LaunchState { get; private set; } = default!;
|
||||
|
||||
private ResourceManifestData? _resourceManifest;
|
||||
|
||||
public void SetCommandLineArgs(CommandLineArgs args)
|
||||
{
|
||||
_commandLineArgs = args;
|
||||
@@ -86,19 +88,25 @@ namespace Robust.Client
|
||||
|
||||
internal bool StartupContinue(DisplayMode displayMode)
|
||||
{
|
||||
DebugTools.AssertNotNull(_resourceManifest);
|
||||
|
||||
_clyde.InitializePostWindowing();
|
||||
_clydeAudio.InitializePostWindowing();
|
||||
_clyde.SetWindowTitle(Options.DefaultWindowTitle);
|
||||
_clyde.SetWindowTitle(Options.DefaultWindowTitle ?? _resourceManifest!.DefaultWindowTitle ?? "RobustToolbox");
|
||||
|
||||
_taskManager.Initialize();
|
||||
_fontManager.SetFontDpi((uint)_configurationManager.GetCVar(CVars.DisplayFontDpi));
|
||||
|
||||
// Load optional Robust modules.
|
||||
LoadOptionalRobustModules(displayMode, _resourceManifest!);
|
||||
|
||||
// Disable load context usage on content start.
|
||||
// This prevents Content.Client being loaded twice and things like csi blowing up because of it.
|
||||
_modLoader.SetUseLoadContext(!ContentStart);
|
||||
_modLoader.SetEnableSandboxing(Options.Sandboxing);
|
||||
|
||||
if (!_modLoader.TryLoadModulesFrom(Options.AssemblyDirectory, Options.ContentModulePrefix))
|
||||
var assemblyPrefix = Options.ContentModulePrefix ?? _resourceManifest!.AssemblyPrefix ?? "Content.";
|
||||
if (!_modLoader.TryLoadModulesFrom(Options.AssemblyDirectory, assemblyPrefix))
|
||||
{
|
||||
Logger.Fatal("Errors while loading content assemblies.");
|
||||
return false;
|
||||
@@ -111,9 +119,6 @@ namespace Robust.Client
|
||||
|
||||
IoCManager.Resolve<ISerializationManager>().Initialize();
|
||||
|
||||
// Load optional Robust modules.
|
||||
LoadOptionalRobustModules(displayMode);
|
||||
|
||||
// Call Init in game assemblies.
|
||||
_modLoader.BroadcastRunLevel(ModRunLevel.PreInit);
|
||||
_modLoader.BroadcastRunLevel(ModRunLevel.Init);
|
||||
@@ -129,8 +134,8 @@ namespace Robust.Client
|
||||
_prototypeManager.Initialize();
|
||||
_prototypeManager.LoadDirectory(Options.PrototypeDirectory);
|
||||
_prototypeManager.Resync();
|
||||
_mapManager.Initialize();
|
||||
_entityManager.Initialize();
|
||||
_mapManager.Initialize();
|
||||
_gameStateManager.Initialize();
|
||||
_placementManager.Initialize();
|
||||
_viewVariablesManager.Initialize();
|
||||
@@ -209,7 +214,7 @@ namespace Robust.Client
|
||||
{
|
||||
// Parses /manifest.yml for game-specific settings that cannot be exclusively set up by content code.
|
||||
if (!_resourceCache.TryContentFileRead("/manifest.yml", out var stream))
|
||||
return new ResourceManifestData(Array.Empty<string>());
|
||||
return new ResourceManifestData(Array.Empty<string>(), null, null, null, null);
|
||||
|
||||
var yamlStream = new YamlStream();
|
||||
using (stream)
|
||||
@@ -218,6 +223,9 @@ namespace Robust.Client
|
||||
yamlStream.Load(streamReader);
|
||||
}
|
||||
|
||||
if (yamlStream.Documents.Count == 0)
|
||||
return new ResourceManifestData(Array.Empty<string>(), null, null, null, null);
|
||||
|
||||
if (yamlStream.Documents.Count != 1 || yamlStream.Documents[0].RootNode is not YamlMappingNode mapping)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
@@ -235,7 +243,23 @@ namespace Robust.Client
|
||||
}
|
||||
}
|
||||
|
||||
return new ResourceManifestData(modules);
|
||||
string? assemblyPrefix = null;
|
||||
if (mapping.TryGetNode("assemblyPrefix", out var prefixNode))
|
||||
assemblyPrefix = prefixNode.AsString();
|
||||
|
||||
string? defaultWindowTitle = null;
|
||||
if (mapping.TryGetNode("defaultWindowTitle", out var winTitleNode))
|
||||
defaultWindowTitle = winTitleNode.AsString();
|
||||
|
||||
string? windowIconSet = null;
|
||||
if (mapping.TryGetNode("windowIconSet", out var iconSetNode))
|
||||
windowIconSet = iconSetNode.AsString();
|
||||
|
||||
string? splashLogo = null;
|
||||
if (mapping.TryGetNode("splashLogo", out var splashNode))
|
||||
splashLogo = splashNode.AsString();
|
||||
|
||||
return new ResourceManifestData(modules, assemblyPrefix, defaultWindowTitle, windowIconSet, splashLogo);
|
||||
}
|
||||
|
||||
internal bool StartupSystemSplash(GameControllerOptions options, Func<ILogHandler>? logHandlerFactory)
|
||||
@@ -301,15 +325,6 @@ namespace Robust.Client
|
||||
_configurationManager.OverrideConVars(_commandLineArgs.CVars);
|
||||
}
|
||||
|
||||
{
|
||||
// Handle GameControllerOptions implicit CVar overrides.
|
||||
_configurationManager.OverrideConVars(new[]
|
||||
{
|
||||
(CVars.DisplayWindowIconSet.Name, options.WindowIconSet.ToString()),
|
||||
(CVars.DisplaySplashLogo.Name, options.SplashLogo.ToString())
|
||||
});
|
||||
}
|
||||
|
||||
ProfileOptSetup.Setup(_configurationManager);
|
||||
|
||||
_resourceCache.Initialize(Options.LoadConfigAndUserData ? userDataDir : null);
|
||||
@@ -324,11 +339,32 @@ namespace Robust.Client
|
||||
|
||||
if (_loaderArgs != null)
|
||||
{
|
||||
if (_loaderArgs.ApiMounts is { } mounts)
|
||||
{
|
||||
foreach (var (api, prefix) in mounts)
|
||||
{
|
||||
_resourceCache.MountLoaderApi(api, "", new ResourcePath(prefix));
|
||||
}
|
||||
}
|
||||
|
||||
_stringSerializer.EnableCaching = false;
|
||||
_resourceCache.MountLoaderApi(_loaderArgs.FileApi, "Resources/");
|
||||
_modLoader.VerifierExtraLoadHandler = VerifierExtraLoadHandler;
|
||||
}
|
||||
|
||||
_resourceManifest = LoadResourceManifest();
|
||||
|
||||
{
|
||||
// Handle GameControllerOptions implicit CVar overrides.
|
||||
_configurationManager.OverrideConVars(new[]
|
||||
{
|
||||
(CVars.DisplayWindowIconSet.Name,
|
||||
options.WindowIconSet?.ToString() ?? _resourceManifest.WindowIconSet ?? ""),
|
||||
(CVars.DisplaySplashLogo.Name,
|
||||
options.SplashLogo?.ToString() ?? _resourceManifest.SplashLogo ?? "")
|
||||
});
|
||||
}
|
||||
|
||||
_clyde.TextEntered += TextEntered;
|
||||
_clyde.MouseMove += MouseMove;
|
||||
_clyde.KeyUp += KeyUp;
|
||||
@@ -431,7 +467,9 @@ namespace Robust.Client
|
||||
// In singleplayer, however, we're in full control instead.
|
||||
else if (_client.RunLevel == ClientRunLevel.SinglePlayerGame)
|
||||
{
|
||||
_entityManager.TickUpdate(frameEventArgs.DeltaSeconds);
|
||||
// The last real tick is the current tick! This way we won't be in "prediction" mode.
|
||||
_gameTiming.LastRealTick = _gameTiming.CurTick;
|
||||
_entityManager.TickUpdate(frameEventArgs.DeltaSeconds, noPredictions: false);
|
||||
_lookup.Update();
|
||||
}
|
||||
|
||||
@@ -543,6 +581,12 @@ namespace Robust.Client
|
||||
_clydeAudio.Shutdown();
|
||||
}
|
||||
|
||||
private sealed record ResourceManifestData(string[] Modules);
|
||||
private sealed record ResourceManifestData(
|
||||
string[] Modules,
|
||||
string? AssemblyPrefix,
|
||||
string? DefaultWindowTitle,
|
||||
string? WindowIconSet,
|
||||
string? SplashLogo
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ using Robust.Shared.Utility;
|
||||
|
||||
namespace Robust.Client
|
||||
{
|
||||
public class GameControllerOptions
|
||||
public sealed class GameControllerOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether content sandboxing will be enabled & enforced.
|
||||
@@ -30,12 +30,18 @@ namespace Robust.Client
|
||||
/// <summary>
|
||||
/// Default window title.
|
||||
/// </summary>
|
||||
public string DefaultWindowTitle { get; init; } = "Space Station 14";
|
||||
/// <remarks>
|
||||
/// Defaults to <c>RobustToolbox</c> if unset.
|
||||
/// </remarks>
|
||||
public string? DefaultWindowTitle { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Assemblies with this prefix will be loaded.
|
||||
/// </summary>
|
||||
public string ContentModulePrefix { get; init; } = "Content.";
|
||||
/// <remarks>
|
||||
/// Defaults to <c>Content.</c> if unset.
|
||||
/// </remarks>
|
||||
public string? ContentModulePrefix { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Name of the content build directory, for game pack mounting purposes.
|
||||
@@ -55,12 +61,12 @@ namespace Robust.Client
|
||||
/// <summary>
|
||||
/// Directory resource path containing window icons to load.
|
||||
/// </summary>
|
||||
public ResourcePath WindowIconSet { get; init; } = new("/Textures/Logo/icon");
|
||||
public ResourcePath? WindowIconSet { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Resource path for splash image to show when the game starts up.
|
||||
/// </summary>
|
||||
public ResourcePath SplashLogo { get; init; } = new("/Textures/Logo/logo.png");
|
||||
public ResourcePath? SplashLogo { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to disable mounting the "Resources/" folder on FULL_RELEASE.
|
||||
|
||||
@@ -6,7 +6,7 @@ using Robust.Shared.Reflection;
|
||||
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
internal class ClientComponentFactory : ComponentFactory
|
||||
internal sealed class ClientComponentFactory : ComponentFactory
|
||||
{
|
||||
public ClientComponentFactory(IDynamicTypeFactoryInternal typeFactory, IReflectionManager reflectionManager, IConsoleHost conHost)
|
||||
: base(typeFactory, reflectionManager, conHost)
|
||||
@@ -29,13 +29,9 @@ namespace Robust.Client.GameObjects
|
||||
RegisterClass<EyeComponent>();
|
||||
RegisterClass<AnimationPlayerComponent>();
|
||||
RegisterClass<TimerComponent>();
|
||||
|
||||
#if DEBUG
|
||||
RegisterClass<DebugExceptionOnAddComponent>();
|
||||
RegisterClass<DebugExceptionInitializeComponent>();
|
||||
RegisterClass<DebugExceptionStartupComponent>();
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace Robust.Client.GameObjects
|
||||
_networkManager.RegisterNetMessage<MsgEntity>(HandleEntityNetworkMessage);
|
||||
}
|
||||
|
||||
public override void TickUpdate(float frameTime, Histogram? histogram)
|
||||
public override void TickUpdate(float frameTime, bool noPredictions, Histogram? histogram)
|
||||
{
|
||||
using (histogram?.WithLabels("EntityNet").NewTimer())
|
||||
{
|
||||
@@ -79,7 +79,7 @@ namespace Robust.Client.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
base.TickUpdate(frameTime, histogram);
|
||||
base.TickUpdate(frameTime, noPredictions, histogram);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -109,10 +109,11 @@ namespace Robust.Client.GameObjects
|
||||
[Obsolete("Component Messages are deprecated, use Entity Events instead.")]
|
||||
public void SendComponentNetworkMessage(INetChannel? channel, EntityUid entity, IComponent component, ComponentMessage message)
|
||||
{
|
||||
var netId = ComponentFactory.GetRegistration(component.GetType()).NetID;
|
||||
var componentType = component.GetType();
|
||||
var netId = ComponentFactory.GetRegistration(componentType).NetID;
|
||||
|
||||
if (!netId.HasValue)
|
||||
throw new ArgumentException($"Component {component.Name} does not have a NetID.", nameof(component));
|
||||
throw new ArgumentException($"Component {componentType} does not have a NetID.", nameof(component));
|
||||
|
||||
var msg = _networkManager.CreateNetMessage<MsgEntity>();
|
||||
msg.Type = EntityMessageType.ComponentMessage;
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Runtime.Serialization;
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
[Serializable]
|
||||
[Virtual]
|
||||
public class ComponentStateApplyException : Exception
|
||||
{
|
||||
public ComponentStateApplyException()
|
||||
|
||||
@@ -13,8 +13,6 @@ namespace Robust.Client.GameObjects
|
||||
{
|
||||
// TODO: Give this component a friend someday. Way too much content shit to change atm ._.
|
||||
|
||||
public override string Name => "AnimationPlayer";
|
||||
|
||||
public int PlayingAnimationCount => PlayingAnimations.Count;
|
||||
|
||||
internal readonly Dictionary<string, AnimationPlayback> PlayingAnimations
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
using System;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
namespace Robust.Client.GameObjects;
|
||||
@@ -14,6 +15,7 @@ public abstract class AppearanceVisualizer
|
||||
/// Initializes an entity to be managed by this appearance controller.
|
||||
/// DO NOT assume this is your only entity. Visualizers are shared.
|
||||
/// </summary>
|
||||
[Obsolete("Subscribe to your component being initialised instead.")]
|
||||
public virtual void InitializeEntity(EntityUid entity)
|
||||
{
|
||||
}
|
||||
@@ -23,6 +25,7 @@ public abstract class AppearanceVisualizer
|
||||
/// Update its visuals here.
|
||||
/// </summary>
|
||||
/// <param name="component">The appearance component of the entity that might need updating.</param>
|
||||
[Obsolete("Subscribe to AppearanceChangeEvent instead.")]
|
||||
public virtual void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using Robust.Shared.Analyzers;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.ViewVariables;
|
||||
@@ -9,39 +10,10 @@ namespace Robust.Client.GameObjects;
|
||||
/// This is the client instance of <see cref="AppearanceComponent"/>.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(AppearanceComponent))]
|
||||
[ComponentReference(typeof(AppearanceComponent)), Friend(typeof(AppearanceSystem))]
|
||||
public sealed class ClientAppearanceComponent : AppearanceComponent
|
||||
{
|
||||
[ViewVariables]
|
||||
private bool _appearanceDirty;
|
||||
|
||||
[ViewVariables]
|
||||
[DataField("visuals")]
|
||||
internal List<AppearanceVisualizer> Visualizers = new();
|
||||
|
||||
protected override void MarkDirty()
|
||||
{
|
||||
if (_appearanceDirty)
|
||||
return;
|
||||
|
||||
EntitySystem.Get<AppearanceSystem>().EnqueueUpdate(this);
|
||||
_appearanceDirty = true;
|
||||
}
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
foreach (var visual in Visualizers)
|
||||
{
|
||||
visual.InitializeEntity(Owner);
|
||||
}
|
||||
|
||||
MarkDirty();
|
||||
}
|
||||
|
||||
internal void UnmarkDirty()
|
||||
{
|
||||
_appearanceDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,14 +9,11 @@ using Robust.Shared.ViewVariables;
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
[ComponentReference(typeof(SharedEyeComponent))]
|
||||
public class EyeComponent : SharedEyeComponent
|
||||
public sealed class EyeComponent : SharedEyeComponent
|
||||
{
|
||||
[Dependency] private readonly IEyeManager _eyeManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Name => "Eye";
|
||||
|
||||
[ViewVariables]
|
||||
private Eye? _eye = default!;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.GameObjects;
|
||||
@@ -12,9 +12,8 @@ using Robust.Shared.Utility;
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class IconComponent : Component, ISerializationHooks
|
||||
public sealed class IconComponent : Component, ISerializationHooks
|
||||
{
|
||||
public override string Name => "Icon";
|
||||
public IDirectionalTextureProvider? Icon { get; private set; }
|
||||
|
||||
[DataField("sprite")]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.ViewVariables;
|
||||
@@ -8,11 +8,8 @@ namespace Robust.Client.GameObjects
|
||||
/// <summary>
|
||||
/// Defines data fields used in the <see cref="InputSystem"/>.
|
||||
/// </summary>
|
||||
public class InputComponent : Component
|
||||
public sealed class InputComponent : Component
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Name => "Input";
|
||||
|
||||
/// <summary>
|
||||
/// The context that will be made active for a client that attaches to this entity.
|
||||
/// </summary>
|
||||
|
||||
@@ -40,13 +40,14 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
public void AnchorStateChanged()
|
||||
{
|
||||
SendDirty();
|
||||
var xform = _entityManager.GetComponent<TransformComponent>(Owner);
|
||||
SendDirty(xform);
|
||||
|
||||
if(!_entityManager.GetComponent<TransformComponent>(Owner).Anchored)
|
||||
if(!xform.Anchored)
|
||||
return;
|
||||
|
||||
var grid = _mapManager.GetGrid(_entityManager.GetComponent<TransformComponent>(Owner).GridID);
|
||||
_lastPosition = (_entityManager.GetComponent<TransformComponent>(Owner).GridID, grid.TileIndicesFor(_entityManager.GetComponent<TransformComponent>(Owner).Coordinates));
|
||||
var grid = _mapManager.GetGrid(xform.GridID);
|
||||
_lastPosition = (xform.GridID, grid.TileIndicesFor(xform.Coordinates));
|
||||
}
|
||||
|
||||
protected override void Shutdown()
|
||||
@@ -56,9 +57,10 @@ namespace Robust.Client.GameObjects
|
||||
SendDirty();
|
||||
}
|
||||
|
||||
private void SendDirty()
|
||||
private void SendDirty(TransformComponent? xform = null)
|
||||
{
|
||||
if (_entityManager.GetComponent<TransformComponent>(Owner).Anchored)
|
||||
xform ??= _entityManager.GetComponent<TransformComponent>(Owner);
|
||||
if (xform.Anchored)
|
||||
{
|
||||
_entityManager.EventBus.RaiseEvent(EventSource.Local,
|
||||
new OccluderDirtyEvent(Owner, _lastPosition));
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Robust.Client.GameObjects
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(SharedPointLightComponent))]
|
||||
public class PointLightComponent : SharedPointLightComponent, ISerializationHooks
|
||||
public sealed class PointLightComponent : SharedPointLightComponent, ISerializationHooks
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
|
||||
@@ -96,26 +96,6 @@ namespace Robust.Client.GameObjects
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public Texture? Mask { get; set; }
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[Animatable]
|
||||
public float Energy
|
||||
{
|
||||
get => _energy;
|
||||
set => _energy = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Soft shadow strength multiplier.
|
||||
/// Has no effect if soft shadows are not enabled.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[Animatable]
|
||||
public float Softness
|
||||
{
|
||||
get => _softness;
|
||||
set => _softness = value;
|
||||
}
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool VisibleNested
|
||||
{
|
||||
@@ -134,10 +114,7 @@ namespace Robust.Client.GameObjects
|
||||
[DataField("autoRot")]
|
||||
private bool _maskAutoRotate;
|
||||
private Angle _rotation;
|
||||
[DataField("energy")]
|
||||
private float _energy = 1f;
|
||||
[DataField("softness")]
|
||||
private float _softness = 1f;
|
||||
|
||||
[DataField("mask")]
|
||||
internal string? _maskPath;
|
||||
|
||||
@@ -162,7 +139,7 @@ namespace Robust.Client.GameObjects
|
||||
internal RenderingTreeComponent? RenderTree { get; set; }
|
||||
}
|
||||
|
||||
public class PointLightRadiusChangedEvent : EntityEventArgs
|
||||
public sealed class PointLightRadiusChangedEvent : EntityEventArgs
|
||||
{
|
||||
public PointLightComponent PointLightComponent { get; }
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Robust.Client.GameObjects
|
||||
private bool _enabled;
|
||||
}
|
||||
|
||||
public class SpriteBoundsOverlay : Overlay
|
||||
public sealed class SpriteBoundsOverlay : Overlay
|
||||
{
|
||||
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
||||
|
||||
|
||||
@@ -1257,7 +1257,10 @@ namespace Robust.Client.GameObjects
|
||||
if (worldRotation.Theta < 0)
|
||||
worldRotation = new Angle(worldRotation.Theta + Math.Tau);
|
||||
|
||||
var spriteMatrix = GetLocalMatrix();
|
||||
// sprite matrix, WITHOUT offset.
|
||||
// offset is applied after sprite numDirs snapping/rotation correction
|
||||
// --> apply at same time as layer offset
|
||||
var spriteMatrix = Matrix3.CreateTransform(Vector2.Zero, rotation, scale);
|
||||
|
||||
foreach (var layer in Layers)
|
||||
{
|
||||
@@ -1268,7 +1271,7 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
var numDirs = GetLayerDirectionCount(layer);
|
||||
var layerRotation = worldRotation + layer.Rotation;
|
||||
var layerPosition = worldPosition + layerRotation.RotateVec(layer._offset);
|
||||
var layerPosition = worldPosition + layerRotation.RotateVec(layer._offset + offset);
|
||||
|
||||
CalcModelMatrix(numDirs, eyeRotation, layerRotation, layerPosition, out var modelMatrix);
|
||||
Matrix3.Multiply(ref spriteMatrix, ref modelMatrix, out var transformMatrix);
|
||||
@@ -1474,30 +1477,6 @@ namespace Robust.Client.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
private RSI.State.Direction GetDir(RSI.State.DirectionType rsiDirectionType, Angle worldRotation)
|
||||
{
|
||||
var dir = rsiDirectionType switch
|
||||
{
|
||||
RSI.State.DirectionType.Dir1 => Direction.South,
|
||||
RSI.State.DirectionType.Dir4 => worldRotation.GetCardinalDir(),
|
||||
RSI.State.DirectionType.Dir8 => worldRotation.GetDir(),
|
||||
_ => throw new ArgumentException($"Unknown RSI DirectionType: {rsiDirectionType}.", nameof(rsiDirectionType))
|
||||
};
|
||||
|
||||
return dir switch
|
||||
{
|
||||
Direction.North => RSI.State.Direction.North,
|
||||
Direction.South => RSI.State.Direction.South,
|
||||
Direction.East => RSI.State.Direction.East,
|
||||
Direction.West => RSI.State.Direction.West,
|
||||
Direction.SouthEast => RSI.State.Direction.SouthEast,
|
||||
Direction.SouthWest => RSI.State.Direction.SouthWest,
|
||||
Direction.NorthEast => RSI.State.Direction.NorthEast,
|
||||
Direction.NorthWest => RSI.State.Direction.NorthWest,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(dir), dir, null)
|
||||
};
|
||||
}
|
||||
|
||||
private void QueueUpdateIsInert()
|
||||
{
|
||||
// Look this was an easy way to get bounds checks for layer updates.
|
||||
@@ -1547,58 +1526,13 @@ namespace Robust.Client.GameObjects
|
||||
return rsi["error"];
|
||||
}
|
||||
|
||||
private static RSI.State.Direction OffsetRsiDir(RSI.State.Direction dir, DirectionOffset offset)
|
||||
{
|
||||
// There is probably a better way to do this.
|
||||
// Eh.
|
||||
switch (offset)
|
||||
{
|
||||
case DirectionOffset.None:
|
||||
return dir;
|
||||
case DirectionOffset.Clockwise:
|
||||
return dir switch
|
||||
{
|
||||
RSI.State.Direction.North => RSI.State.Direction.East,
|
||||
RSI.State.Direction.East => RSI.State.Direction.South,
|
||||
RSI.State.Direction.South => RSI.State.Direction.West,
|
||||
RSI.State.Direction.West => RSI.State.Direction.North,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
case DirectionOffset.CounterClockwise:
|
||||
return dir switch
|
||||
{
|
||||
RSI.State.Direction.North => RSI.State.Direction.West,
|
||||
RSI.State.Direction.East => RSI.State.Direction.North,
|
||||
RSI.State.Direction.South => RSI.State.Direction.East,
|
||||
RSI.State.Direction.West => RSI.State.Direction.South,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
case DirectionOffset.Flip:
|
||||
switch (dir)
|
||||
{
|
||||
case RSI.State.Direction.North:
|
||||
return RSI.State.Direction.South;
|
||||
case RSI.State.Direction.East:
|
||||
return RSI.State.Direction.West;
|
||||
case RSI.State.Direction.South:
|
||||
return RSI.State.Direction.North;
|
||||
case RSI.State.Direction.West:
|
||||
return RSI.State.Direction.East;
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public string GetDebugString()
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
builder.AppendFormat(
|
||||
"vis/depth/scl/rot/ofs/col/norot/override/dir: {0}/{1}/{2}/{3}/{4}/{5}/{6}/{8}/{7}\n",
|
||||
Visible, DrawDepth, Scale, Rotation, Offset,
|
||||
Color, NoRotation, GetDir(RSI.State.DirectionType.Dir8, entities.GetComponent<TransformComponent>(Owner).WorldRotation),
|
||||
Color, NoRotation, entities.GetComponent<TransformComponent>(Owner).WorldRotation.ToRsiDirection(RSI.State.DirectionType.Dir8),
|
||||
DirectionOverride
|
||||
);
|
||||
|
||||
@@ -1681,7 +1615,7 @@ namespace Robust.Client.GameObjects
|
||||
Flip = 3,
|
||||
}
|
||||
|
||||
public class Layer : ISpriteLayer
|
||||
public sealed class Layer : ISpriteLayer
|
||||
{
|
||||
[ViewVariables] private readonly SpriteComponent _parent;
|
||||
|
||||
@@ -1839,10 +1773,10 @@ namespace Robust.Client.GameObjects
|
||||
}
|
||||
else
|
||||
{
|
||||
dir = _parent.GetDir(state.Directions, worldRotation);
|
||||
dir = worldRotation.ToRsiDirection(state.Directions);
|
||||
}
|
||||
|
||||
return OffsetRsiDir(dir, DirOffset);
|
||||
return dir.OffsetRsiDir(DirOffset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2073,6 +2007,7 @@ namespace Robust.Client.GameObjects
|
||||
var entityManager = IoCManager.Resolve<IEntityManager>();
|
||||
var dummy = entityManager.SpawnEntity(prototype.ID, MapCoordinates.Nullspace);
|
||||
var spriteComponent = entityManager.EnsureComponent<SpriteComponent>(dummy);
|
||||
EntitySystem.Get<AppearanceSystem>().OnChangeData(dummy);
|
||||
|
||||
var anyTexture = false;
|
||||
foreach (var layer in spriteComponent.AllLayers)
|
||||
|
||||
@@ -6,8 +6,6 @@ namespace Robust.Client.GameObjects
|
||||
[RegisterComponent]
|
||||
public sealed class RenderingTreeComponent : Component
|
||||
{
|
||||
public override string Name => "RenderingTree";
|
||||
|
||||
internal DynamicTree<SpriteComponent> SpriteTree { get; set; } = default!;
|
||||
internal DynamicTree<PointLightComponent> LightTree { get; set; } = default!;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ using Robust.Shared.ViewVariables;
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
[ComponentReference(typeof(SharedUserInterfaceComponent))]
|
||||
public class ClientUserInterfaceComponent : SharedUserInterfaceComponent, ISerializationHooks
|
||||
public sealed class ClientUserInterfaceComponent : SharedUserInterfaceComponent, ISerializationHooks
|
||||
{
|
||||
[Dependency] private readonly IReflectionManager _reflectionManager = default!;
|
||||
[Dependency] private readonly IDynamicTypeFactory _dynamicTypeFactory = default!;
|
||||
|
||||
@@ -62,6 +62,12 @@ namespace Robust.Client.GameObjects
|
||||
Play(component, animation, key);
|
||||
}
|
||||
|
||||
public void Play(EntityUid uid, AnimationPlayerComponent? component, Animation animation, string key)
|
||||
{
|
||||
component ??= EntityManager.EnsureComponent<AnimationPlayerComponent>(uid);
|
||||
Play(component, animation, key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start playing an animation.
|
||||
/// </summary>
|
||||
@@ -79,6 +85,14 @@ namespace Robust.Client.GameObjects
|
||||
component.PlayingAnimations.ContainsKey(key);
|
||||
}
|
||||
|
||||
public bool HasRunningAnimation(EntityUid uid, AnimationPlayerComponent? component, string key)
|
||||
{
|
||||
if (component == null)
|
||||
TryComp(uid, out component);
|
||||
|
||||
return component != null && component.PlayingAnimations.ContainsKey(key);
|
||||
}
|
||||
|
||||
public bool HasRunningAnimation(AnimationPlayerComponent component, string key)
|
||||
{
|
||||
return component.PlayingAnimations.ContainsKey(key);
|
||||
@@ -88,6 +102,18 @@ namespace Robust.Client.GameObjects
|
||||
{
|
||||
component.PlayingAnimations.Remove(key);
|
||||
}
|
||||
|
||||
public void Stop(EntityUid uid, string key)
|
||||
{
|
||||
if (!TryComp<AnimationPlayerComponent>(uid, out var player)) return;
|
||||
player.PlayingAnimations.Remove(key);
|
||||
}
|
||||
|
||||
public void Stop(EntityUid uid, AnimationPlayerComponent? component, string key)
|
||||
{
|
||||
if (!Resolve(uid, ref component, false)) return;
|
||||
component.PlayingAnimations.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class AnimationCompletedEvent : EntityEventArgs
|
||||
|
||||
@@ -1,17 +1,71 @@
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
[UsedImplicitly]
|
||||
internal sealed class AppearanceSystem : EntitySystem
|
||||
internal sealed class AppearanceSystem : SharedAppearanceSystem
|
||||
{
|
||||
private readonly Queue<ClientAppearanceComponent> _queuedUpdates = new();
|
||||
|
||||
public void EnqueueUpdate(ClientAppearanceComponent component)
|
||||
public override void Initialize()
|
||||
{
|
||||
_queuedUpdates.Enqueue(component);
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ClientAppearanceComponent, ComponentInit>(OnAppearanceInit);
|
||||
SubscribeLocalEvent<ClientAppearanceComponent, ComponentHandleState>(OnAppearanceHandleState);
|
||||
}
|
||||
|
||||
private void OnAppearanceInit(EntityUid uid, ClientAppearanceComponent component, ComponentInit args)
|
||||
{
|
||||
foreach (var visual in component.Visualizers)
|
||||
{
|
||||
visual.InitializeEntity(uid);
|
||||
}
|
||||
|
||||
MarkDirty(component);
|
||||
}
|
||||
|
||||
private void OnAppearanceHandleState(EntityUid uid, ClientAppearanceComponent component, ref ComponentHandleState args)
|
||||
{
|
||||
if (args.Current is not AppearanceComponentState actualState)
|
||||
return;
|
||||
|
||||
var stateDiff = component.AppearanceData.Count != actualState.Data.Count;
|
||||
|
||||
if (!stateDiff)
|
||||
{
|
||||
foreach (var (key, value) in component.AppearanceData)
|
||||
{
|
||||
if (!actualState.Data.TryGetValue(key, out var stateValue) ||
|
||||
!value.Equals(stateValue))
|
||||
{
|
||||
stateDiff = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!stateDiff) return;
|
||||
|
||||
component.AppearanceData = actualState.Data;
|
||||
MarkDirty(component);
|
||||
}
|
||||
|
||||
public override void MarkDirty(AppearanceComponent component)
|
||||
{
|
||||
if (component.AppearanceDirty)
|
||||
return;
|
||||
|
||||
_queuedUpdates.Enqueue((ClientAppearanceComponent) component);
|
||||
component.AppearanceDirty = true;
|
||||
}
|
||||
|
||||
internal void UnmarkDirty(ClientAppearanceComponent component)
|
||||
{
|
||||
component.AppearanceDirty = false;
|
||||
}
|
||||
|
||||
public override void FrameUpdate(float frameTime)
|
||||
@@ -19,15 +73,41 @@ namespace Robust.Client.GameObjects
|
||||
while (_queuedUpdates.TryDequeue(out var appearance))
|
||||
{
|
||||
if (appearance.Deleted)
|
||||
return;
|
||||
continue;
|
||||
|
||||
foreach (var visualizer in appearance.Visualizers)
|
||||
{
|
||||
visualizer.OnChangeData(appearance);
|
||||
}
|
||||
OnChangeData(appearance.Owner, appearance);
|
||||
UnmarkDirty(appearance);
|
||||
}
|
||||
}
|
||||
|
||||
appearance.UnmarkDirty();
|
||||
public void OnChangeData(EntityUid uid, ClientAppearanceComponent? appearanceComponent = null)
|
||||
{
|
||||
if (!Resolve(uid, ref appearanceComponent, false)) return;
|
||||
|
||||
var ev = new AppearanceChangeEvent
|
||||
{
|
||||
Component = appearanceComponent,
|
||||
AppearanceData = appearanceComponent.AppearanceData,
|
||||
};
|
||||
|
||||
// Give it AppearanceData so we can still keep the friend attribute on the component.
|
||||
EntityManager.EventBus.RaiseLocalEvent(uid, ref ev);
|
||||
|
||||
// Eventually visualizers would be nuked and we'd just make them components instead.
|
||||
foreach (var visualizer in appearanceComponent.Visualizers)
|
||||
{
|
||||
visualizer.OnChangeData(appearanceComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised whenever the appearance data for an entity changes.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public struct AppearanceChangeEvent
|
||||
{
|
||||
public AppearanceComponent Component = default!;
|
||||
public IReadOnlyDictionary<object, object> AppearanceData = default!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ using Robust.Shared.Utility;
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class AudioSystem : SharedAudioSystem, IAudioSystem
|
||||
public sealed class AudioSystem : SharedAudioSystem, IAudioSystem
|
||||
{
|
||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
@@ -253,9 +253,15 @@ namespace Robust.Client.GameObjects
|
||||
/// </summary>
|
||||
/// <param name="stream">The audio stream to play.</param>
|
||||
/// <param name="audioParams"></param>
|
||||
private IPlayingAudioStream Play(AudioStream stream, AudioParams? audioParams = null)
|
||||
private IPlayingAudioStream? Play(AudioStream stream, AudioParams? audioParams = null)
|
||||
{
|
||||
var source = _clyde.CreateAudioSource(stream);
|
||||
|
||||
if (source == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ApplyAudioParams(audioParams, source);
|
||||
|
||||
source.SetGlobal();
|
||||
@@ -303,6 +309,12 @@ namespace Robust.Client.GameObjects
|
||||
AudioParams? audioParams = null)
|
||||
{
|
||||
var source = _clyde.CreateAudioSource(stream);
|
||||
|
||||
if (source == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!source.SetPosition(EntityManager.GetComponent<TransformComponent>(entity).WorldPosition))
|
||||
{
|
||||
return Play(stream, fallbackCoordinates, fallbackCoordinates, audioParams);
|
||||
@@ -356,6 +368,12 @@ namespace Robust.Client.GameObjects
|
||||
EntityCoordinates fallbackCoordinates, AudioParams? audioParams = null)
|
||||
{
|
||||
var source = _clyde.CreateAudioSource(stream);
|
||||
|
||||
if (source == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!source.SetPosition(fallbackCoordinates.Position))
|
||||
{
|
||||
source.Dispose();
|
||||
@@ -402,7 +420,7 @@ namespace Robust.Client.GameObjects
|
||||
source.IsLooping = audioParams.Value.Loop;
|
||||
}
|
||||
|
||||
private class PlayingStream : IPlayingAudioStream
|
||||
private sealed class PlayingStream : IPlayingAudioStream
|
||||
{
|
||||
public uint? NetIdentifier;
|
||||
public IClydeAudioSource Source = default!;
|
||||
|
||||
@@ -72,10 +72,13 @@ namespace Robust.Client.GameObjects
|
||||
var sender = ev.Sender;
|
||||
if (EntityManager.EntityExists(sender) &&
|
||||
EntityManager.TryGetComponent(sender, out ClientOccluderComponent? iconSmooth)
|
||||
&& iconSmooth.Running)
|
||||
&& iconSmooth.Initialized)
|
||||
{
|
||||
var grid1 = _mapManager.GetGrid(EntityManager.GetComponent<TransformComponent>(sender).GridID);
|
||||
var coords = EntityManager.GetComponent<TransformComponent>(sender).Coordinates;
|
||||
var xform = EntityManager.GetComponent<TransformComponent>(sender);
|
||||
if (!_mapManager.TryGetGrid(xform.GridID, out var grid1))
|
||||
return;
|
||||
|
||||
var coords = xform.Coordinates;
|
||||
|
||||
_dirtyEntities.Enqueue(sender);
|
||||
AddValidEntities(grid1.GetInDir(coords, Direction.North));
|
||||
@@ -85,7 +88,7 @@ namespace Robust.Client.GameObjects
|
||||
}
|
||||
|
||||
// Entity is no longer valid, update around the last position it was at.
|
||||
if (ev.LastPosition.HasValue && _mapManager.TryGetGrid(ev.LastPosition.Value.grid, out var grid))
|
||||
else if (ev.LastPosition.HasValue && _mapManager.TryGetGrid(ev.LastPosition.Value.grid, out var grid))
|
||||
{
|
||||
var pos = ev.LastPosition.Value.pos;
|
||||
|
||||
|
||||
@@ -5,12 +5,14 @@ using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Serialization;
|
||||
using static Robust.Shared.Containers.ContainerManagerComponent;
|
||||
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
public class ContainerSystem : SharedContainerSystem
|
||||
public sealed class ContainerSystem : SharedContainerSystem
|
||||
{
|
||||
[Dependency] private readonly IRobustSerializer _serializer = default!;
|
||||
[Dependency] private readonly IDynamicTypeFactoryInternal _dynFactory = default!;
|
||||
@@ -59,7 +61,7 @@ namespace Robust.Client.GameObjects
|
||||
{
|
||||
if (!cast.ContainerSet.Any(data => data.Id == id))
|
||||
{
|
||||
container.EmptyContainer(true);
|
||||
container.EmptyContainer(true, entMan: EntityManager);
|
||||
container.Shutdown();
|
||||
toDelete ??= new List<string>();
|
||||
toDelete.Add(id);
|
||||
@@ -131,12 +133,51 @@ namespace Robust.Client.GameObjects
|
||||
continue;
|
||||
}
|
||||
|
||||
// If an entity is currently in the shadow realm, it means we probably left PVS and are now getting
|
||||
// back into range. We do not want to directly insert this entity, as IF the container and entity
|
||||
// transform states did not get sent simultaneously, the entity's transform will be modified by the
|
||||
// insert operation. This means it will then be reset to the shadow realm, causing it to be ejected
|
||||
// from the container. It would then subsequently be parented to the container without ever being
|
||||
// re-inserted, leading to the client seeing what should be hidden entities attached to
|
||||
// containers/players.
|
||||
if (Transform(entity).MapID == MapId.Nullspace)
|
||||
{
|
||||
AddExpectedEntity(entity, container);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!container.ContainedEntities.Contains(entity))
|
||||
container.Insert(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void HandleParentChanged(ref EntParentChangedMessage message)
|
||||
{
|
||||
base.HandleParentChanged(ref message);
|
||||
|
||||
// If an entity warped in from null-space (i.e., re-entered PVS) and got attached to a container, do the same checks as for newly initialized entities.
|
||||
if (message.OldParent != null && message.OldParent.Value.IsValid())
|
||||
return;
|
||||
|
||||
if (!ExpectedEntities.TryGetValue(message.Entity, out var container))
|
||||
return;
|
||||
|
||||
if (Transform(message.Entity).ParentUid != container.Owner)
|
||||
{
|
||||
// This container is expecting an entity... but it got parented to some other entity???
|
||||
// Ah well, the sever should send a new container state that updates expected entities so just ignore it for now.
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveExpectedEntity(message.Entity);
|
||||
|
||||
if (container.Deleted)
|
||||
return;
|
||||
|
||||
container.Insert(message.Entity);
|
||||
}
|
||||
|
||||
private IContainer ContainerFactory(ContainerManagerComponent component, string containerType, string id)
|
||||
{
|
||||
var type = _serializer.FindSerializedType(typeof(IContainer), containerType);
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
#if DEBUG
|
||||
using System;
|
||||
using System.Text;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
internal sealed class DebugGridTileLookupSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IEyeManager _eyeManager = default!;
|
||||
[Dependency] private readonly IInputManager _inputManager = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
|
||||
public bool Enabled
|
||||
{
|
||||
get => _enabled;
|
||||
set
|
||||
{
|
||||
if (_enabled == value) return;
|
||||
_enabled = value;
|
||||
|
||||
if (_enabled)
|
||||
{
|
||||
_label.Visible = true;
|
||||
LastTile = default;
|
||||
}
|
||||
else
|
||||
{
|
||||
_label.Text = null;
|
||||
_label.Visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _enabled;
|
||||
|
||||
private (GridId Grid, Vector2i Indices) LastTile;
|
||||
|
||||
// Label and shit that follows cursor
|
||||
private Label _label = new()
|
||||
{
|
||||
Visible = false,
|
||||
};
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeNetworkEvent<SendGridTileLookupMessage>(HandleSentEntities);
|
||||
IoCManager.Resolve<IUserInterfaceManager>().StateRoot.AddChild(_label);
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
{
|
||||
base.Shutdown();
|
||||
IoCManager.Resolve<IUserInterfaceManager>().StateRoot.RemoveChild(_label);
|
||||
}
|
||||
|
||||
private void RequestEntities(GridId gridId, Vector2i indices)
|
||||
{
|
||||
if (gridId == GridId.Invalid) return;
|
||||
RaiseNetworkEvent(new RequestGridTileLookupMessage(gridId, indices));
|
||||
}
|
||||
|
||||
private void HandleSentEntities(SendGridTileLookupMessage message)
|
||||
{
|
||||
if (!Enabled) return;
|
||||
var text = new StringBuilder();
|
||||
text.AppendLine($"GridId: {LastTile.Grid}, Tile: {LastTile.Indices}");
|
||||
|
||||
for (var i = 0; i < message.Entities.Count; i++)
|
||||
{
|
||||
var entity = message.Entities[i];
|
||||
|
||||
if (!EntityManager.EntityExists(entity)) continue;
|
||||
|
||||
text.AppendLine((string) EntityManager.ToPrettyString(entity));
|
||||
}
|
||||
|
||||
_label.Text = text.ToString();
|
||||
}
|
||||
|
||||
public override void FrameUpdate(float frameTime)
|
||||
{
|
||||
base.FrameUpdate(frameTime);
|
||||
if (!Enabled) return;
|
||||
|
||||
var mousePos = _inputManager.MouseScreenPosition;
|
||||
var worldPos = _eyeManager.ScreenToMap(mousePos);
|
||||
|
||||
GridId gridId;
|
||||
Vector2i tile;
|
||||
|
||||
if (_mapManager.TryFindGridAt(worldPos, out var grid))
|
||||
{
|
||||
gridId = grid.Index;
|
||||
tile = grid.WorldToTile(worldPos.Position);
|
||||
}
|
||||
else
|
||||
{
|
||||
gridId = GridId.Invalid;
|
||||
tile = new Vector2i((int) MathF.Floor(worldPos.Position.X), (int) MathF.Floor(worldPos.Position.Y));
|
||||
}
|
||||
|
||||
LayoutContainer.SetPosition(_label, mousePos.Position);
|
||||
|
||||
if ((gridId, tile).Equals(LastTile)) return;
|
||||
|
||||
_label.Text = null;
|
||||
LastTile = (gridId, tile);
|
||||
RequestEntities(gridId, tile);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class RequestTileEntities : IConsoleCommand
|
||||
{
|
||||
public string Command => "tilelookup";
|
||||
public string Description => "Used for debugging GridTileLookupSystem";
|
||||
public string Help => $"{Command}";
|
||||
public void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
EntitySystem.Get<DebugGridTileLookupSystem>().Enabled ^= true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -15,7 +15,7 @@ using Robust.Shared.Enums;
|
||||
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
public class EffectSystem : EntitySystem
|
||||
public sealed class EffectSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IGameTiming gameTiming = default!;
|
||||
[Dependency] private readonly IResourceCache resourceCache = default!;
|
||||
@@ -94,7 +94,7 @@ namespace Robust.Client.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
private class Effect
|
||||
private sealed class Effect
|
||||
{
|
||||
/// <summary>
|
||||
/// Effect Sprite
|
||||
@@ -347,11 +347,17 @@ namespace Robust.Client.GameObjects
|
||||
if (_playerManager.LocalPlayer?.ControlledEntity is not {} playerEnt)
|
||||
return;
|
||||
|
||||
var playerXform = _entityManager.GetComponent<TransformComponent>(playerEnt);
|
||||
|
||||
foreach (var effect in _owner._Effects)
|
||||
{
|
||||
if(effect.AttachedEntityUid is {} attached
|
||||
&& _entityManager.GetComponent<TransformComponent>(attached).MapID != _entityManager.GetComponent<TransformComponent>(playerEnt).MapID
|
||||
&& effect.Coordinates.GetMapId(_entityManager) != map)
|
||||
TransformComponent? attachedXform = null;
|
||||
|
||||
if ((effect.AttachedEntityUid is {} attached &&
|
||||
_entityManager.TryGetComponent(attached, out attachedXform) &&
|
||||
attachedXform.MapID != playerXform.MapID) ||
|
||||
(effect.AttachedEntityUid == null &&
|
||||
effect.Coordinates.GetMapId(_entityManager) != map))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -367,16 +373,17 @@ namespace Robust.Client.GameObjects
|
||||
// TODO: Should be doing matrix transformations
|
||||
var effectSprite = effect.EffectSprite;
|
||||
|
||||
var tempQualifier1 = effect.AttachedEntityUid;
|
||||
var coordinates =
|
||||
(tempQualifier1 != null ? _entityManager.GetComponent<TransformComponent>(tempQualifier1.Value).Coordinates : effect.Coordinates)
|
||||
(attachedXform?.Coordinates ?? effect.Coordinates)
|
||||
.Offset(effect.AttachedOffset);
|
||||
|
||||
var rotation = _entityManager.GetComponent<TransformComponent>(coordinates.EntityId).WorldRotation;
|
||||
// ???
|
||||
var rotation = attachedXform?.WorldRotation ?? _entityManager.GetComponent<TransformComponent>(coordinates.EntityId).WorldRotation;
|
||||
|
||||
var effectOrigin = coordinates.ToMapPos(_entityManager);
|
||||
|
||||
var effectArea = Box2.CenteredAround(effectOrigin, effect.Size);
|
||||
var rotatedBox = new Box2Rotated(effectArea, effect.Rotation - rotation, effectOrigin);
|
||||
var rotatedBox = new Box2Rotated(effectArea, effect.Rotation + rotation, effectOrigin);
|
||||
|
||||
worldHandle.DrawTextureRect(effectSprite, rotatedBox, ToColor(effect.Color));
|
||||
}
|
||||
|
||||
@@ -7,8 +7,10 @@ using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Input.Binding;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
#nullable enable
|
||||
|
||||
@@ -18,26 +20,8 @@ namespace Robust.Client.GameObjects
|
||||
/// Updates the position of every Eye every frame, so that the camera follows the player around.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
internal class EyeUpdateSystem : EntitySystem
|
||||
public sealed class EyeUpdateSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IEyeManager _eyeManager = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
|
||||
private TransformComponent? _lastParent;
|
||||
private TransformComponent? _lerpTo;
|
||||
private Angle LerpStartRotation;
|
||||
private float _accumulator;
|
||||
|
||||
public bool IsLerping { get => _lerpTo != null; }
|
||||
|
||||
// How fast the camera rotates in radians / s
|
||||
private const float CameraRotateSpeed = MathF.PI;
|
||||
// PER THIS AMOUNT OF TIME MILLISECONDS
|
||||
private const float CameraRotateTimeUnit = 1.2f;
|
||||
// Safety override
|
||||
private const float _lerpTimeMax = CameraRotateTimeUnit + 0.4f;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -65,77 +49,6 @@ namespace Robust.Client.GameObjects
|
||||
/// <inheritdoc />
|
||||
public override void FrameUpdate(float frameTime)
|
||||
{
|
||||
var currentEye = _eyeManager.CurrentEye;
|
||||
|
||||
// TODO: Content should have its own way of handling this. We should have a default behavior that they can overwrite.
|
||||
|
||||
EntityUid tempQualifier = _playerManager.LocalPlayer?.ControlledEntity ?? EntityUid.Invalid;
|
||||
var playerTransform = (tempQualifier != EntityUid.Invalid ? EntityManager.GetComponent<TransformComponent>(tempQualifier) : null);
|
||||
|
||||
if (playerTransform == null) return;
|
||||
|
||||
var gridId = playerTransform.GridID;
|
||||
|
||||
TransformComponent parent;
|
||||
if (gridId != GridId.Invalid &&
|
||||
_mapManager.GetGrid(gridId).GridEntityId is var gridEnt &&
|
||||
EntityManager.EntityExists(gridEnt))
|
||||
parent = EntityManager.GetComponent<TransformComponent>(gridEnt);
|
||||
else
|
||||
{
|
||||
parent = EntityManager.GetComponent<TransformComponent>(
|
||||
_mapManager.GetMapEntityId(playerTransform.MapID));
|
||||
}
|
||||
|
||||
// Make sure that we don't fire the vomit carousel when we spawn in
|
||||
if (_lastParent is null)
|
||||
_lastParent = parent;
|
||||
|
||||
// Set a default for target rotation
|
||||
var parentRotation = -parent.WorldRotation;
|
||||
// Reuse current rotation when stepping into space
|
||||
if (parent.GridID == GridId.Invalid)
|
||||
parentRotation = currentEye.Rotation;
|
||||
|
||||
// Handle grid change in general
|
||||
if (_lastParent != parent)
|
||||
_lerpTo = parent;
|
||||
|
||||
// And we are up and running!
|
||||
if (_lerpTo is not null)
|
||||
{
|
||||
// Handle a case where we have beeing spinning around, but suddenly got off onto a different grid
|
||||
if (parent != _lerpTo) {
|
||||
LerpStartRotation = currentEye.Rotation;
|
||||
_lerpTo = parent;
|
||||
_accumulator = 0f;
|
||||
}
|
||||
|
||||
_accumulator += frameTime;
|
||||
|
||||
var changeNeeded = (float) (LerpStartRotation - parentRotation).Theta;
|
||||
|
||||
var changeLerp = _accumulator / (Math.Abs(changeNeeded % MathF.PI) / CameraRotateSpeed * CameraRotateTimeUnit);
|
||||
|
||||
currentEye.Rotation = Angle.Lerp(LerpStartRotation, parentRotation, changeLerp);
|
||||
|
||||
// Either we have overshot, or we have taken way too long on this, emergency reset time
|
||||
if (changeLerp > 1.0f || _accumulator >= _lerpTimeMax)
|
||||
{
|
||||
_lastParent = parent;
|
||||
_lerpTo = null;
|
||||
_accumulator = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
// We are just fine, or we finished a lerp (and probably overshot)
|
||||
if (_lerpTo is null)
|
||||
{
|
||||
currentEye.Rotation = parentRotation;
|
||||
LerpStartRotation = parentRotation;
|
||||
}
|
||||
|
||||
|
||||
foreach (var eyeComponent in EntityManager.EntityQuery<EyeComponent>(true))
|
||||
{
|
||||
eyeComponent.UpdateEyePosition();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.GameObjects;
|
||||
@@ -11,8 +10,12 @@ using Robust.Shared.Utility;
|
||||
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
public class GridChunkBoundsDebugSystem : EntitySystem
|
||||
public sealed class GridChunkBoundsDebugSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IEyeManager _eyeManager = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly IOverlayManager _overlayManager = default!;
|
||||
|
||||
private GridChunkBoundsOverlay? _overlay;
|
||||
|
||||
public bool Enabled
|
||||
@@ -29,14 +32,14 @@ namespace Robust.Client.GameObjects
|
||||
DebugTools.Assert(_overlay == null);
|
||||
_overlay = new GridChunkBoundsOverlay(
|
||||
EntityManager,
|
||||
IoCManager.Resolve<IEyeManager>(),
|
||||
IoCManager.Resolve<IMapManager>());
|
||||
_eyeManager,
|
||||
_mapManager);
|
||||
|
||||
IoCManager.Resolve<IOverlayManager>().AddOverlay(_overlay);
|
||||
_overlayManager.AddOverlay(_overlay);
|
||||
}
|
||||
else
|
||||
{
|
||||
IoCManager.Resolve<IOverlayManager>().RemoveOverlay(_overlay!);
|
||||
_overlayManager.RemoveOverlay(_overlay!);
|
||||
_overlay = null;
|
||||
}
|
||||
}
|
||||
@@ -63,7 +66,7 @@ namespace Robust.Client.GameObjects
|
||||
protected internal override void Draw(in OverlayDrawArgs args)
|
||||
{
|
||||
var currentMap = _eyeManager.CurrentMap;
|
||||
var viewport = _eyeManager.GetWorldViewport();
|
||||
var viewport = args.WorldBounds;
|
||||
var worldHandle = args.WorldHandle;
|
||||
|
||||
foreach (var grid in _mapManager.FindGridsIntersecting(currentMap, viewport))
|
||||
|
||||
@@ -2,6 +2,8 @@ using System;
|
||||
using Robust.Client.GameStates;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.IoC;
|
||||
@@ -14,7 +16,7 @@ namespace Robust.Client.GameObjects
|
||||
/// <summary>
|
||||
/// Client-side processing of all input commands through the simulation.
|
||||
/// </summary>
|
||||
public class InputSystem : SharedInputSystem
|
||||
public sealed class InputSystem : SharedInputSystem
|
||||
{
|
||||
[Dependency] private readonly IInputManager _inputManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
@@ -62,6 +64,9 @@ namespace Robust.Client.GameObjects
|
||||
// handle local binds before sending off
|
||||
foreach (var handler in BindRegistry.GetHandlers(function))
|
||||
{
|
||||
if (!_stateManager.IsPredictionEnabled && !handler.FireOutsidePrediction)
|
||||
continue;
|
||||
|
||||
// local handlers can block sending over the network.
|
||||
if (handler.HandleCmdMessage(session, message))
|
||||
{
|
||||
@@ -158,7 +163,7 @@ namespace Robust.Client.GameObjects
|
||||
/// <summary>
|
||||
/// Entity system message that is raised when the player changes attached entities.
|
||||
/// </summary>
|
||||
public class PlayerAttachSysMessage : EntityEventArgs
|
||||
public sealed class PlayerAttachSysMessage : EntityEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// New entity the player is attached to.
|
||||
@@ -175,7 +180,7 @@ namespace Robust.Client.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
public class PlayerAttachedEvent : EntityEventArgs
|
||||
public sealed class PlayerAttachedEvent : EntityEventArgs
|
||||
{
|
||||
public PlayerAttachedEvent(EntityUid entity)
|
||||
{
|
||||
@@ -185,7 +190,7 @@ namespace Robust.Client.GameObjects
|
||||
public EntityUid Entity { get; }
|
||||
}
|
||||
|
||||
public class PlayerDetachedEvent : EntityEventArgs
|
||||
public sealed class PlayerDetachedEvent : EntityEventArgs
|
||||
{
|
||||
public PlayerDetachedEvent(EntityUid entity)
|
||||
{
|
||||
|
||||
@@ -4,7 +4,7 @@ using Robust.Shared.IoC;
|
||||
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
public class MidiSystem : EntitySystem
|
||||
public sealed class MidiSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IMidiManager _midiManager = default!;
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace Robust.Client.GameObjects
|
||||
public sealed class PointLightSystem : SharedPointLightSystem
|
||||
{
|
||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||
[Dependency] private readonly RenderingTreeSystem _renderingTreeSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -19,16 +20,14 @@ namespace Robust.Client.GameObjects
|
||||
private void HandleInit(EntityUid uid, PointLightComponent component, ComponentInit args)
|
||||
{
|
||||
UpdateMask(component);
|
||||
RaiseLocalEvent(uid, new PointLightUpdateEvent());
|
||||
}
|
||||
|
||||
private void HandleRemove(EntityUid uid, PointLightComponent component, ComponentRemove args)
|
||||
{
|
||||
var map = EntityManager.GetComponent<TransformComponent>(uid).MapID;
|
||||
// TODO: Just make this update the tree directly and not allocate
|
||||
if (map != MapId.Nullspace)
|
||||
if (Transform(uid).MapID != MapId.Nullspace)
|
||||
{
|
||||
EntityManager.EventBus.RaiseEvent(EventSource.Local,
|
||||
new RenderTreeRemoveLightEvent(component, map));
|
||||
_renderingTreeSystem.ClearLight(component);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,6 @@ namespace Robust.Client.GameObjects
|
||||
SubscribeLocalEvent<PointLightComponent, EntMapIdChangedMessage>(LightMapChanged);
|
||||
SubscribeLocalEvent<PointLightComponent, EntParentChangedMessage>(LightParentChanged);
|
||||
SubscribeLocalEvent<PointLightComponent, PointLightRadiusChangedEvent>(PointLightRadiusChanged);
|
||||
SubscribeLocalEvent<PointLightComponent, RenderTreeRemoveLightEvent>(RemoveLight);
|
||||
SubscribeLocalEvent<PointLightComponent, PointLightUpdateEvent>(HandleLightUpdate);
|
||||
|
||||
SubscribeLocalEvent<RenderingTreeComponent, ComponentInit>(OnTreeInit);
|
||||
@@ -114,28 +113,31 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
private void AnythingMoved(ref MoveEvent args)
|
||||
{
|
||||
AnythingMovedSubHandler(EntityManager.GetComponent<TransformComponent>(args.Sender));
|
||||
var xforms = EntityManager.GetEntityQuery<TransformComponent>();
|
||||
|
||||
AnythingMovedSubHandler(args.Sender, xforms);
|
||||
}
|
||||
|
||||
private void AnythingMovedSubHandler(TransformComponent sender)
|
||||
private void AnythingMovedSubHandler(EntityUid uid, EntityQuery<TransformComponent> xforms)
|
||||
{
|
||||
// To avoid doing redundant updates (and we don't need to update a grid's children ever)
|
||||
if (!_checkedChildren.Add(sender.Owner) ||
|
||||
EntityManager.HasComponent<RenderingTreeComponent>(sender.Owner)) return;
|
||||
if (!_checkedChildren.Add(uid) || EntityManager.HasComponent<RenderingTreeComponent>(uid)) return;
|
||||
|
||||
// This recursive search is needed, as MoveEvent is defined to not care about indirect events like children.
|
||||
// WHATEVER YOU DO, DON'T REPLACE THIS WITH SPAMMING EVENTS UNLESS YOU HAVE A GUARANTEE IT WON'T LAG THE GC.
|
||||
// (Struct-based events ok though)
|
||||
// Ironically this was lagging the GC lolz
|
||||
if (EntityManager.TryGetComponent(sender.Owner, out SpriteComponent? sprite))
|
||||
if (EntityManager.TryGetComponent(uid, out SpriteComponent? sprite))
|
||||
QueueSpriteUpdate(sprite);
|
||||
|
||||
if (EntityManager.TryGetComponent(sender.Owner, out PointLightComponent? light))
|
||||
if (EntityManager.TryGetComponent(uid, out PointLightComponent? light))
|
||||
QueueLightUpdate(light);
|
||||
|
||||
foreach (TransformComponent child in sender.Children)
|
||||
if (!xforms.TryGetComponent(uid, out var xform)) return;
|
||||
|
||||
foreach (var child in xform.ChildEntities)
|
||||
{
|
||||
AnythingMovedSubHandler(child);
|
||||
AnythingMovedSubHandler(child, xforms);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,12 +195,7 @@ namespace Robust.Client.GameObjects
|
||||
QueueLightUpdate(component);
|
||||
}
|
||||
|
||||
private void RemoveLight(EntityUid uid, PointLightComponent component, RenderTreeRemoveLightEvent args)
|
||||
{
|
||||
ClearLight(component);
|
||||
}
|
||||
|
||||
private void ClearLight(PointLightComponent component)
|
||||
public void ClearLight(PointLightComponent component)
|
||||
{
|
||||
if (component.RenderTree == null) return;
|
||||
|
||||
@@ -253,23 +250,21 @@ namespace Robust.Client.GameObjects
|
||||
EntityManager.EnsureComponent<RenderingTreeComponent>(_mapManager.GetGrid(gridId).GridEntityId);
|
||||
}
|
||||
|
||||
// TODO: Pass in TransformComponent directly: mainly interested in getting this shit working atm.
|
||||
private RenderingTreeComponent? GetRenderTree(EntityUid entity)
|
||||
private RenderingTreeComponent? GetRenderTree(EntityUid entity, EntityQuery<TransformComponent> xforms)
|
||||
{
|
||||
var lookups = EntityManager.GetEntityQuery<RenderingTreeComponent>();
|
||||
|
||||
if (!EntityManager.EntityExists(entity) ||
|
||||
!EntityManager.TryGetComponent(entity, out TransformComponent? xform) ||
|
||||
!xforms.TryGetComponent(entity, out var xform) ||
|
||||
xform.MapID == MapId.Nullspace ||
|
||||
EntityManager.HasComponent<RenderingTreeComponent>(entity)) return null;
|
||||
lookups.HasComponent(entity)) return null;
|
||||
|
||||
var parent = xform.ParentUid;
|
||||
|
||||
while (true)
|
||||
while (parent.IsValid())
|
||||
{
|
||||
if (!parent.IsValid())
|
||||
break;
|
||||
|
||||
if (EntityManager.TryGetComponent(parent, out RenderingTreeComponent? comp)) return comp;
|
||||
parent = EntityManager.GetComponent<TransformComponent>(parent).ParentUid;
|
||||
if (lookups.TryGetComponent(parent, out var comp)) return comp;
|
||||
parent = xforms.GetComponent(parent).ParentUid;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -284,6 +279,8 @@ namespace Robust.Client.GameObjects
|
||||
{
|
||||
_checkedChildren.Clear();
|
||||
|
||||
var xforms = EntityManager.GetEntityQuery<TransformComponent>();
|
||||
|
||||
foreach (var sprite in _spriteQueue)
|
||||
{
|
||||
sprite.TreeUpdateQueued = false;
|
||||
@@ -294,9 +291,9 @@ namespace Robust.Client.GameObjects
|
||||
}
|
||||
|
||||
var oldMapTree = sprite.RenderTree;
|
||||
var newMapTree = GetRenderTree(sprite.Owner);
|
||||
var newMapTree = GetRenderTree(sprite.Owner, xforms);
|
||||
// TODO: Temp PVS guard
|
||||
var xform = EntityManager.GetComponent<TransformComponent>(sprite.Owner);
|
||||
var xform = xforms.GetComponent(sprite.Owner);
|
||||
var (worldPos, worldRot) = xform.GetWorldPositionRotation();
|
||||
|
||||
if (float.IsNaN(worldPos.X) || float.IsNaN(worldPos.Y))
|
||||
@@ -305,7 +302,7 @@ namespace Robust.Client.GameObjects
|
||||
continue;
|
||||
}
|
||||
|
||||
var aabb = SpriteAabbFunc(sprite, worldPos, worldRot);
|
||||
var aabb = SpriteAabbFunc(sprite, worldPos, worldRot, xforms);
|
||||
|
||||
// If we're on a new map then clear the old one.
|
||||
if (oldMapTree != newMapTree)
|
||||
@@ -332,9 +329,9 @@ namespace Robust.Client.GameObjects
|
||||
}
|
||||
|
||||
var oldMapTree = light.RenderTree;
|
||||
var newMapTree = GetRenderTree(light.Owner);
|
||||
var newMapTree = GetRenderTree(light.Owner, xforms);
|
||||
// TODO: Temp PVS guard
|
||||
var worldPos = EntityManager.GetComponent<TransformComponent>(light.Owner).WorldPosition;
|
||||
var worldPos = xforms.GetComponent(light.Owner).WorldPosition;
|
||||
|
||||
if (float.IsNaN(worldPos.X) || float.IsNaN(worldPos.Y))
|
||||
{
|
||||
@@ -349,7 +346,7 @@ namespace Robust.Client.GameObjects
|
||||
Logger.WarningS(LoggerSawmill, $"Light radius for {light.Owner} set above max radius of {MaxLightRadius}. This may lead to pop-in.");
|
||||
}
|
||||
|
||||
var aabb = LightAabbFunc(light, worldPos);
|
||||
var aabb = LightAabbFunc(light, worldPos, xforms);
|
||||
|
||||
// If we're on a new map then clear the old one.
|
||||
if (oldMapTree != newMapTree)
|
||||
@@ -371,82 +368,44 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
private Box2 SpriteAabbFunc(in SpriteComponent value)
|
||||
{
|
||||
var xform = EntityManager.GetComponent<TransformComponent>(value.Owner);
|
||||
var xforms = EntityManager.GetEntityQuery<TransformComponent>();
|
||||
|
||||
var xform = xforms.GetComponent(value.Owner);
|
||||
var (worldPos, worldRot) = xform.GetWorldPositionRotation();
|
||||
var bounds = new Box2Rotated(value.CalculateBoundingBox(worldPos), worldRot, worldPos);
|
||||
var tree = GetRenderTree(value.Owner);
|
||||
var tree = GetRenderTree(value.Owner, xforms);
|
||||
|
||||
if (tree == null)
|
||||
{
|
||||
return bounds.CalcBoundingBox();
|
||||
}
|
||||
else
|
||||
{
|
||||
return EntityManager.GetComponent<TransformComponent>(tree.Owner).InvWorldMatrix.TransformBox(bounds);
|
||||
}
|
||||
return tree == null ? bounds.CalcBoundingBox() : xforms.GetComponent(tree.Owner).InvWorldMatrix.TransformBox(bounds);
|
||||
}
|
||||
|
||||
private Box2 LightAabbFunc(in PointLightComponent value)
|
||||
{
|
||||
var worldPos = EntityManager.GetComponent<TransformComponent>(value.Owner).WorldPosition;
|
||||
var tree = GetRenderTree(value.Owner);
|
||||
var xforms = EntityManager.GetEntityQuery<TransformComponent>();
|
||||
|
||||
var worldPos = xforms.GetComponent(value.Owner).WorldPosition;
|
||||
var tree = GetRenderTree(value.Owner, xforms);
|
||||
var boxSize = value.Radius * 2;
|
||||
|
||||
Vector2 localPos;
|
||||
if (tree == null)
|
||||
{
|
||||
localPos = worldPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Need a way to just cache this InvWorldMatrix
|
||||
localPos = EntityManager.GetComponent<TransformComponent>(tree.Owner).InvWorldMatrix.Transform(worldPos);
|
||||
}
|
||||
var localPos = tree == null ? worldPos : xforms.GetComponent(tree.Owner).InvWorldMatrix.Transform(worldPos);
|
||||
return Box2.CenteredAround(localPos, (boxSize, boxSize));
|
||||
}
|
||||
|
||||
private Box2 SpriteAabbFunc(SpriteComponent value, Vector2 worldPos, Angle worldRot)
|
||||
private Box2 SpriteAabbFunc(SpriteComponent value, Vector2 worldPos, Angle worldRot, EntityQuery<TransformComponent> xforms)
|
||||
{
|
||||
var bounds = new Box2Rotated(value.CalculateBoundingBox(worldPos), worldRot, worldPos);
|
||||
var tree = GetRenderTree(value.Owner);
|
||||
var tree = GetRenderTree(value.Owner, xforms);
|
||||
|
||||
if (tree == null)
|
||||
{
|
||||
return bounds.CalcBoundingBox();
|
||||
}
|
||||
else
|
||||
{
|
||||
return EntityManager.GetComponent<TransformComponent>(tree.Owner).InvWorldMatrix.TransformBox(bounds);
|
||||
}
|
||||
return tree == null ? bounds.CalcBoundingBox() : xforms.GetComponent(tree.Owner).InvWorldMatrix.TransformBox(bounds);
|
||||
}
|
||||
|
||||
private Box2 LightAabbFunc(PointLightComponent value, Vector2 worldPos)
|
||||
private Box2 LightAabbFunc(PointLightComponent value, Vector2 worldPos, EntityQuery<TransformComponent> xforms)
|
||||
{
|
||||
// Lights are circles so don't need entity's rotation
|
||||
var tree = GetRenderTree(value.Owner);
|
||||
var tree = GetRenderTree(value.Owner, xforms);
|
||||
var boxSize = value.Radius * 2;
|
||||
|
||||
Vector2 localPos;
|
||||
if (tree == null)
|
||||
{
|
||||
localPos = worldPos;
|
||||
} else
|
||||
{
|
||||
localPos = EntityManager.GetComponent<TransformComponent>(tree.Owner).InvWorldMatrix.Transform(worldPos);
|
||||
}
|
||||
var localPos = tree == null ? worldPos : xforms.GetComponent(tree.Owner).InvWorldMatrix.Transform(worldPos);
|
||||
return Box2.CenteredAround(localPos, (boxSize, boxSize));
|
||||
}
|
||||
}
|
||||
|
||||
internal class RenderTreeRemoveLightEvent : EntityEventArgs
|
||||
{
|
||||
public RenderTreeRemoveLightEvent(PointLightComponent light, MapId map)
|
||||
{
|
||||
Light = light;
|
||||
Map = map;
|
||||
}
|
||||
|
||||
public PointLightComponent Light { get; }
|
||||
public MapId Map { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Robust.Client.GameObjects
|
||||
/// Updates the layer animation for every visible sprite.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
public class SpriteSystem : EntitySystem
|
||||
public sealed class SpriteSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IEyeManager _eyeManager = default!;
|
||||
[Dependency] private readonly RenderingTreeSystem _treeSystem = default!;
|
||||
@@ -53,9 +53,11 @@ namespace Robust.Client.GameObjects
|
||||
return;
|
||||
}
|
||||
|
||||
var xforms = EntityManager.GetEntityQuery<TransformComponent>();
|
||||
|
||||
foreach (var comp in _treeSystem.GetRenderTrees(currentMap, pvsBounds))
|
||||
{
|
||||
var bounds = EntityManager.GetComponent<TransformComponent>(comp.Owner).InvWorldMatrix.TransformBox(pvsBounds);
|
||||
var bounds = xforms.GetComponent(comp.Owner).InvWorldMatrix.TransformBox(pvsBounds);
|
||||
|
||||
comp.SpriteTree.QueryAabb(ref frameTime, (ref float state, in SpriteComponent value) =>
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Robust.Client.GameObjects
|
||||
/// Handles interpolation of transform positions.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
internal sealed class TransformSystem : SharedTransformSystem
|
||||
public sealed class TransformSystem : SharedTransformSystem
|
||||
{
|
||||
// Max distance per tick how far an entity can move before it is considered teleporting.
|
||||
// TODO: Make these values somehow dependent on server TPS.
|
||||
|
||||
@@ -8,7 +8,7 @@ using Robust.Shared.Maths;
|
||||
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
public class VelocityDebugSystem : EntitySystem
|
||||
public sealed class VelocityDebugSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IEyeManager _eyeManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
|
||||
20
Robust.Client/GameObjects/EntitySystems/VisualizerSystem.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Robust.Client.GameObjects;
|
||||
|
||||
/// <summary>
|
||||
/// An abstract entity system inheritor for systems that deal with
|
||||
/// appearance data, replacing <see cref="AppearanceVisualizer"/>.
|
||||
/// </summary>
|
||||
public abstract class VisualizerSystem<T> : EntitySystem
|
||||
where T: Component
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<T, AppearanceChangeEvent>(OnAppearanceChange);
|
||||
}
|
||||
|
||||
protected virtual void OnAppearanceChange(EntityUid uid, T component, ref AppearanceChangeEvent args) {}
|
||||
}
|
||||