Compare commits
518 Commits
v0.7.6
...
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 | ||
|
|
d8059cacf4 | ||
|
|
374e80aad3 | ||
|
|
2fd15b0375 | ||
|
|
9293421f41 | ||
|
|
4f358b3a5e | ||
|
|
76a804d427 | ||
|
|
f8bf877b61 | ||
|
|
1f99f43755 | ||
|
|
457abf323b | ||
|
|
35d81974a8 | ||
|
|
c6a9113144 | ||
|
|
c76d1d8c5c | ||
|
|
0e289873f5 | ||
|
|
7e59febb47 | ||
|
|
fb7a231b78 | ||
|
|
85ded7a5a5 | ||
|
|
db996b9fb3 | ||
|
|
52b09cef71 | ||
|
|
26dcef4a11 | ||
|
|
9133879bd3 | ||
|
|
76b2909116 | ||
|
|
9dab8e77a7 | ||
|
|
0464b89cfe | ||
|
|
877e64f6be | ||
|
|
4df03f859b | ||
|
|
66435e6022 | ||
|
|
dc4f3b8f6f | ||
|
|
8377acb672 | ||
|
|
84c14a4657 | ||
|
|
1d5476e01b | ||
|
|
73d21da0dd | ||
|
|
81672fbe29 | ||
|
|
5655dea1c7 | ||
|
|
2616f3cedd | ||
|
|
511f272e96 | ||
|
|
3c7f87b8c3 | ||
|
|
7f89aabbb0 | ||
|
|
d6c9420a74 | ||
|
|
43e67c0db9 | ||
|
|
2e1aa16d38 | ||
|
|
849bcaeb74 | ||
|
|
dce320d0f5 | ||
|
|
d40804b41e | ||
|
|
90596c8979 | ||
|
|
36f582a712 | ||
|
|
163deff564 | ||
|
|
ca68041199 | ||
|
|
850d7ba032 | ||
|
|
4c5fefc3b2 | ||
|
|
84ee039f62 | ||
|
|
a84b481143 | ||
|
|
69fa2eed64 | ||
|
|
71f8275ae2 | ||
|
|
b89bf5739c | ||
|
|
e9ec2ee1d3 | ||
|
|
a44a25fb96 | ||
|
|
5356523305 | ||
|
|
2004ee9040 | ||
|
|
7b6d9bd719 | ||
|
|
287e57f717 | ||
|
|
add06753e9 | ||
|
|
8aa6fb478b | ||
|
|
5e7d617736 | ||
|
|
fa6c37778e | ||
|
|
4f92301d25 | ||
|
|
bd6be35b4d | ||
|
|
c39f6d09eb | ||
|
|
5eda1b326d | ||
|
|
5c3b058e81 | ||
|
|
7a06db60cf | ||
|
|
aafb15aff5 | ||
|
|
c437fadd25 | ||
|
|
bab37587c5 | ||
|
|
c4cd1fb6ee | ||
|
|
94e6886a85 | ||
|
|
e93ae73e50 | ||
|
|
9739eaa34a | ||
|
|
2aa5e8c07f | ||
|
|
f8b2412855 | ||
|
|
04782b83ab | ||
|
|
e2f2b3a26d | ||
|
|
b44a1cde88 | ||
|
|
af964b52ed | ||
|
|
ebca38b57a | ||
|
|
86d05dfa1e | ||
|
|
e10bd576ff | ||
|
|
20ff1e86c0 | ||
|
|
9d2a2ef4ba | ||
|
|
70d2457514 | ||
|
|
ba8deea700 | ||
|
|
f44d797057 | ||
|
|
e72d29a677 | ||
|
|
5730465c36 | ||
|
|
19f50d60c9 | ||
|
|
bbf5e92f32 | ||
|
|
419f4f36ab | ||
|
|
7769252109 | ||
|
|
3785777983 | ||
|
|
61aa73ffe3 | ||
|
|
ce11bf4564 | ||
|
|
0cf97780f0 | ||
|
|
fc2f6d4910 | ||
|
|
69158de99b | ||
|
|
7bec76d8d1 | ||
|
|
6e86f98406 | ||
|
|
f782e76671 | ||
|
|
5a8464b518 | ||
|
|
5f1feb9bb1 | ||
|
|
196e2bb427 | ||
|
|
f8bebee904 | ||
|
|
6515b08b41 | ||
|
|
6e2f18d0d8 | ||
|
|
a2ecd63e9d | ||
|
|
6da9176410 | ||
|
|
ae9b771c8c | ||
|
|
d1e206864c | ||
|
|
f812eb1e27 | ||
|
|
1dec0dd980 | ||
|
|
7316d9e950 | ||
|
|
f7c2305bce | ||
|
|
ebc0fc9c60 | ||
|
|
d157aab786 | ||
|
|
70a5d1bad6 | ||
|
|
2471bf8b4b | ||
|
|
e7c5706b04 | ||
|
|
7b6d8a1465 | ||
|
|
31b750bd5b | ||
|
|
6ebd0eb4ae | ||
|
|
37eac8c73f | ||
|
|
44649eea1c | ||
|
|
caa0212282 | ||
|
|
7f9d08c8f9 | ||
|
|
1c128e6b74 | ||
|
|
099e7c5c48 | ||
|
|
2f76908efb | ||
|
|
5adde7d588 | ||
|
|
7b1bb7df47 | ||
|
|
8e5eb6ebbb | ||
|
|
87ef010348 | ||
|
|
229d1c248b | ||
|
|
8db606c4e4 | ||
|
|
6b5181269b | ||
|
|
17b84c3520 | ||
|
|
42875fc101 | ||
|
|
72a7bc2ae7 | ||
|
|
bef4f75419 | ||
|
|
216509f89d | ||
|
|
b7991204f1 | ||
|
|
02987ac703 | ||
|
|
5cf8cb262f | ||
|
|
49dfca169c | ||
|
|
33008a2bce | ||
|
|
c2e90132c0 | ||
|
|
9859b5b090 | ||
|
|
20aec0a8f9 | ||
|
|
a9ee78e40d | ||
|
|
69f36aac6f | ||
|
|
173b41ab9e | ||
|
|
7796d7f065 | ||
|
|
175c111be9 | ||
|
|
279cc0f83f | ||
|
|
b334d927a5 | ||
|
|
bdb9b9af2b | ||
|
|
5aa634b5eb | ||
|
|
60d7430fe7 | ||
|
|
a9aeff9b78 | ||
|
|
e7a0409645 | ||
|
|
3e718575ff | ||
|
|
746ec9eab7 | ||
|
|
60e6ecb0cc | ||
|
|
3a00e0d497 | ||
|
|
24a5020b42 | ||
|
|
bbb9e94ce9 | ||
|
|
2bea9576f0 | ||
|
|
6e0be2b8c9 | ||
|
|
0a348dd1be | ||
|
|
a95283913b | ||
|
|
ebc73a71c2 | ||
|
|
05321f0381 | ||
|
|
6554144c42 | ||
|
|
28e6cdc92f | ||
|
|
2ec715b70e | ||
|
|
424e0768c8 | ||
|
|
e1b9327ec0 | ||
|
|
80308a799f | ||
|
|
e30f8f3e69 | ||
|
|
302b910cf3 | ||
|
|
5a6a16e7dc | ||
|
|
8d84c56a72 | ||
|
|
13f821be5f | ||
|
|
d647ab1c61 | ||
|
|
b902ef290a | ||
|
|
058d897529 | ||
|
|
8e173a7a18 | ||
|
|
5443f77526 | ||
|
|
b406526592 | ||
|
|
48697da450 | ||
|
|
06f20ea722 | ||
|
|
427378f94d | ||
|
|
6cf5021efa | ||
|
|
ad9bda2efe | ||
|
|
f0bf251acf | ||
|
|
21f5fed32f | ||
|
|
cc67a47c32 | ||
|
|
e78e7bacfe |
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
4
MSBuild/Robust.Engine.Version.props
Normal file
@@ -0,0 +1,4 @@
|
||||
<Project>
|
||||
<!-- This file automatically reset by Tools/version.py -->
|
||||
<PropertyGroup><Version>0.8.52</Version></PropertyGroup>
|
||||
</Project>
|
||||
@@ -6,4 +6,5 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<WarningsAsErrors>nullable</WarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<Import Project="Robust.Engine.Version.props" />
|
||||
</Project>
|
||||
|
||||
122
MSBuild/Robust.Trimming.targets
Normal file
@@ -0,0 +1,122 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
|
||||
<!--
|
||||
Stuff for using ILLink trimming without self-contained deployments.
|
||||
This is not something officially supported by the .NET SDK currently, but we can simply run ILLink ourselves.
|
||||
-->
|
||||
|
||||
<!--
|
||||
A lot of stuff taken from Microsoft.NET.ILLink.targets in the SDK files.
|
||||
-->
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<RobustLinkRoots>
|
||||
<Visible>false</Visible>
|
||||
</RobustLinkRoots>
|
||||
<RobustLinkAssemblies>
|
||||
<Visible>false</Visible>
|
||||
</RobustLinkAssemblies>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<Target Name="RobustILLink"
|
||||
BeforeTargets="ILLink"
|
||||
Condition="'$(PublishTrimmed)' != 'true' And
|
||||
'$(RobustILLink)' == 'true'"
|
||||
DependsOnTargets="_ComputeAssembliesToPostprocessOnPublish">
|
||||
|
||||
<ComputeManagedAssemblies Assemblies="@(ResolvedFileToPublish)">
|
||||
<Output TaskParameter="ManagedAssemblies" ItemName="_ResolvedFileToPublishFiltered" />
|
||||
</ComputeManagedAssemblies>
|
||||
|
||||
<JoinItems Left="@(_ResolvedFileToPublishFiltered)" LeftKey="FileName" LeftMetadata="*"
|
||||
Right="@(RobustLinkRoots)"
|
||||
ItemSpecToUse="Left">
|
||||
<Output TaskParameter="JoinResult" ItemName="_RobustLinkRootsJoined" />
|
||||
</JoinItems>
|
||||
|
||||
<JoinItems Left="@(_ResolvedFileToPublishFiltered)" LeftKey="FileName" LeftMetadata="*"
|
||||
Right="@(RobustLinkAssemblies)"
|
||||
ItemSpecToUse="Left">
|
||||
<Output TaskParameter="JoinResult" ItemName="_RobustLinkAssembliesJoined" />
|
||||
</JoinItems>
|
||||
|
||||
<PropertyGroup>
|
||||
<TrimMode Condition=" '$(TrimMode)' == '' ">link</TrimMode>
|
||||
<TrimmerDefaultAction Condition=" '$(TrimmerDefaultAction)' == '' ">copy</TrimmerDefaultAction>
|
||||
<_ExtraTrimmerArgs>--skip-unresolved true $(_ExtraTrimmerArgs)</_ExtraTrimmerArgs>
|
||||
<ILLinkTreatWarningsAsErrors Condition=" '$(ILLinkTreatWarningsAsErrors)' == '' ">$(TreatWarningsAsErrors)</ILLinkTreatWarningsAsErrors>
|
||||
<TrimmerSingleWarn Condition=" '$(TrimmerSingleWarn)' == '' ">true</TrimmerSingleWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<RobustAssemblyToLink Include="@(_RobustLinkRootsJoined)">
|
||||
<TrimMode>Copy</TrimMode>
|
||||
</RobustAssemblyToLink>
|
||||
<RobustAssemblyToLink Include="@(_RobustLinkAssembliesJoined)">
|
||||
<TrimMode>Link</TrimMode>
|
||||
</RobustAssemblyToLink>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- The linker implicitly picks up PDBs next to input assemblies. We will filter these out of the publish set. -->
|
||||
<__PDBToLink Include="@(ResolvedFileToPublish)" Exclude="@(RobustAssemblyToLink->'%(RelativeDir)%(Filename).pdb')" />
|
||||
<_PDBToLink Include="@(ResolvedFileToPublish)" Exclude="@(__PDBToLink)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_LinkedResolvedFileToPublishCandidate Include="@(RobustAssemblyToLink->'$(IntermediateLinkDir)%(Filename)%(Extension)')" />
|
||||
<_LinkedResolvedFileToPublishCandidate Include="@(_PDBToLink->'$(IntermediateLinkDir)%(Filename)%(Extension)')" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--<Message Text="@(ResolvedFileToPublish)" Importance="high" />-->
|
||||
|
||||
<ItemGroup>
|
||||
<_TrimmerFeatureSettings Include="@(RuntimeHostConfigurationOption)"
|
||||
Condition="'%(RuntimeHostConfigurationOption.Trim)' == 'true'" />
|
||||
</ItemGroup>
|
||||
|
||||
<Delete Files="@(_LinkedResolvedFileToPublishCandidate)" />
|
||||
<ILLink AssemblyPaths="@(RobustAssemblyToLink)"
|
||||
ReferenceAssemblyPaths="@(ReferencePath)"
|
||||
RootAssemblyNames="@(RobustLinkRoots)"
|
||||
TrimMode="Skip"
|
||||
DefaultAction="$(TrimmerDefaultAction)"
|
||||
RemoveSymbols="false"
|
||||
FeatureSettings="@(_TrimmerFeatureSettings)"
|
||||
CustomData="@(_TrimmerCustomData)"
|
||||
|
||||
BeforeFieldInit="$(_TrimmerBeforeFieldInit)"
|
||||
OverrideRemoval="$(_TrimmerOverrideRemoval)"
|
||||
UnreachableBodies="$(_TrimmerUnreachableBodies)"
|
||||
UnusedInterfaces="$(_TrimmerUnusedInterfaces)"
|
||||
IPConstProp="$(_TrimmerIPConstProp)"
|
||||
Sealer="$(_TrimmerSealer)"
|
||||
|
||||
Warn="$(ILLinkWarningLevel)"
|
||||
NoWarn="$(NoWarn)"
|
||||
TreatWarningsAsErrors="$(ILLinkTreatWarningsAsErrors)"
|
||||
WarningsAsErrors="$(WarningsAsErrors)"
|
||||
WarningsNotAsErrors="$(WarningsNotAsErrors)"
|
||||
SingleWarn="$(TrimmerSingleWarn)"
|
||||
|
||||
CustomSteps="@(_TrimmerCustomSteps)"
|
||||
RootDescriptorFiles="@(TrimmerRootDescriptor)"
|
||||
OutputDirectory="$(IntermediateLinkDir)"
|
||||
DumpDependencies="$(_TrimmerDumpDependencies)"
|
||||
ExtraArgs="$(_ExtraTrimmerArgs)"
|
||||
ToolExe="$(_DotNetHostFileName)"
|
||||
ToolPath="$(_DotNetHostDirectory)"
|
||||
ContinueOnError="ErrorAndContinue">
|
||||
<Output TaskParameter="ExitCode" PropertyName="_ILLinkExitCode" />
|
||||
</ILLink>
|
||||
|
||||
<Touch Files="$(_LinkSemaphore)" AlwaysCreate="true" Condition=" '$(_ILLinkExitCode)' == '0' " />
|
||||
|
||||
<ItemGroup>
|
||||
<_LinkedResolvedFileToPublish Include="@(_LinkedResolvedFileToPublishCandidate)" Condition="Exists('%(Identity)')" />
|
||||
<ResolvedFileToPublish Remove="@(RobustAssemblyToLink)" />
|
||||
<ResolvedFileToPublish Remove="@(_PDBToLink)" />
|
||||
<ResolvedFileToPublish Include="@(_LinkedResolvedFileToPublish)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
@@ -18,20 +18,18 @@ namespace OpenToolkit.GraphicsLibraryFramework
|
||||
NativeLibrary.SetDllImportResolver(typeof(GLFWNative).Assembly, (name, assembly, path) =>
|
||||
{
|
||||
// Please keep in sync with what Robust.Shared/DllMapHelper.cs does.
|
||||
|
||||
if (name != "glfw3.dll")
|
||||
{
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
if (OperatingSystem.IsLinux())
|
||||
{
|
||||
return NativeLibrary.Load("libglfw.so.3", assembly, path);
|
||||
}
|
||||
string rName = null;
|
||||
if (OperatingSystem.IsLinux()) rName = "libglfw.so.3";
|
||||
else if (OperatingSystem.IsMacOS()) rName = "libglfw.3.dylib";
|
||||
|
||||
if (OperatingSystem.IsMacOS())
|
||||
{
|
||||
return NativeLibrary.Load("libglfw.3.dylib", assembly, path);
|
||||
}
|
||||
if ((rName != null) && NativeLibrary.TryLoad(rName, assembly, path, out var handle))
|
||||
return handle;
|
||||
|
||||
return IntPtr.Zero;
|
||||
});
|
||||
|
||||
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)]
|
||||
|
||||
@@ -1,14 +1,23 @@
|
||||
using BenchmarkDotNet.Running;
|
||||
using BenchmarkDotNet.Configs;
|
||||
using BenchmarkDotNet.Running;
|
||||
using System;
|
||||
|
||||
namespace Robust.Benchmarks
|
||||
{
|
||||
internal class Program
|
||||
internal static class Program
|
||||
{
|
||||
// --allCategories=ctg1,ctg2
|
||||
// --anyCategories=ctg1,ctg2
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
#if DEBUG
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine("\nWARNING: YOU ARE RUNNING A DEBUG BUILD, USE A RELEASE BUILD FOR AN ACCURATE BENCHMARK");
|
||||
Console.WriteLine("THE DEBUG BUILD IS ONLY GOOD FOR FIXING A CRASHING BENCHMARK\n");
|
||||
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, new DebugInProcessConfig());
|
||||
#else
|
||||
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -301,7 +301,7 @@ namespace {nameSpace}
|
||||
foreach (var candidateClass in receiver.CandidateClasses)
|
||||
{
|
||||
var model = compilation.GetSemanticModel(candidateClass.SyntaxTree);
|
||||
var typeSymbol = (INamedTypeSymbol) model.GetDeclaredSymbol(candidateClass);
|
||||
var typeSymbol = model.GetDeclaredSymbol(candidateClass);
|
||||
var relevantAttribute = typeSymbol.GetAttributes().FirstOrDefault(attr =>
|
||||
attr.AttributeClass != null &&
|
||||
attr.AttributeClass.Equals(attributeSymbol, SymbolEqualityComparer.Default));
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<OutputType>WinExe</OutputType>
|
||||
</PropertyGroup>
|
||||
@@ -15,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>
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Animations;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Robust.Client.Animations
|
||||
{
|
||||
@@ -18,8 +19,8 @@ namespace Robust.Client.Animations
|
||||
throw new InvalidOperationException("Must set parameters to non-null values.");
|
||||
}
|
||||
|
||||
var entity = (IEntity) context;
|
||||
var component = entity.GetComponent(ComponentType);
|
||||
var entity = (EntityUid) context;
|
||||
var component = IoCManager.Resolve<IEntityManager>().GetComponent(entity, ComponentType);
|
||||
|
||||
if (component is IAnimationProperties properties)
|
||||
{
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Robust.Client.Animations
|
||||
public override (int KeyFrameIndex, float FramePlayingTime)
|
||||
AdvancePlayback(object context, int prevKeyFrameIndex, float prevPlayingTime, float frameTime)
|
||||
{
|
||||
var entity = (IEntity) context;
|
||||
var entity = (EntityUid) context;
|
||||
|
||||
var playingTime = prevPlayingTime + frameTime;
|
||||
var keyFrameIndex = prevKeyFrameIndex;
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Robust.Client.Animations
|
||||
@@ -38,8 +39,8 @@ namespace Robust.Client.Animations
|
||||
{
|
||||
DebugTools.AssertNotNull(LayerKey);
|
||||
|
||||
var entity = (IEntity) context;
|
||||
var sprite = entity.GetComponent<ISpriteComponent>();
|
||||
var entity = (EntityUid) context;
|
||||
var sprite = IoCManager.Resolve<IEntityManager>().GetComponent<ISpriteComponent>(entity);
|
||||
|
||||
var playingTime = prevPlayingTime + frameTime;
|
||||
var keyFrameIndex = prevKeyFrameIndex;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
@@ -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 = renderer.TrackingEntity.Transform.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.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;
|
||||
|
||||
@@ -150,7 +150,7 @@ namespace Robust.Client.Audio.Midi
|
||||
/// The entity whose position will be used for positional audio.
|
||||
/// This is only used if <see cref="Mono"/> is set to True.
|
||||
/// </summary>
|
||||
IEntity? TrackingEntity { get; set; }
|
||||
EntityUid? TrackingEntity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The position that will be used for positional audio.
|
||||
@@ -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!;
|
||||
@@ -297,7 +297,7 @@ namespace Robust.Client.Audio.Midi
|
||||
set
|
||||
{
|
||||
lock (_playerStateLock)
|
||||
_player?.SetLoop(value ? -1 : 1);
|
||||
_player?.SetLoop(value ? -1 : 0);
|
||||
_loopMidi = value;
|
||||
}
|
||||
}
|
||||
@@ -306,7 +306,7 @@ namespace Robust.Client.Audio.Midi
|
||||
public bool VolumeBoost { get; set; }
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public IEntity? TrackingEntity { get; set; } = null;
|
||||
public EntityUid? TrackingEntity { get; set; } = null;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public EntityCoordinates? TrackingCoordinates { get; set; } = null;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@ using Robust.Client.Debugging;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.GameStates;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Graphics.Audio;
|
||||
using Robust.Client.Graphics.Clyde;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Client.Map;
|
||||
@@ -42,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>();
|
||||
@@ -82,8 +83,9 @@ namespace Robust.Client
|
||||
case GameController.DisplayMode.Headless:
|
||||
IoCManager.Register<IClyde, ClydeHeadless>();
|
||||
IoCManager.Register<IClipboardManager, ClydeHeadless>();
|
||||
IoCManager.Register<IClydeAudio, ClydeHeadless>();
|
||||
IoCManager.Register<IClydeInternal, ClydeHeadless>();
|
||||
IoCManager.Register<IClydeAudio, ClydeAudioHeadless>();
|
||||
IoCManager.Register<IClydeAudioInternal, ClydeAudioHeadless>();
|
||||
IoCManager.Register<IInputManager, InputManager>();
|
||||
IoCManager.Register<IFileDialogManager, DummyFileDialogManager>();
|
||||
IoCManager.Register<IUriOpener, UriOpenerDummy>();
|
||||
@@ -91,8 +93,9 @@ namespace Robust.Client
|
||||
case GameController.DisplayMode.Clyde:
|
||||
IoCManager.Register<IClyde, Clyde>();
|
||||
IoCManager.Register<IClipboardManager, Clyde>();
|
||||
IoCManager.Register<IClydeAudio, Clyde>();
|
||||
IoCManager.Register<IClydeInternal, Clyde>();
|
||||
IoCManager.Register<IClydeAudio, FallbackProxyClydeAudio>();
|
||||
IoCManager.Register<IClydeAudioInternal, FallbackProxyClydeAudio>();
|
||||
IoCManager.Register<IInputManager, ClydeInputManager>();
|
||||
IoCManager.Register<IFileDialogManager, FileDialogManager>();
|
||||
IoCManager.Register<IUriOpener, UriOpener>();
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -21,13 +21,12 @@ namespace Robust.Client.Console.Commands
|
||||
return;
|
||||
}
|
||||
|
||||
var entityUid = EntityUid.Parse(args[0]);
|
||||
var entity = EntityUid.Parse(args[0]);
|
||||
var componentName = args[1];
|
||||
|
||||
var compFactory = IoCManager.Resolve<IComponentFactory>();
|
||||
var entityManager = IoCManager.Resolve<IEntityManager>();
|
||||
|
||||
var entity = entityManager.GetEntity(entityUid);
|
||||
var component = (Component) compFactory.GetComponent(componentName);
|
||||
|
||||
component.Owner = entity;
|
||||
|
||||
@@ -15,15 +15,15 @@ namespace Robust.Client.Console.Commands
|
||||
|
||||
public void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
var player = IoCManager.Resolve<IPlayerManager>().LocalPlayer;
|
||||
if (player?.ControlledEntity == null)
|
||||
var controlled = IoCManager.Resolve<IPlayerManager>().LocalPlayer?.ControlledEntity ?? EntityUid.Invalid;
|
||||
if (controlled == EntityUid.Invalid)
|
||||
{
|
||||
shell.WriteLine("You don't have an attached entity.");
|
||||
return;
|
||||
}
|
||||
|
||||
var entityManager = IoCManager.Resolve<IEntityManager>();
|
||||
entityManager.SpawnEntity(args[0], player.ControlledEntity.Transform.Coordinates);
|
||||
entityManager.SpawnEntity(args[0], entityManager.GetComponent<TransformComponent>(controlled).Coordinates);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.";
|
||||
|
||||
@@ -4,13 +4,12 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Client.Debugging;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
@@ -31,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";
|
||||
@@ -41,14 +40,14 @@ namespace Robust.Client.Console.Commands
|
||||
{
|
||||
var entityManager = IoCManager.Resolve<IEntityManager>();
|
||||
|
||||
foreach (var e in entityManager.GetEntities().OrderBy(e => e.Uid))
|
||||
foreach (var e in entityManager.GetEntities().OrderBy(e => e))
|
||||
{
|
||||
shell.WriteLine($"entity {e.Uid}, {e.Prototype?.ID}, {e.Transform.Coordinates}.");
|
||||
shell.WriteLine($"entity {e}, {entityManager.GetComponent<MetaDataComponent>(e).EntityPrototype?.ID}, {entityManager.GetComponent<TransformComponent>(e).Coordinates}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class GetComponentRegistrationCommand : IConsoleCommand
|
||||
internal sealed class GetComponentRegistrationCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "getcomponentregistration";
|
||||
public string Help => "Usage: getcomponentregistration <componentName>";
|
||||
@@ -94,7 +93,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class ToggleMonitorCommand : IConsoleCommand
|
||||
internal sealed class ToggleMonitorCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "monitor";
|
||||
|
||||
@@ -149,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";
|
||||
@@ -161,7 +160,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class ShowPositionsCommand : IConsoleCommand
|
||||
internal sealed class ShowPositionsCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "showpos";
|
||||
public string Help => "";
|
||||
@@ -174,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>";
|
||||
@@ -201,7 +200,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class DisconnectCommand : IConsoleCommand
|
||||
internal sealed class DisconnectCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "disconnect";
|
||||
public string Help => "";
|
||||
@@ -213,7 +212,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class EntityInfoCommand : IConsoleCommand
|
||||
internal sealed class EntityInfoCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "entfo";
|
||||
|
||||
@@ -238,15 +237,15 @@ namespace Robust.Client.Console.Commands
|
||||
|
||||
var uid = EntityUid.Parse(args[0]);
|
||||
var entmgr = IoCManager.Resolve<IEntityManager>();
|
||||
if (!entmgr.TryGetEntity(uid, out var entity))
|
||||
if (!entmgr.EntityExists(uid))
|
||||
{
|
||||
shell.WriteError("That entity does not exist. Sorry lad.");
|
||||
return;
|
||||
}
|
||||
|
||||
shell.WriteLine($"{entity.Uid}: {entity.Prototype?.ID}/{entity.Name}");
|
||||
shell.WriteLine($"init/del/lmt: {entity.Initialized}/{entity.Deleted}/{entity.LastModifiedTick}");
|
||||
foreach (var component in entity.GetAllComponents())
|
||||
var meta = entmgr.GetComponent<MetaDataComponent>(uid);
|
||||
shell.WriteLine($"{uid}: {meta.EntityPrototype?.ID}/{meta.EntityName}");
|
||||
shell.WriteLine($"init/del/lmt: {meta.EntityInitialized}/{meta.EntityDeleted}/{meta.EntityLastModifiedTick}");
|
||||
foreach (var component in entmgr.GetComponents(uid))
|
||||
{
|
||||
shell.WriteLine(component.ToString() ?? "");
|
||||
if (component is IComponentDebug debug)
|
||||
@@ -265,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>.";
|
||||
@@ -314,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.";
|
||||
@@ -334,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.";
|
||||
@@ -371,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.";
|
||||
@@ -405,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";
|
||||
@@ -439,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.";
|
||||
@@ -450,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");
|
||||
@@ -515,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";
|
||||
@@ -523,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();
|
||||
@@ -647,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";
|
||||
@@ -660,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";
|
||||
@@ -673,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.";
|
||||
@@ -687,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.";
|
||||
@@ -701,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).";
|
||||
@@ -715,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.";
|
||||
@@ -728,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.";
|
||||
@@ -742,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.";
|
||||
@@ -764,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.";
|
||||
@@ -777,7 +774,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class GcModeCommand : IConsoleCommand
|
||||
internal sealed class GcModeCommand : IConsoleCommand
|
||||
{
|
||||
|
||||
public string Command => "gc_mode";
|
||||
@@ -819,7 +816,7 @@ namespace Robust.Client.Console.Commands
|
||||
|
||||
}
|
||||
|
||||
internal class SerializeStatsCommand : IConsoleCommand
|
||||
internal sealed class SerializeStatsCommand : IConsoleCommand
|
||||
{
|
||||
|
||||
public string Command => "szr_stats";
|
||||
@@ -839,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.";
|
||||
@@ -868,7 +865,7 @@ namespace Robust.Client.Console.Commands
|
||||
}
|
||||
}
|
||||
|
||||
internal class ReloadShadersCommand : IConsoleCommand
|
||||
internal sealed class ReloadShadersCommand : IConsoleCommand
|
||||
{
|
||||
|
||||
public string Command => "rldshader";
|
||||
@@ -1039,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";
|
||||
@@ -1064,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.
|
||||
|
||||
@@ -79,13 +79,13 @@ namespace Robust.Client.Debugging
|
||||
|
||||
foreach (var ent in grid.GetAnchoredEntities(spot))
|
||||
{
|
||||
if (!EntityManager.TryGetEntity(ent, out var entity))
|
||||
if (EntityManager.TryGetComponent<MetaDataComponent>(ent, out var meta))
|
||||
{
|
||||
text.AppendLine($"uid: {ent}, invalid");
|
||||
text.AppendLine($"uid: {ent}, {meta.EntityName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
text.AppendLine($"uid: {ent}, {entity.Name}");
|
||||
text.AppendLine($"uid: {ent}, invalid");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,11 +7,12 @@ 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!;
|
||||
[Dependency] private readonly IEntityLookup _lookup = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
|
||||
private bool _debugPositions;
|
||||
|
||||
@@ -30,7 +31,7 @@ namespace Robust.Client.Debugging
|
||||
|
||||
if (value && !_overlayManager.HasOverlay<EntityPositionOverlay>())
|
||||
{
|
||||
_overlayManager.AddOverlay(new EntityPositionOverlay(_lookup, _eyeManager));
|
||||
_overlayManager.AddOverlay(new EntityPositionOverlay(_lookup, _eyeManager, _entityManager));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -43,13 +44,15 @@ namespace Robust.Client.Debugging
|
||||
{
|
||||
private readonly IEntityLookup _lookup;
|
||||
private readonly IEyeManager _eyeManager;
|
||||
private readonly IEntityManager _entityManager;
|
||||
|
||||
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
||||
|
||||
public EntityPositionOverlay(IEntityLookup lookup, IEyeManager eyeManager)
|
||||
public EntityPositionOverlay(IEntityLookup lookup, IEyeManager eyeManager, IEntityManager entityManager)
|
||||
{
|
||||
_lookup = lookup;
|
||||
_eyeManager = eyeManager;
|
||||
_entityManager = entityManager;
|
||||
}
|
||||
|
||||
protected internal override void Draw(in OverlayDrawArgs args)
|
||||
@@ -61,7 +64,7 @@ namespace Robust.Client.Debugging
|
||||
|
||||
foreach (var entity in _lookup.GetEntitiesIntersecting(_eyeManager.CurrentMap, viewport))
|
||||
{
|
||||
var transform = entity.Transform;
|
||||
var transform = _entityManager.GetComponent<TransformComponent>(entity);
|
||||
|
||||
var center = transform.WorldPosition;
|
||||
var worldRotation = transform.WorldRotation;
|
||||
|
||||
@@ -201,16 +201,16 @@ namespace Robust.Client.Debugging
|
||||
{
|
||||
foreach (var physBody in _physicsSystem.GetCollidingEntities(mapId, viewBounds))
|
||||
{
|
||||
if (physBody.Owner.HasComponent<MapGridComponent>()) continue;
|
||||
if (_entityManager.HasComponent<MapGridComponent>(physBody.Owner)) continue;
|
||||
|
||||
var xform = physBody.GetTransform();
|
||||
|
||||
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));
|
||||
}
|
||||
@@ -246,7 +246,7 @@ namespace Robust.Client.Debugging
|
||||
const float Alpha = 0.25f;
|
||||
float size;
|
||||
|
||||
if (physBody.Owner.HasComponent<MapGridComponent>())
|
||||
if (_entityManager.HasComponent<MapGridComponent>(physBody.Owner))
|
||||
{
|
||||
color = Color.Orange.WithAlpha(Alpha);
|
||||
size = 1f;
|
||||
@@ -267,14 +267,14 @@ namespace Robust.Client.Debugging
|
||||
{
|
||||
foreach (var physBody in _physicsSystem.GetCollidingEntities(mapId, viewBounds))
|
||||
{
|
||||
if (physBody.Owner.HasComponent<MapGridComponent>()) continue;
|
||||
if (_entityManager.HasComponent<MapGridComponent>(physBody.Owner)) continue;
|
||||
|
||||
var xform = physBody.GetTransform();
|
||||
|
||||
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++)
|
||||
{
|
||||
@@ -296,7 +296,7 @@ namespace Robust.Client.Debugging
|
||||
foreach (var jointComponent in _entityManager.EntityQuery<JointComponent>(true))
|
||||
{
|
||||
if (jointComponent.JointCount == 0 ||
|
||||
!_entityManager.TryGetComponent(jointComponent.Owner.Uid, out TransformComponent? xf1) ||
|
||||
!_entityManager.TryGetComponent(jointComponent.Owner, out TransformComponent? xf1) ||
|
||||
!viewAABB.Contains(xf1.WorldPosition)) continue;
|
||||
|
||||
foreach (var (_, joint) in jointComponent.Joints)
|
||||
@@ -350,7 +350,7 @@ namespace Robust.Client.Debugging
|
||||
|
||||
foreach (var physBody in _physicsSystem.GetCollidingEntities(mapId, bounds))
|
||||
{
|
||||
if (physBody.Owner.HasComponent<MapGridComponent>()) continue;
|
||||
if (_entityManager.HasComponent<MapGridComponent>(physBody.Owner)) continue;
|
||||
hoverBodies.Add(physBody);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ namespace Robust.Client
|
||||
[Dependency] private readonly IViewVariablesManagerInternal _viewVariablesManager = default!;
|
||||
[Dependency] private readonly IDiscordRichPresence _discord = default!;
|
||||
[Dependency] private readonly IClydeInternal _clyde = default!;
|
||||
[Dependency] private readonly IClydeAudioInternal _clydeAudio = default!;
|
||||
[Dependency] private readonly IFontManagerInternal _fontManager = default!;
|
||||
[Dependency] private readonly IModLoaderInternal _modLoader = default!;
|
||||
[Dependency] private readonly IScriptClient _scriptClient = default!;
|
||||
@@ -78,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;
|
||||
@@ -85,18 +88,25 @@ namespace Robust.Client
|
||||
|
||||
internal bool StartupContinue(DisplayMode displayMode)
|
||||
{
|
||||
DebugTools.AssertNotNull(_resourceManifest);
|
||||
|
||||
_clyde.InitializePostWindowing();
|
||||
_clyde.SetWindowTitle(Options.DefaultWindowTitle);
|
||||
_clydeAudio.InitializePostWindowing();
|
||||
_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;
|
||||
@@ -109,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);
|
||||
@@ -127,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();
|
||||
@@ -207,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)
|
||||
@@ -216,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(
|
||||
@@ -233,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)
|
||||
@@ -299,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);
|
||||
@@ -322,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;
|
||||
@@ -429,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();
|
||||
}
|
||||
|
||||
@@ -439,6 +479,7 @@ namespace Robust.Client
|
||||
private void Update(FrameEventArgs frameEventArgs)
|
||||
{
|
||||
_webViewHook?.Update();
|
||||
_clydeAudio.FrameProcess(frameEventArgs);
|
||||
_clyde.FrameProcess(frameEventArgs);
|
||||
_modLoader.BroadcastUpdate(ModUpdateLevel.FramePreEngine, frameEventArgs);
|
||||
_stateManager.FrameUpdate(frameEventArgs);
|
||||
@@ -537,8 +578,15 @@ namespace Robust.Client
|
||||
IoCManager.Resolve<IEntityLookup>().Shutdown();
|
||||
_entityManager.Shutdown();
|
||||
_clyde.Shutdown();
|
||||
_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)
|
||||
@@ -27,16 +27,11 @@ namespace Robust.Client.GameObjects
|
||||
RegisterClass<ClientOccluderComponent>();
|
||||
RegisterClass<OccluderTreeComponent>();
|
||||
RegisterClass<EyeComponent>();
|
||||
RegisterClass<AppearanceComponent>();
|
||||
RegisterClass<AnimationPlayerComponent>();
|
||||
RegisterClass<TimerComponent>();
|
||||
|
||||
#if DEBUG
|
||||
RegisterClass<DebugExceptionOnAddComponent>();
|
||||
RegisterClass<DebugExceptionInitializeComponent>();
|
||||
RegisterClass<DebugExceptionStartupComponent>();
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,19 +33,19 @@ namespace Robust.Client.GameObjects
|
||||
base.Initialize();
|
||||
}
|
||||
|
||||
IEntity IClientEntityManagerInternal.CreateEntity(string? prototypeName, EntityUid? uid)
|
||||
EntityUid IClientEntityManagerInternal.CreateEntity(string? prototypeName, EntityUid uid)
|
||||
{
|
||||
return base.CreateEntity(prototypeName, uid);
|
||||
}
|
||||
|
||||
void IClientEntityManagerInternal.InitializeEntity(IEntity entity)
|
||||
void IClientEntityManagerInternal.InitializeEntity(EntityUid entity)
|
||||
{
|
||||
base.InitializeEntity((Entity)entity);
|
||||
base.InitializeEntity(entity);
|
||||
}
|
||||
|
||||
void IClientEntityManagerInternal.StartEntity(IEntity entity)
|
||||
void IClientEntityManagerInternal.StartEntity(EntityUid entity)
|
||||
{
|
||||
base.StartEntity((Entity)entity);
|
||||
base.StartEntity(entity);
|
||||
}
|
||||
|
||||
#region IEntityNetworkManager impl
|
||||
@@ -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 />
|
||||
@@ -107,16 +107,17 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
/// <inheritdoc />
|
||||
[Obsolete("Component Messages are deprecated, use Entity Events instead.")]
|
||||
public void SendComponentNetworkMessage(INetChannel? channel, IEntity entity, IComponent component, ComponentMessage message)
|
||||
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;
|
||||
msg.EntityUid = entity.Uid;
|
||||
msg.EntityUid = entity;
|
||||
msg.NetId = netId.Value;
|
||||
msg.ComponentMessage = message;
|
||||
msg.SourceTick = _gameTiming.CurTick;
|
||||
|
||||
@@ -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,161 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Reflection;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
[ComponentReference(typeof(SharedAppearanceComponent))]
|
||||
public sealed class AppearanceComponent : SharedAppearanceComponent
|
||||
{
|
||||
[ViewVariables]
|
||||
private Dictionary<object, object> data = new();
|
||||
|
||||
[ViewVariables]
|
||||
[DataField("visuals")]
|
||||
internal List<AppearanceVisualizer> Visualizers = new();
|
||||
|
||||
[ViewVariables]
|
||||
private bool _appearanceDirty;
|
||||
|
||||
public override void SetData(string key, object value)
|
||||
{
|
||||
SetData(key, value);
|
||||
}
|
||||
|
||||
public override void SetData(Enum key, object value)
|
||||
{
|
||||
SetData(key, value);
|
||||
}
|
||||
|
||||
public override T GetData<T>(string key)
|
||||
{
|
||||
return (T) data[key];
|
||||
}
|
||||
|
||||
public override T GetData<T>(Enum key)
|
||||
{
|
||||
return (T) data[key];
|
||||
}
|
||||
|
||||
internal T GetData<T>(object key)
|
||||
{
|
||||
return (T) data[key];
|
||||
}
|
||||
|
||||
public override bool TryGetData<T>(Enum key, [NotNullWhen(true)] out T data)
|
||||
{
|
||||
return TryGetData(key, out data);
|
||||
}
|
||||
|
||||
public override bool TryGetData<T>(string key, [NotNullWhen(true)] out T data)
|
||||
{
|
||||
return TryGetData(key, out data);
|
||||
}
|
||||
|
||||
internal bool TryGetData<T>(object key, [NotNullWhen(true)] out T data)
|
||||
{
|
||||
if (this.data.TryGetValue(key, out var dat))
|
||||
{
|
||||
data = (T) dat;
|
||||
return true;
|
||||
}
|
||||
|
||||
data = default!;
|
||||
return false;
|
||||
}
|
||||
|
||||
private void SetData(object key, object value)
|
||||
{
|
||||
if (data.TryGetValue(key, out var existing) && existing.Equals(value)) return;
|
||||
|
||||
data[key] = value;
|
||||
|
||||
MarkDirty();
|
||||
}
|
||||
|
||||
public override void HandleComponentState(ComponentState? curState, ComponentState? nextState)
|
||||
{
|
||||
if (curState is not AppearanceComponentState actualState)
|
||||
return;
|
||||
|
||||
var stateDiff = data.Count != actualState.Data.Count;
|
||||
|
||||
if (!stateDiff)
|
||||
{
|
||||
foreach (var (key, value) in data)
|
||||
{
|
||||
if (!actualState.Data.TryGetValue(key, out var stateValue) ||
|
||||
!value.Equals(stateValue))
|
||||
{
|
||||
stateDiff = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!stateDiff) return;
|
||||
|
||||
data = actualState.Data;
|
||||
MarkDirty();
|
||||
}
|
||||
|
||||
internal void MarkDirty()
|
||||
{
|
||||
if (_appearanceDirty)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EntitySystem.Get<AppearanceSystem>().EnqueueUpdate(this);
|
||||
_appearanceDirty = true;
|
||||
}
|
||||
|
||||
internal void UnmarkDirty()
|
||||
{
|
||||
_appearanceDirty = false;
|
||||
}
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
foreach (var visual in Visualizers)
|
||||
{
|
||||
visual.InitializeEntity(Owner);
|
||||
}
|
||||
|
||||
MarkDirty();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the visualization of data inside of an appearance component.
|
||||
/// Implementations of this class are NOT bound to a specific entity, they are flyweighted across multiple.
|
||||
/// </summary>
|
||||
[ImplicitDataDefinitionForInheritors]
|
||||
public abstract class AppearanceVisualizer
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes an entity to be managed by this appearance controller.
|
||||
/// DO NOT assume this is your only entity. Visualizers are shared.
|
||||
/// </summary>
|
||||
public virtual void InitializeEntity(IEntity entity)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called whenever appearance data for an entity changes.
|
||||
/// Update its visuals here.
|
||||
/// </summary>
|
||||
/// <param name="component">The appearance component of the entity that might need updating.</param>
|
||||
public virtual void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
namespace Robust.Client.GameObjects;
|
||||
|
||||
/// <summary>
|
||||
/// Handles the visualization of data inside of an appearance component.
|
||||
/// Implementations of this class are NOT bound to a specific entity, they are flyweighted across multiple.
|
||||
/// </summary>
|
||||
[ImplicitDataDefinitionForInheritors]
|
||||
public abstract class AppearanceVisualizer
|
||||
{
|
||||
/// <summary>
|
||||
/// 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)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called whenever appearance data for an entity changes.
|
||||
/// 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)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Collections.Generic;
|
||||
using Robust.Shared.Analyzers;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Robust.Client.GameObjects;
|
||||
|
||||
/// <summary>
|
||||
/// This is the client instance of <see cref="AppearanceComponent"/>.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(AppearanceComponent)), Friend(typeof(AppearanceSystem))]
|
||||
public sealed class ClientAppearanceComponent : AppearanceComponent
|
||||
{
|
||||
[ViewVariables]
|
||||
[DataField("visuals")]
|
||||
internal List<AppearanceVisualizer> Visualizers = new();
|
||||
}
|
||||
@@ -3,20 +3,16 @@ using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
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!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Name => "Eye";
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
|
||||
[ViewVariables]
|
||||
private Eye? _eye = default!;
|
||||
@@ -118,7 +114,7 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
_eye = new Eye
|
||||
{
|
||||
Position = Owner.Transform.MapPosition,
|
||||
Position = _entityManager.GetComponent<TransformComponent>(Owner).MapPosition,
|
||||
Zoom = _setZoomOnInitialize,
|
||||
DrawFov = _setDrawFovOnInitialize
|
||||
};
|
||||
@@ -166,7 +162,7 @@ namespace Robust.Client.GameObjects
|
||||
public void UpdateEyePosition()
|
||||
{
|
||||
if (_eye == null) return;
|
||||
var mapPos = Owner.Transform.MapPosition;
|
||||
var mapPos = _entityManager.GetComponent<TransformComponent>(Owner).MapPosition;
|
||||
_eye.Position = new MapCoordinates(mapPos.Position, mapPos.MapId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
@@ -12,6 +11,7 @@ namespace Robust.Client.GameObjects
|
||||
internal sealed class ClientOccluderComponent : OccluderComponent
|
||||
{
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
|
||||
[ViewVariables] private (GridId, Vector2i) _lastPosition;
|
||||
[ViewVariables] internal OccluderDir Occluding { get; private set; }
|
||||
@@ -32,7 +32,7 @@ namespace Robust.Client.GameObjects
|
||||
{
|
||||
base.Startup();
|
||||
|
||||
if (Owner.Transform.Anchored)
|
||||
if (_entityManager.GetComponent<TransformComponent>(Owner).Anchored)
|
||||
{
|
||||
AnchorStateChanged();
|
||||
}
|
||||
@@ -40,13 +40,14 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
public void AnchorStateChanged()
|
||||
{
|
||||
SendDirty();
|
||||
var xform = _entityManager.GetComponent<TransformComponent>(Owner);
|
||||
SendDirty(xform);
|
||||
|
||||
if(!Owner.Transform.Anchored)
|
||||
if(!xform.Anchored)
|
||||
return;
|
||||
|
||||
var grid = _mapManager.GetGrid(Owner.Transform.GridID);
|
||||
_lastPosition = (Owner.Transform.GridID, grid.TileIndicesFor(Owner.Transform.Coordinates));
|
||||
var grid = _mapManager.GetGrid(xform.GridID);
|
||||
_lastPosition = (xform.GridID, grid.TileIndicesFor(xform.Coordinates));
|
||||
}
|
||||
|
||||
protected override void Shutdown()
|
||||
@@ -56,11 +57,12 @@ namespace Robust.Client.GameObjects
|
||||
SendDirty();
|
||||
}
|
||||
|
||||
private void SendDirty()
|
||||
private void SendDirty(TransformComponent? xform = null)
|
||||
{
|
||||
if (Owner.Transform.Anchored)
|
||||
xform ??= _entityManager.GetComponent<TransformComponent>(Owner);
|
||||
if (xform.Anchored)
|
||||
{
|
||||
Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local,
|
||||
_entityManager.EventBus.RaiseEvent(EventSource.Local,
|
||||
new OccluderDirtyEvent(Owner, _lastPosition));
|
||||
}
|
||||
}
|
||||
@@ -69,18 +71,18 @@ namespace Robust.Client.GameObjects
|
||||
{
|
||||
Occluding = OccluderDir.None;
|
||||
|
||||
if (Deleted || !Owner.Transform.Anchored)
|
||||
if (Deleted || !_entityManager.GetComponent<TransformComponent>(Owner).Anchored)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var grid = _mapManager.GetGrid(_entityManager.GetComponent<TransformComponent>(Owner).GridID);
|
||||
var position = _entityManager.GetComponent<TransformComponent>(Owner).Coordinates;
|
||||
void CheckDir(Direction dir, OccluderDir oclDir)
|
||||
{
|
||||
var grid = _mapManager.GetGrid(Owner.Transform.GridID);
|
||||
var position = Owner.Transform.Coordinates;
|
||||
foreach (var neighbor in grid.GetInDir(position, dir))
|
||||
{
|
||||
if (Owner.EntityManager.TryGetComponent(neighbor, out ClientOccluderComponent? comp) && comp.Enabled)
|
||||
if (_entityManager.TryGetComponent(neighbor, out ClientOccluderComponent? comp) && comp.Enabled)
|
||||
{
|
||||
Occluding |= oclDir;
|
||||
break;
|
||||
@@ -88,10 +90,20 @@ namespace Robust.Client.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
CheckDir(Direction.North, OccluderDir.North);
|
||||
CheckDir(Direction.East, OccluderDir.East);
|
||||
CheckDir(Direction.South, OccluderDir.South);
|
||||
CheckDir(Direction.West, OccluderDir.West);
|
||||
var angle = _entityManager.GetComponent<TransformComponent>(Owner).LocalRotation;
|
||||
var dirRolling = angle.GetCardinalDir();
|
||||
// dirRolling starts at effective south
|
||||
|
||||
CheckDir(dirRolling, OccluderDir.South);
|
||||
dirRolling = dirRolling.GetClockwise90Degrees();
|
||||
|
||||
CheckDir(dirRolling, OccluderDir.West);
|
||||
dirRolling = dirRolling.GetClockwise90Degrees();
|
||||
|
||||
CheckDir(dirRolling, OccluderDir.North);
|
||||
dirRolling = dirRolling.GetClockwise90Degrees();
|
||||
|
||||
CheckDir(dirRolling, OccluderDir.East);
|
||||
}
|
||||
|
||||
[Flags]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Animations;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
@@ -10,8 +11,10 @@ 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!;
|
||||
|
||||
internal bool TreeUpdateQueued { get; set; }
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
@@ -31,7 +34,7 @@ namespace Robust.Client.GameObjects
|
||||
{
|
||||
if (_enabled == value) return;
|
||||
base.Enabled = value;
|
||||
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, new PointLightUpdateEvent());
|
||||
_entityManager.EventBus.RaiseLocalEvent(Owner, new PointLightUpdateEvent());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +47,7 @@ namespace Robust.Client.GameObjects
|
||||
if (_containerOccluded == value) return;
|
||||
|
||||
_containerOccluded = value;
|
||||
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, new PointLightUpdateEvent());
|
||||
_entityManager.EventBus.RaiseLocalEvent(Owner, new PointLightUpdateEvent());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,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
|
||||
{
|
||||
@@ -131,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;
|
||||
|
||||
@@ -151,7 +131,7 @@ namespace Robust.Client.GameObjects
|
||||
if (MathHelper.CloseToPercent(value, _radius)) return;
|
||||
|
||||
base.Radius = value;
|
||||
Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local, new PointLightRadiusChangedEvent(this));
|
||||
_entityManager.EventBus.RaiseEvent(EventSource.Local, new PointLightRadiusChangedEvent(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,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; }
|
||||
|
||||
|
||||
@@ -23,6 +23,11 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
public sealed class SpriteBoundsSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IEyeManager _eye = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly IOverlayManager _overlayManager = default!;
|
||||
[Dependency] private readonly RenderingTreeSystem _renderingTree = default!;
|
||||
|
||||
private SpriteBoundsOverlay? _overlay;
|
||||
|
||||
public bool Enabled
|
||||
@@ -37,15 +42,13 @@ namespace Robust.Client.GameObjects
|
||||
if (_enabled)
|
||||
{
|
||||
DebugTools.AssertNull(_overlay);
|
||||
var overlayManager = IoCManager.Resolve<IOverlayManager>();
|
||||
_overlay = new SpriteBoundsOverlay(EntitySystem.Get<RenderingTreeSystem>(), IoCManager.Resolve<IEyeManager>());
|
||||
overlayManager.AddOverlay(_overlay);
|
||||
_overlay = new SpriteBoundsOverlay(_renderingTree, _eye, _entityManager);
|
||||
_overlayManager.AddOverlay(_overlay);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_overlay == null) return;
|
||||
var overlayManager = IoCManager.Resolve<IOverlayManager>();
|
||||
overlayManager.RemoveOverlay(_overlay);
|
||||
_overlayManager.RemoveOverlay(_overlay);
|
||||
_overlay = null;
|
||||
}
|
||||
}
|
||||
@@ -54,17 +57,19 @@ namespace Robust.Client.GameObjects
|
||||
private bool _enabled;
|
||||
}
|
||||
|
||||
public class SpriteBoundsOverlay : Overlay
|
||||
public sealed class SpriteBoundsOverlay : Overlay
|
||||
{
|
||||
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
||||
|
||||
private readonly IEyeManager _eyeManager = default!;
|
||||
private readonly IEyeManager _eyeManager;
|
||||
private readonly IEntityManager _entityManager;
|
||||
private RenderingTreeSystem _renderTree;
|
||||
|
||||
public SpriteBoundsOverlay(RenderingTreeSystem renderTree, IEyeManager eyeManager)
|
||||
public SpriteBoundsOverlay(RenderingTreeSystem renderTree, IEyeManager eyeManager, IEntityManager entityManager)
|
||||
{
|
||||
_renderTree = renderTree;
|
||||
_eyeManager = eyeManager;
|
||||
_entityManager = entityManager;
|
||||
}
|
||||
|
||||
protected internal override void Draw(in OverlayDrawArgs args)
|
||||
@@ -75,11 +80,11 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
foreach (var comp in _renderTree.GetRenderTrees(currentMap, viewport))
|
||||
{
|
||||
var localAABB = comp.Owner.Transform.InvWorldMatrix.TransformBox(viewport);
|
||||
var localAABB = _entityManager.GetComponent<TransformComponent>(comp.Owner).InvWorldMatrix.TransformBox(viewport);
|
||||
|
||||
foreach (var sprite in comp.SpriteTree.QueryAabb(localAABB))
|
||||
{
|
||||
var worldPos = sprite.Owner.Transform.WorldPosition;
|
||||
var worldPos = _entityManager.GetComponent<TransformComponent>(sprite.Owner).WorldPosition;
|
||||
var bounds = sprite.CalculateBoundingBox(worldPos);
|
||||
handle.DrawRect(bounds, Color.Red.WithAlpha(0.2f));
|
||||
handle.DrawRect(bounds.Scale(0.2f).Translated(-new Vector2(0f, bounds.Extents.Y)), Color.Blue.WithAlpha(0.5f));
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -13,14 +12,11 @@ using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Reflection;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using DrawDepthTag = Robust.Shared.GameObjects.DrawDepth;
|
||||
@@ -34,6 +30,7 @@ namespace Robust.Client.GameObjects
|
||||
{
|
||||
[Dependency] private readonly IResourceCache resourceCache = default!;
|
||||
[Dependency] private readonly IPrototypeManager prototypes = default!;
|
||||
[Dependency] private readonly IEntityManager entities = default!;
|
||||
|
||||
[DataField("visible")]
|
||||
private bool _visible = true;
|
||||
@@ -47,7 +44,7 @@ namespace Robust.Client.GameObjects
|
||||
if (_visible == value) return;
|
||||
_visible = value;
|
||||
|
||||
Owner.EntityManager.EventBus.RaiseLocalEvent(OwnerUid, new SpriteUpdateEvent());
|
||||
entities.EventBus.RaiseLocalEvent(Owner, new SpriteUpdateEvent());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,6 +210,7 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
layer.Color = layerDatum.Color;
|
||||
layer.Rotation = layerDatum.Rotation;
|
||||
layer._offset = layerDatum.Offset;
|
||||
// If neither state: nor texture: were provided we assume that they want a blank invisible layer.
|
||||
layer.Visible = anyTextureAttempted && layerDatum.Visible;
|
||||
layer.Scale = layerDatum.Scale;
|
||||
@@ -302,7 +300,7 @@ namespace Robust.Client.GameObjects
|
||||
{
|
||||
if (_containerOccluded == value) return;
|
||||
_containerOccluded = value;
|
||||
Owner.EntityManager.EventBus.RaiseLocalEvent(OwnerUid, new SpriteUpdateEvent());
|
||||
entities.EventBus.RaiseLocalEvent(Owner, new SpriteUpdateEvent());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1259,7 +1257,10 @@ namespace Robust.Client.GameObjects
|
||||
if (worldRotation.Theta < 0)
|
||||
worldRotation = new Angle(worldRotation.Theta + Math.Tau);
|
||||
|
||||
var localMatrix = 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)
|
||||
{
|
||||
@@ -1270,9 +1271,10 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
var numDirs = GetLayerDirectionCount(layer);
|
||||
var layerRotation = worldRotation + layer.Rotation;
|
||||
var layerPosition = worldPosition + layerRotation.RotateVec(layer._offset + offset);
|
||||
|
||||
CalcModelMatrix(numDirs, eyeRotation, layerRotation, worldPosition, out var modelMatrix);
|
||||
Matrix3.Multiply(ref localMatrix, ref modelMatrix, out var transformMatrix);
|
||||
CalcModelMatrix(numDirs, eyeRotation, layerRotation, layerPosition, out var modelMatrix);
|
||||
Matrix3.Multiply(ref spriteMatrix, ref modelMatrix, out var transformMatrix);
|
||||
drawingHandle.SetTransform(in transformMatrix);
|
||||
|
||||
RenderLayer(drawingHandle, layer, eyeRotation, layerRotation, overrideDirection);
|
||||
@@ -1290,7 +1292,7 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
var layerColor = color * layer.Color;
|
||||
|
||||
var position = -(Vector2)texture.Size / (2f * EyeManager.PixelsPerMeter) + layer.Offset;
|
||||
var position = -(Vector2)texture.Size / (2f * EyeManager.PixelsPerMeter);
|
||||
var textureSize = texture.Size / (float)EyeManager.PixelsPerMeter;
|
||||
var quad = Box2.FromDimensions(position, textureSize);
|
||||
|
||||
@@ -1475,35 +1477,11 @@ 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.
|
||||
// If you really want it optimal you'll need to comb through all 2k lines of spritecomponent.
|
||||
if (Owner?.EntityManager?.EventBus != null)
|
||||
if ((Owner != default ? entities : null)?.EventBus != null)
|
||||
UpdateBounds();
|
||||
|
||||
if (_inertUpdateQueued)
|
||||
@@ -1512,7 +1490,7 @@ namespace Robust.Client.GameObjects
|
||||
_inertUpdateQueued = true;
|
||||
// Yes that null check is valid because of that stupid fucking dummy IEntity.
|
||||
// Who thought that was a good idea.
|
||||
Owner?.EntityManager?.EventBus?.RaiseEvent(EventSource.Local, new SpriteUpdateInertEvent {Sprite = this});
|
||||
(Owner != default ? entities : null)?.EventBus?.RaiseEvent(EventSource.Local, new SpriteUpdateInertEvent {Sprite = this});
|
||||
}
|
||||
|
||||
internal void DoUpdateIsInert()
|
||||
@@ -1548,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, Owner.Transform.WorldRotation),
|
||||
Color, NoRotation, entities.GetComponent<TransformComponent>(Owner).WorldRotation.ToRsiDirection(RSI.State.DirectionType.Dir8),
|
||||
DirectionOverride
|
||||
);
|
||||
|
||||
@@ -1653,7 +1586,7 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
internal void UpdateBounds()
|
||||
{
|
||||
Owner.EntityManager.EventBus.RaiseLocalEvent(OwnerUid, new SpriteUpdateEvent());
|
||||
entities.EventBus.RaiseLocalEvent(Owner, new SpriteUpdateEvent());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1682,7 +1615,7 @@ namespace Robust.Client.GameObjects
|
||||
Flip = 3,
|
||||
}
|
||||
|
||||
public class Layer : ISpriteLayer
|
||||
public sealed class Layer : ISpriteLayer
|
||||
{
|
||||
[ViewVariables] private readonly SpriteComponent _parent;
|
||||
|
||||
@@ -1723,7 +1656,7 @@ namespace Robust.Client.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
private Vector2 _offset;
|
||||
internal Vector2 _offset;
|
||||
|
||||
[ViewVariables]
|
||||
public DirectionOffset DirOffset { get; set; }
|
||||
@@ -1840,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2072,8 +2005,9 @@ namespace Robust.Client.GameObjects
|
||||
}
|
||||
|
||||
var entityManager = IoCManager.Resolve<IEntityManager>();
|
||||
var dummy = entityManager.SpawnEntity(prototype.ID, MapCoordinates.Nullspace).Uid;
|
||||
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)
|
||||
@@ -2111,7 +2045,7 @@ namespace Robust.Client.GameObjects
|
||||
}
|
||||
|
||||
var entityManager = IoCManager.Resolve<IEntityManager>();
|
||||
var dummy = entityManager.SpawnEntity(prototype.ID, MapCoordinates.Nullspace).Uid;
|
||||
var dummy = entityManager.SpawnEntity(prototype.ID, MapCoordinates.Nullspace);
|
||||
var spriteComponent = entityManager.EnsureComponent<SpriteComponent>(dummy);
|
||||
var result = spriteComponent.Icon ?? GetFallbackState(resourceCache);
|
||||
entityManager.DeleteEntity(dummy);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Physics;
|
||||
|
||||
namespace Robust.Client.GameObjects
|
||||
@@ -7,57 +6,7 @@ namespace Robust.Client.GameObjects
|
||||
[RegisterComponent]
|
||||
public sealed class RenderingTreeComponent : Component
|
||||
{
|
||||
public override string Name => "RenderingTree";
|
||||
|
||||
internal DynamicTree<SpriteComponent> SpriteTree { get; private set; } = new(SpriteAabbFunc);
|
||||
internal DynamicTree<PointLightComponent> LightTree { get; private set; } = new(LightAabbFunc);
|
||||
|
||||
private static Box2 SpriteAabbFunc(in SpriteComponent value)
|
||||
{
|
||||
var worldPos = value.Owner.Transform.WorldPosition;
|
||||
var worldRot = value.Owner.Transform.WorldRotation;
|
||||
var bounds = new Box2Rotated(value.CalculateBoundingBox(worldPos), worldRot, worldPos);
|
||||
var tree = RenderingTreeSystem.GetRenderTree(value.Owner);
|
||||
|
||||
var localAABB = tree?.Owner.Transform.InvWorldMatrix.TransformBox(bounds) ?? bounds.CalcBoundingBox();
|
||||
|
||||
return localAABB;
|
||||
}
|
||||
|
||||
private static Box2 LightAabbFunc(in PointLightComponent value)
|
||||
{
|
||||
var worldPos = value.Owner.Transform.WorldPosition;
|
||||
var tree = RenderingTreeSystem.GetRenderTree(value.Owner);
|
||||
var boxSize = value.Radius * 2;
|
||||
|
||||
var localPos = tree?.Owner.Transform.InvWorldMatrix.Transform(worldPos) ?? worldPos;
|
||||
|
||||
return Box2.CenteredAround(localPos, (boxSize, boxSize));
|
||||
}
|
||||
|
||||
internal static Box2 SpriteAabbFunc(SpriteComponent value, Vector2? worldPos = null, Angle? worldRot = null)
|
||||
{
|
||||
worldPos ??= value.Owner.Transform.WorldPosition;
|
||||
worldRot ??= value.Owner.Transform.WorldRotation;
|
||||
var bounds = new Box2Rotated(value.CalculateBoundingBox(worldPos.Value), worldRot.Value, worldPos.Value);
|
||||
var tree = RenderingTreeSystem.GetRenderTree(value.Owner);
|
||||
|
||||
var localAABB = tree?.Owner.Transform.InvWorldMatrix.TransformBox(bounds) ?? bounds.CalcBoundingBox();
|
||||
|
||||
return localAABB;
|
||||
}
|
||||
|
||||
internal static Box2 LightAabbFunc(PointLightComponent value, Vector2? worldPos = null)
|
||||
{
|
||||
// Lights are circles so don't need entity's rotation
|
||||
|
||||
worldPos ??= value.Owner.Transform.WorldPosition;
|
||||
var tree = RenderingTreeSystem.GetRenderTree(value.Owner);
|
||||
var boxSize = value.Radius * 2;
|
||||
|
||||
var localPos = tree?.Owner.Transform.InvWorldMatrix.Transform(worldPos.Value) ?? worldPos.Value;
|
||||
|
||||
return Box2.CenteredAround(localPos, (boxSize, boxSize));
|
||||
}
|
||||
internal DynamicTree<SpriteComponent> SpriteTree { get; set; } = default!;
|
||||
internal DynamicTree<PointLightComponent> LightTree { get; set; } = default!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,12 @@ 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!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
|
||||
private readonly Dictionary<object, BoundUserInterface> _openInterfaces =
|
||||
new();
|
||||
@@ -87,15 +89,15 @@ namespace Robust.Client.GameObjects
|
||||
_openInterfaces.Remove(uiKey);
|
||||
boundUserInterface.Dispose();
|
||||
|
||||
var playerSession = IoCManager.Resolve<IPlayerManager>().LocalPlayer?.Session;
|
||||
var playerSession = _playerManager.LocalPlayer?.Session;
|
||||
if(playerSession != null)
|
||||
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, new BoundUIClosedEvent(uiKey, Owner.Uid, playerSession));
|
||||
_entityManager.EventBus.RaiseLocalEvent(Owner, new BoundUIClosedEvent(uiKey, Owner, playerSession));
|
||||
}
|
||||
|
||||
internal void SendMessage(BoundUserInterfaceMessage message, object uiKey)
|
||||
{
|
||||
EntitySystem.Get<UserInterfaceSystem>()
|
||||
.Send(new BoundUIWrapMessage(Owner.Uid, message, uiKey));
|
||||
.Send(new BoundUIWrapMessage(Owner, message, uiKey));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Robust.Client.GameObjects
|
||||
foreach (var key in remie)
|
||||
{
|
||||
component.PlayingAnimations.Remove(key);
|
||||
EntityManager.EventBus.RaiseLocalEvent(component.Owner.Uid, new AnimationCompletedEvent {Uid = component.Owner.Uid, Key = key});
|
||||
EntityManager.EventBus.RaiseLocalEvent(component.Owner, new AnimationCompletedEvent {Uid = component.Owner, Key = key});
|
||||
component.AnimationComplete(key);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,13 @@ namespace Robust.Client.GameObjects
|
||||
/// </summary>
|
||||
public void Play(EntityUid uid, Animation animation, string key)
|
||||
{
|
||||
var component = EntityManager.EnsureComponent<AnimationPlayerComponent>(EntityManager.GetEntity(uid));
|
||||
var component = EntityManager.EnsureComponent<AnimationPlayerComponent>(uid);
|
||||
Play(component, animation, key);
|
||||
}
|
||||
|
||||
public void Play(EntityUid uid, AnimationPlayerComponent? component, Animation animation, string key)
|
||||
{
|
||||
component ??= EntityManager.EnsureComponent<AnimationPlayerComponent>(uid);
|
||||
Play(component, animation, key);
|
||||
}
|
||||
|
||||
@@ -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 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<AppearanceComponent> _queuedUpdates = new();
|
||||
private readonly Queue<ClientAppearanceComponent> _queuedUpdates = new();
|
||||
|
||||
public void EnqueueUpdate(AppearanceComponent 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!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.Audio;
|
||||
using Robust.Client.Graphics;
|
||||
@@ -18,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!;
|
||||
@@ -82,8 +81,8 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
private void PlayAudioEntityHandler(PlayAudioEntityMessage ev)
|
||||
{
|
||||
var stream = EntityManager.TryGetEntity(ev.EntityUid, out var entity) ?
|
||||
(PlayingStream?) Play(ev.FileName, entity, ev.FallbackCoordinates, ev.AudioParams)
|
||||
var stream = EntityManager.EntityExists(ev.EntityUid) ?
|
||||
(PlayingStream?) Play(ev.FileName, ev.EntityUid, ev.FallbackCoordinates, ev.AudioParams)
|
||||
: (PlayingStream?) Play(ev.FileName, ev.Coordinates, ev.FallbackCoordinates, ev.AudioParams);
|
||||
|
||||
if (stream != null)
|
||||
@@ -123,15 +122,15 @@ namespace Robust.Client.GameObjects
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (stream.TrackingEntity != null)
|
||||
else if (stream.TrackingEntity != default)
|
||||
{
|
||||
if (stream.TrackingEntity.Deleted)
|
||||
if (EntityManager.Deleted(stream.TrackingEntity))
|
||||
{
|
||||
StreamDone(stream);
|
||||
continue;
|
||||
}
|
||||
|
||||
mapPos = stream.TrackingEntity.Transform.MapPosition;
|
||||
mapPos = EntityManager.GetComponent<TransformComponent>(stream.TrackingEntity).MapPosition;
|
||||
}
|
||||
|
||||
// TODO Remove when coordinates can't be NaN
|
||||
@@ -211,7 +210,7 @@ namespace Robust.Client.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
if (stream.TrackingEntity != null)
|
||||
if (stream.TrackingEntity != default)
|
||||
{
|
||||
stream.Source.SetVelocity(stream.TrackingEntity.GlobalLinearVelocity());
|
||||
}
|
||||
@@ -254,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();
|
||||
@@ -281,7 +286,7 @@ namespace Robust.Client.GameObjects
|
||||
/// <param name="entity">The entity "emitting" the audio.</param>
|
||||
/// <param name="fallbackCoordinates">The map or grid coordinates at which to play the audio when entity is invalid.</param>
|
||||
/// <param name="audioParams"></param>
|
||||
private IPlayingAudioStream? Play(string filename, IEntity entity, EntityCoordinates fallbackCoordinates,
|
||||
private IPlayingAudioStream? Play(string filename, EntityUid entity, EntityCoordinates fallbackCoordinates,
|
||||
AudioParams? audioParams = null)
|
||||
{
|
||||
if (_resourceCache.TryGetResource<AudioResource>(new ResourcePath(filename), out var audio))
|
||||
@@ -300,11 +305,17 @@ namespace Robust.Client.GameObjects
|
||||
/// <param name="entity">The entity "emitting" the audio.</param>
|
||||
/// <param name="fallbackCoordinates">The map or grid coordinates at which to play the audio when entity is invalid.</param>
|
||||
/// <param name="audioParams"></param>
|
||||
private IPlayingAudioStream? Play(AudioStream stream, IEntity entity, EntityCoordinates fallbackCoordinates,
|
||||
private IPlayingAudioStream? Play(AudioStream stream, EntityUid entity, EntityCoordinates fallbackCoordinates,
|
||||
AudioParams? audioParams = null)
|
||||
{
|
||||
var source = _clyde.CreateAudioSource(stream);
|
||||
if (!source.SetPosition(entity.Transform.WorldPosition))
|
||||
|
||||
if (source == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!source.SetPosition(EntityManager.GetComponent<TransformComponent>(entity).WorldPosition))
|
||||
{
|
||||
return Play(stream, fallbackCoordinates, fallbackCoordinates, audioParams);
|
||||
}
|
||||
@@ -357,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();
|
||||
@@ -403,11 +420,11 @@ 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!;
|
||||
public IEntity TrackingEntity = default!;
|
||||
public EntityUid TrackingEntity = default!;
|
||||
public EntityCoordinates? TrackingCoordinates;
|
||||
public EntityCoordinates? TrackingFallbackCoordinates;
|
||||
public bool Done;
|
||||
@@ -440,9 +457,6 @@ namespace Robust.Client.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int DefaultSoundRange => 25;
|
||||
|
||||
/// <inheritdoc />
|
||||
public int OcclusionCollisionMask { get; set; }
|
||||
|
||||
@@ -453,15 +467,9 @@ namespace Robust.Client.GameObjects
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IPlayingAudioStream? Play(Filter playerFilter, string filename, IEntity entity, AudioParams? audioParams = null)
|
||||
public IPlayingAudioStream? Play(Filter playerFilter, string filename, EntityUid entity, AudioParams? audioParams = null)
|
||||
{
|
||||
return Play(filename, entity, GetFallbackCoordinates(entity.Transform.MapPosition), audioParams);
|
||||
}
|
||||
|
||||
public IPlayingAudioStream? Play(Filter playerFilter, string filename, EntityUid uid, AudioParams? audioParams = null)
|
||||
{
|
||||
return EntityManager.TryGetEntity(uid, out var entity)
|
||||
? Play(filename, entity, GetFallbackCoordinates(entity.Transform.MapPosition), audioParams) : null;
|
||||
return Play(filename, entity, GetFallbackCoordinates(EntityManager.GetComponent<TransformComponent>(entity).MapPosition), audioParams);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -70,14 +70,17 @@ namespace Robust.Client.GameObjects
|
||||
private void HandleDirtyEvent(OccluderDirtyEvent ev)
|
||||
{
|
||||
var sender = ev.Sender;
|
||||
if (sender.IsValid() &&
|
||||
sender.TryGetComponent(out ClientOccluderComponent? iconSmooth)
|
||||
&& iconSmooth.Running)
|
||||
if (EntityManager.EntityExists(sender) &&
|
||||
EntityManager.TryGetComponent(sender, out ClientOccluderComponent? iconSmooth)
|
||||
&& iconSmooth.Initialized)
|
||||
{
|
||||
var grid1 = _mapManager.GetGrid(sender.Transform.GridID);
|
||||
var coords = sender.Transform.Coordinates;
|
||||
var xform = EntityManager.GetComponent<TransformComponent>(sender);
|
||||
if (!_mapManager.TryGetGrid(xform.GridID, out var grid1))
|
||||
return;
|
||||
|
||||
_dirtyEntities.Enqueue(sender.Uid);
|
||||
var coords = xform.Coordinates;
|
||||
|
||||
_dirtyEntities.Enqueue(sender);
|
||||
AddValidEntities(grid1.GetInDir(coords, Direction.North));
|
||||
AddValidEntities(grid1.GetInDir(coords, Direction.South));
|
||||
AddValidEntities(grid1.GetInDir(coords, Direction.East));
|
||||
@@ -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;
|
||||
|
||||
@@ -113,13 +116,13 @@ namespace Robust.Client.GameObjects
|
||||
/// </summary>
|
||||
internal sealed class OccluderDirtyEvent : EntityEventArgs
|
||||
{
|
||||
public OccluderDirtyEvent(IEntity sender, (GridId grid, Vector2i pos)? lastPosition)
|
||||
public OccluderDirtyEvent(EntityUid sender, (GridId grid, Vector2i pos)? lastPosition)
|
||||
{
|
||||
LastPosition = lastPosition;
|
||||
Sender = sender;
|
||||
}
|
||||
|
||||
public (GridId grid, Vector2i pos)? LastPosition { get; }
|
||||
public IEntity Sender { get; }
|
||||
public EntityUid Sender { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,17 +5,19 @@ 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!;
|
||||
|
||||
private readonly HashSet<IEntity> _updateQueue = new();
|
||||
private readonly HashSet<EntityUid> _updateQueue = new();
|
||||
|
||||
public readonly Dictionary<EntityUid, IContainer> ExpectedEntities = new();
|
||||
|
||||
@@ -37,10 +39,10 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
private void HandleEntityInitialized(EntityInitializedMessage ev)
|
||||
{
|
||||
if (!ExpectedEntities.TryGetValue(ev.Entity.Uid, out var container))
|
||||
if (!ExpectedEntities.TryGetValue(ev.Entity, out var container))
|
||||
return;
|
||||
|
||||
RemoveExpectedEntity(ev.Entity.Uid);
|
||||
RemoveExpectedEntity(ev.Entity);
|
||||
|
||||
if (container.Deleted)
|
||||
return;
|
||||
@@ -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);
|
||||
@@ -89,12 +91,12 @@ namespace Robust.Client.GameObjects
|
||||
container.OccludesLight = occludesLight;
|
||||
|
||||
// Remove gone entities.
|
||||
List<IEntity>? toRemove = null;
|
||||
List<EntityUid>? toRemove = null;
|
||||
foreach (var entity in container.ContainedEntities)
|
||||
{
|
||||
if (!entityUids.Contains(entity.Uid))
|
||||
if (!entityUids.Contains(entity))
|
||||
{
|
||||
toRemove ??= new List<IEntity>();
|
||||
toRemove ??= new List<EntityUid>();
|
||||
toRemove.Add(entity);
|
||||
}
|
||||
}
|
||||
@@ -123,11 +125,24 @@ namespace Robust.Client.GameObjects
|
||||
}
|
||||
|
||||
// Add new entities.
|
||||
foreach (var entityUid in entityUids)
|
||||
foreach (var entity in entityUids)
|
||||
{
|
||||
if (!EntityManager.TryGetEntity(entityUid, out var entity))
|
||||
if (!EntityManager.EntityExists(entity))
|
||||
{
|
||||
AddExpectedEntity(entityUid, container);
|
||||
AddExpectedEntity(entity, container);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -137,6 +152,32 @@ namespace Robust.Client.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -172,7 +213,7 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
foreach (var toUpdate in _updateQueue)
|
||||
{
|
||||
if (toUpdate.Deleted)
|
||||
if (EntityManager.Deleted(toUpdate))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -183,22 +224,22 @@ namespace Robust.Client.GameObjects
|
||||
_updateQueue.Clear();
|
||||
}
|
||||
|
||||
private static void UpdateEntityRecursively(IEntity entity)
|
||||
private void UpdateEntityRecursively(EntityUid entity)
|
||||
{
|
||||
// TODO: Since we are recursing down,
|
||||
// we could cache ShowContents data here to speed it up for children.
|
||||
// Am lazy though.
|
||||
UpdateEntity(entity);
|
||||
|
||||
foreach (var child in entity.Transform.Children)
|
||||
foreach (var child in EntityManager.GetComponent<TransformComponent>(entity).Children)
|
||||
{
|
||||
UpdateEntityRecursively(child.Owner);
|
||||
}
|
||||
}
|
||||
|
||||
private static void UpdateEntity(IEntity entity)
|
||||
private void UpdateEntity(EntityUid entity)
|
||||
{
|
||||
if (entity.TryGetComponent(out SpriteComponent? sprite))
|
||||
if (EntityManager.TryGetComponent(entity, out SpriteComponent? sprite))
|
||||
{
|
||||
sprite.ContainerOccluded = false;
|
||||
|
||||
@@ -216,7 +257,7 @@ namespace Robust.Client.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.TryGetComponent(out PointLightComponent? light))
|
||||
if (EntityManager.TryGetComponent(entity, out PointLightComponent? light))
|
||||
{
|
||||
light.ContainerOccluded = false;
|
||||
|
||||
|
||||