From bc360784ff90d4211999fa7dfcc52812d3de6b9b Mon Sep 17 00:00:00 2001 From: Boaz1111 <149967078+Boaz1111@users.noreply.github.com> Date: Wed, 5 Jun 2024 19:50:37 +0200 Subject: [PATCH 01/55] Cluster Update (#28627) done here --- Resources/Maps/cluster.yml | 981 +++++++++++++++---------------------- 1 file changed, 401 insertions(+), 580 deletions(-) diff --git a/Resources/Maps/cluster.yml b/Resources/Maps/cluster.yml index b8540c6f68d..a9f601114c6 100644 --- a/Resources/Maps/cluster.yml +++ b/Resources/Maps/cluster.yml @@ -38,6 +38,7 @@ tilemap: 113: FloorWhiteMono 1: FloorWhitePlastic 118: FloorWood + 3: FloorWoodLarge 120: Lattice 121: Plating entities: @@ -65,7 +66,7 @@ entities: version: 6 0,-1: ind: 0,-1 - tiles: WQAAAAACWQAAAAACWQAAAAABeQAAAAAAdgAAAAADdgAAAAADdgAAAAABeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAaAAAAAAAaAAAAAAAeQAAAAAAeQAAAAAAYAAAAAAAWQAAAAADWQAAAAABeQAAAAAAdgAAAAACdgAAAAABdgAAAAADeQAAAAAAeQAAAAAAaAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAaAAAAAAAeQAAAAAAeQAAAAAAWQAAAAAAWQAAAAABWQAAAAABeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAaAAAAAAAaAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAADYAAAAAAAWQAAAAADWQAAAAAAeQAAAAAAaAAAAAAAaAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAAAWQAAAAABWQAAAAACWQAAAAABeQAAAAAAWQAAAAAAWQAAAAACWQAAAAACYAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAaAAAAAAAaAAAAAAAeQAAAAAAeQAAAAAAWQAAAAACYAAAAAAAWQAAAAABWQAAAAADWQAAAAADWQAAAAADWQAAAAAAWQAAAAABeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAABWQAAAAAAWQAAAAACYAAAAAAAWQAAAAABWQAAAAABWQAAAAAAWQAAAAAAWQAAAAAAWQAAAAACWQAAAAABWQAAAAAAYAAAAAAAWQAAAAABWQAAAAABeQAAAAAAeQAAAAAAZAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAAAWQAAAAADWQAAAAAATAAAAAAAWQAAAAAAWQAAAAADWQAAAAACWQAAAAABTAAAAAAAWQAAAAABWQAAAAACWQAAAAADYAAAAAAAWQAAAAADeQAAAAAAWQAAAAAAWQAAAAACYAAAAAAAWQAAAAAAWQAAAAACWQAAAAAAWQAAAAAAWQAAAAAAWQAAAAABWQAAAAADWQAAAAAAWQAAAAABWQAAAAACWQAAAAAAWQAAAAAAZAAAAAAAWQAAAAACeQAAAAAAeQAAAAAAeQAAAAAAOgAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAABYAAAAAAAWQAAAAADWQAAAAAAWQAAAAACWQAAAAAAWQAAAAABZAAAAAAAWQAAAAABJAAAAAACJAAAAAAAJAAAAAADOgAAAAAAJAAAAAAAJAAAAAADeQAAAAAAWQAAAAAAWQAAAAACWQAAAAADWQAAAAAAWQAAAAADYAAAAAAAWQAAAAADeQAAAAAAZAAAAAABJAAAAAABJAAAAAADJAAAAAABOgAAAAAAJAAAAAABJAAAAAABeQAAAAAAYAAAAAAAWQAAAAADWQAAAAAAWQAAAAACWQAAAAACWQAAAAAAWQAAAAABeQAAAAAAWQAAAAABOgAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAWQAAAAABTAAAAAAAWQAAAAADeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAEQAAAAAAJAAAAAAAJAAAAAAAJAAAAAAAOgAAAAAAJAAAAAAAJAAAAAADeQAAAAAAWQAAAAABYAAAAAAAWQAAAAADeQAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAeQAAAAAAeQAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAeQAAAAAAWQAAAAACWQAAAAABWQAAAAACOgAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAHQAAAAADHQAAAAABeQAAAAAAeQAAAAAAeQAAAAAAOgAAAAAAOgAAAAAAeQAAAAAAeQAAAAAAWQAAAAADYAAAAAAAWQAAAAAAeQAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAHQAAAAABHQAAAAAC + tiles: WQAAAAACWQAAAAACWQAAAAABeQAAAAAAAwAAAAAAAwAAAAAAAwAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAaAAAAAAAaAAAAAAAeQAAAAAAeQAAAAAAYAAAAAAAWQAAAAADWQAAAAABeQAAAAAAAwAAAAAAAwAAAAAAAwAAAAAAeQAAAAAAeQAAAAAAaAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAaAAAAAAAeQAAAAAAeQAAAAAAWQAAAAAAWQAAAAABWQAAAAABeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAaAAAAAAAaAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAADYAAAAAAAWQAAAAADWQAAAAAAeQAAAAAAaAAAAAAAaAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAAAWQAAAAABWQAAAAACWQAAAAABeQAAAAAAWQAAAAAAWQAAAAACWQAAAAACYAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAaAAAAAAAaAAAAAAAeQAAAAAAeQAAAAAAWQAAAAACYAAAAAAAWQAAAAABWQAAAAADWQAAAAADWQAAAAADWQAAAAAAWQAAAAABeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAABWQAAAAAAWQAAAAACYAAAAAAAWQAAAAABWQAAAAABWQAAAAAAWQAAAAAAWQAAAAAAWQAAAAACWQAAAAABWQAAAAAAYAAAAAAAWQAAAAABWQAAAAABeQAAAAAAeQAAAAAAZAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAAAWQAAAAADWQAAAAAATAAAAAAAWQAAAAAAWQAAAAADWQAAAAACWQAAAAABTAAAAAAAWQAAAAABWQAAAAACWQAAAAADYAAAAAAAWQAAAAADeQAAAAAAWQAAAAAAWQAAAAACYAAAAAAAWQAAAAAAWQAAAAACWQAAAAAAWQAAAAAAWQAAAAAAWQAAAAABWQAAAAADWQAAAAAAWQAAAAABWQAAAAACWQAAAAAAWQAAAAAAZAAAAAAAWQAAAAACeQAAAAAAeQAAAAAAeQAAAAAAOgAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAABYAAAAAAAWQAAAAADWQAAAAAAWQAAAAACWQAAAAAAWQAAAAABZAAAAAAAWQAAAAABJAAAAAACJAAAAAAAJAAAAAADOgAAAAAAJAAAAAAAJAAAAAADeQAAAAAAWQAAAAAAWQAAAAACWQAAAAADWQAAAAAAWQAAAAADYAAAAAAAWQAAAAADeQAAAAAAZAAAAAABJAAAAAABJAAAAAADJAAAAAABOgAAAAAAJAAAAAABJAAAAAABeQAAAAAAYAAAAAAAWQAAAAADWQAAAAAAWQAAAAACWQAAAAACWQAAAAAAWQAAAAABeQAAAAAAWQAAAAABOgAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAWQAAAAABTAAAAAAAWQAAAAADeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAEQAAAAAAJAAAAAAAJAAAAAAAJAAAAAAAOgAAAAAAJAAAAAAAJAAAAAADeQAAAAAAWQAAAAABYAAAAAAAWQAAAAADeQAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAeQAAAAAAeQAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAeQAAAAAAWQAAAAACWQAAAAABWQAAAAACOgAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAHQAAAAADHQAAAAABeQAAAAAAeQAAAAAAeQAAAAAAOgAAAAAAOgAAAAAAeQAAAAAAeQAAAAAAWQAAAAADYAAAAAAAWQAAAAAAeQAAAAAAOgAAAAAAOgAAAAAAOgAAAAAAHQAAAAABHQAAAAAC version: 6 -1,1: ind: -1,1 @@ -85,7 +86,7 @@ entities: version: 6 0,-2: ind: 0,-2 - tiles: YAAAAAAAWQAAAAACWQAAAAAAeQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAABYAAAAAAAWQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAABWQAAAAAAYAAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAYAAAAAAAWQAAAAADWQAAAAADeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAACWQAAAAAAWQAAAAACeQAAAAAAWQAAAAAAWQAAAAACWQAAAAABeQAAAAAAWQAAAAABWQAAAAACWQAAAAACWQAAAAABWQAAAAABWQAAAAAAWQAAAAABWQAAAAAAWQAAAAAAWQAAAAAAWQAAAAAAeQAAAAAAWQAAAAAAWQAAAAABWQAAAAACZAAAAAADWQAAAAADWQAAAAAAWQAAAAAAWQAAAAABYAAAAAAAWQAAAAAAWQAAAAADWQAAAAADWQAAAAAAWQAAAAACYAAAAAAAeQAAAAAAWQAAAAACWQAAAAACWQAAAAADeQAAAAAAWQAAAAACWQAAAAAAYAAAAAAAWQAAAAABWQAAAAABWQAAAAAAYAAAAAAAWQAAAAABWQAAAAABWQAAAAACWQAAAAABeQAAAAAAeQAAAAAAZAAAAAADeQAAAAAAeQAAAAAAeQAAAAAAZAAAAAACZAAAAAACeQAAAAAAeQAAAAAAWQAAAAACYAAAAAAAWQAAAAAAWQAAAAABYAAAAAAAWQAAAAACWQAAAAACYAAAAAAAWQAAAAACWQAAAAADZAAAAAADWQAAAAAAYAAAAAAAWQAAAAABWQAAAAABeQAAAAAAWQAAAAAAWQAAAAADYAAAAAAAWQAAAAADWQAAAAABWQAAAAADWQAAAAAAWQAAAAACWQAAAAABYAAAAAAAeQAAAAAAWQAAAAADWQAAAAABYAAAAAAAWQAAAAAAZAAAAAABWQAAAAABYAAAAAAAYAAAAAAAWQAAAAACWQAAAAACWQAAAAAAYAAAAAAAWQAAAAACWQAAAAABWQAAAAADZAAAAAADWQAAAAAAWQAAAAADWQAAAAACWQAAAAAAZAAAAAADYAAAAAAAWQAAAAABWQAAAAAAWQAAAAADWQAAAAACWQAAAAACWQAAAAABYAAAAAAAWQAAAAADYAAAAAAAZAAAAAAAWQAAAAADYAAAAAAAWQAAAAADWQAAAAADeQAAAAAAWQAAAAADWQAAAAABWQAAAAABYAAAAAAAWQAAAAABWQAAAAABWQAAAAABWQAAAAABWQAAAAABYAAAAAAAeQAAAAAAWQAAAAABWQAAAAABWQAAAAADWQAAAAACeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAADWQAAAAAAWQAAAAADeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAABYAAAAAAAWQAAAAADYAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAaAAAAAAAWQAAAAABWQAAAAABYAAAAAAAeQAAAAAAdgAAAAAAdgAAAAADdgAAAAABdgAAAAAAWQAAAAAAWQAAAAABWQAAAAACWQAAAAADeQAAAAAAeQAAAAAAeQAAAAAAaAAAAAAAWQAAAAACWQAAAAAAWQAAAAABeQAAAAAAdgAAAAAAdgAAAAABdgAAAAACeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAaAAAAAAA + tiles: YAAAAAAAWQAAAAACWQAAAAAAeQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAABYAAAAAAAWQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAABWQAAAAAAYAAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAYAAAAAAAWQAAAAADWQAAAAADeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAACWQAAAAAAWQAAAAACeQAAAAAAWQAAAAAAWQAAAAACWQAAAAABeQAAAAAAWQAAAAABWQAAAAACWQAAAAACWQAAAAABWQAAAAABWQAAAAAAWQAAAAABWQAAAAAAWQAAAAAAWQAAAAAAWQAAAAAAeQAAAAAAWQAAAAAAWQAAAAABWQAAAAACZAAAAAADWQAAAAADWQAAAAAAWQAAAAAAWQAAAAABYAAAAAAAWQAAAAAAWQAAAAADWQAAAAADWQAAAAAAWQAAAAACYAAAAAAAeQAAAAAAWQAAAAACWQAAAAACWQAAAAADeQAAAAAAWQAAAAACWQAAAAAAYAAAAAAAWQAAAAABWQAAAAABWQAAAAAAYAAAAAAAWQAAAAABWQAAAAABWQAAAAACWQAAAAABeQAAAAAAeQAAAAAAZAAAAAADeQAAAAAAeQAAAAAAeQAAAAAAZAAAAAACZAAAAAACeQAAAAAAeQAAAAAAWQAAAAACYAAAAAAAWQAAAAAAWQAAAAABYAAAAAAAWQAAAAACWQAAAAACYAAAAAAAWQAAAAACWQAAAAADZAAAAAADWQAAAAAAYAAAAAAAWQAAAAABWQAAAAABeQAAAAAAWQAAAAAAWQAAAAADYAAAAAAAWQAAAAADWQAAAAABWQAAAAADWQAAAAAAWQAAAAACWQAAAAABYAAAAAAAeQAAAAAAWQAAAAADWQAAAAABYAAAAAAAWQAAAAAAZAAAAAABWQAAAAABYAAAAAAAYAAAAAAAWQAAAAACWQAAAAACWQAAAAAAYAAAAAAAWQAAAAACWQAAAAABWQAAAAADZAAAAAADWQAAAAAAWQAAAAADWQAAAAACWQAAAAAAZAAAAAADYAAAAAAAWQAAAAABWQAAAAAAWQAAAAADWQAAAAACWQAAAAACWQAAAAABYAAAAAAAWQAAAAADYAAAAAAAZAAAAAAAWQAAAAADYAAAAAAAWQAAAAADWQAAAAADeQAAAAAAWQAAAAADWQAAAAABWQAAAAABYAAAAAAAWQAAAAABWQAAAAABWQAAAAABWQAAAAABWQAAAAABYAAAAAAAeQAAAAAAWQAAAAABWQAAAAABWQAAAAADWQAAAAACeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAADWQAAAAAAWQAAAAADeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAABYAAAAAAAWQAAAAADYAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAaAAAAAAAWQAAAAABWQAAAAABYAAAAAAAeQAAAAAAAwAAAAAAAwAAAAAAAwAAAAAAdgAAAAAAWQAAAAAAWQAAAAABWQAAAAACWQAAAAADeQAAAAAAeQAAAAAAeQAAAAAAaAAAAAAAWQAAAAACWQAAAAAAWQAAAAABeQAAAAAAAwAAAAAAAwAAAAAAAwAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAaAAAAAAA version: 6 -2,1: ind: -2,1 @@ -7651,11 +7652,6 @@ entities: parent: 1 - proto: Bed entities: - - uid: 1805 - components: - - type: Transform - pos: 25.5,12.5 - parent: 1 - uid: 1806 components: - type: Transform @@ -7676,6 +7672,11 @@ entities: - type: Transform pos: -20.5,-3.5 parent: 1 + - uid: 1852 + components: + - type: Transform + pos: 25.5,12.5 + parent: 1 - uid: 3482 components: - type: Transform @@ -7711,15 +7712,15 @@ entities: - type: Transform pos: 11.5,5.5 parent: 1 - - uid: 5663 + - uid: 5671 components: - type: Transform - pos: 16.5,-15.5 + pos: 20.5,-15.5 parent: 1 - - uid: 7442 + - uid: 7446 components: - type: Transform - pos: 4.5,-17.5 + pos: 6.5,-14.5 parent: 1 - uid: 7714 components: @@ -7765,11 +7766,10 @@ entities: parent: 1 - proto: BedsheetCE entities: - - uid: 5662 + - uid: 4918 components: - type: Transform - rot: 3.141592653589793 rad - pos: 16.5,-15.5 + pos: 20.5,-15.5 parent: 1 - proto: BedsheetClown entities: @@ -7829,7 +7829,7 @@ entities: parent: 1 - proto: BedsheetHOS entities: - - uid: 5373 + - uid: 1863 components: - type: Transform pos: 25.5,12.5 @@ -7877,11 +7877,10 @@ entities: parent: 1 - proto: BedsheetQM entities: - - uid: 7441 + - uid: 5395 components: - type: Transform - rot: -1.5707963267948966 rad - pos: 4.5,-17.5 + pos: 6.5,-14.5 parent: 1 - proto: BedsheetRD entities: @@ -8242,6 +8241,11 @@ entities: parent: 1 - proto: BoxFolderBase entities: + - uid: 1805 + components: + - type: Transform + pos: -22.477488,-1.5542104 + parent: 1 - uid: 1857 components: - type: Transform @@ -8287,6 +8291,11 @@ entities: rot: 3.141592653589793 rad pos: -8.510255,48.552643 parent: 1 + - uid: 5634 + components: + - type: Transform + pos: -22.289988,-1.3667104 + parent: 1 - uid: 6055 components: - type: Transform @@ -8348,16 +8357,6 @@ entities: parent: 1 - proto: BoxFolderGrey entities: - - uid: 1883 - components: - - type: Transform - pos: -21.598257,-1.4382241 - parent: 1 - - uid: 1884 - components: - - type: Transform - pos: -21.473257,-1.3444741 - parent: 1 - uid: 6069 components: - type: Transform @@ -8385,11 +8384,6 @@ entities: - type: Transform pos: 28.678442,8.532815 parent: 1 - - uid: 5390 - components: - - type: Transform - pos: 27.618711,13.570517 - parent: 1 - uid: 5397 components: - type: Transform @@ -8407,18 +8401,28 @@ entities: parent: 1 - proto: BoxFolderWhite entities: - - uid: 1879 + - uid: 5377 components: - type: Transform - pos: -19.351341,14.63665 + pos: -19.312119,13.611187 parent: 1 - - uid: 1880 + - uid: 5655 components: - type: Transform - pos: -19.445091,14.558525 + pos: -19.593369,13.439312 parent: 1 - proto: BoxFolderYellow entities: + - uid: 1879 + components: + - type: Transform + pos: 4.418282,-17.420078 + parent: 1 + - uid: 1881 + components: + - type: Transform + pos: 4.277657,-17.638828 + parent: 1 - uid: 5095 components: - type: Transform @@ -8427,7 +8431,7 @@ entities: - uid: 5677 components: - type: Transform - pos: 18.605122,-14.452038 + pos: 17.707003,-15.576565 parent: 1 - uid: 6787 components: @@ -8469,16 +8473,6 @@ entities: - type: Transform pos: 11.422744,-18.443436 parent: 1 - - uid: 7448 - components: - - type: Transform - pos: 5.6525464,-15.315514 - parent: 1 - - uid: 7449 - components: - - type: Transform - pos: 5.4181714,-15.456139 - parent: 1 - uid: 9600 components: - type: Transform @@ -22162,7 +22156,7 @@ entities: - uid: 4981 components: - type: Transform - pos: 4.562398,31.612326 + pos: 5.6753416,30.52142 parent: 1 - proto: CarbonDioxideCanister entities: @@ -22238,30 +22232,6 @@ entities: rot: 3.141592653589793 rad pos: 26.5,13.5 parent: 1 - - uid: 5625 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 27.5,14.5 - parent: 1 - - uid: 5626 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 27.5,13.5 - parent: 1 - - uid: 5627 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 28.5,14.5 - parent: 1 - - uid: 5628 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 28.5,13.5 - parent: 1 - uid: 5629 components: - type: Transform @@ -22286,18 +22256,6 @@ entities: rot: 3.141592653589793 rad pos: 25.5,14.5 parent: 1 - - uid: 5633 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 27.5,12.5 - parent: 1 - - uid: 5634 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 28.5,12.5 - parent: 1 - uid: 5635 components: - type: Transform @@ -22404,6 +22362,11 @@ entities: parent: 1 - proto: CarpetBlue entities: + - uid: 4091 + components: + - type: Transform + pos: -20.5,15.5 + parent: 1 - uid: 5645 components: - type: Transform @@ -22452,35 +22415,10 @@ entities: rot: 3.141592653589793 rad pos: -19.5,15.5 parent: 1 - - uid: 5653 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -21.5,-2.5 - parent: 1 - - uid: 5654 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -21.5,-2.5 - parent: 1 - - uid: 5655 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -21.5,-3.5 - parent: 1 - - uid: 5656 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -20.5,-2.5 - parent: 1 - - uid: 5657 + - uid: 7444 components: - type: Transform - rot: 3.141592653589793 rad - pos: -20.5,-3.5 + pos: -20.5,16.5 parent: 1 - proto: CarpetGreen entities: @@ -22621,52 +22559,93 @@ entities: parent: 1 - proto: CarpetOrange entities: - - uid: 5658 + - uid: 1845 components: - type: Transform - rot: 3.141592653589793 rad - pos: 16.5,-14.5 + pos: 6.5,-14.5 parent: 1 - - uid: 5659 + - uid: 5415 components: - type: Transform - rot: 3.141592653589793 rad - pos: 16.5,-15.5 + pos: 19.5,-15.5 + parent: 1 + - uid: 5626 + components: + - type: Transform + pos: 4.5,-14.5 + parent: 1 + - uid: 5627 + components: + - type: Transform + pos: 5.5,-14.5 + parent: 1 + - uid: 5628 + components: + - type: Transform + pos: 5.5,-15.5 + parent: 1 + - uid: 5653 + components: + - type: Transform + pos: 6.5,-15.5 parent: 1 - uid: 5660 components: - type: Transform - rot: 3.141592653589793 rad - pos: 17.5,-14.5 + pos: 20.5,-14.5 parent: 1 - uid: 5661 components: - type: Transform - rot: 3.141592653589793 rad - pos: 17.5,-15.5 + pos: 20.5,-15.5 parent: 1 - - uid: 12419 + - uid: 5662 components: - type: Transform - pos: 4.5,-17.5 + pos: 20.5,-13.5 parent: 1 - - uid: 12420 + - uid: 5672 components: - type: Transform - pos: 4.5,-16.5 + pos: 19.5,-14.5 parent: 1 - - uid: 12421 + - uid: 5673 components: - type: Transform - pos: 5.5,-17.5 + pos: 19.5,-13.5 parent: 1 - - uid: 12422 + - uid: 7447 components: - type: Transform - pos: 5.5,-16.5 + pos: 4.5,-15.5 parent: 1 - proto: CarpetPurple entities: + - uid: 1870 + components: + - type: Transform + pos: -22.5,-2.5 + parent: 1 + - uid: 1871 + components: + - type: Transform + pos: -20.5,-2.5 + parent: 1 + - uid: 1873 + components: + - type: Transform + pos: -21.5,-3.5 + parent: 1 + - uid: 1874 + components: + - type: Transform + pos: -20.5,-3.5 + parent: 1 + - uid: 1877 + components: + - type: Transform + pos: -21.5,-2.5 + parent: 1 - uid: 5018 components: - type: Transform @@ -22682,6 +22661,11 @@ entities: - type: Transform pos: 5.5,10.5 parent: 1 + - uid: 5369 + components: + - type: Transform + pos: -22.5,-3.5 + parent: 1 - proto: CarpetSBlue entities: - uid: 5639 @@ -26173,17 +26157,17 @@ entities: - type: Transform pos: 14.5,13.5 parent: 1 - - uid: 1710 + - uid: 1875 components: - type: Transform rot: 3.141592653589793 rad - pos: 5.5,-16.5 + pos: -21.5,-2.5 parent: 1 - - uid: 1875 + - uid: 1883 components: - type: Transform - rot: 3.141592653589793 rad - pos: -21.5,-2.5 + rot: -1.5707963267948966 rad + pos: 5.512032,-16.451328 parent: 1 - uid: 2868 components: @@ -26342,11 +26326,10 @@ entities: rot: 3.141592653589793 rad pos: 28.5,17.5 parent: 1 - - uid: 5375 + - uid: 5393 components: - type: Transform - rot: -1.5707963267948966 rad - pos: 28.5,13.5 + pos: 28.500902,13.478384 parent: 1 - uid: 5574 components: @@ -26360,12 +26343,6 @@ entities: rot: 3.141592653589793 rad pos: -36.5,-3.5 parent: 1 - - uid: 5673 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: 17.5,-14.5 - parent: 1 - uid: 5674 components: - type: Transform @@ -26400,6 +26377,12 @@ entities: - type: Transform pos: 12.5,-26.5 parent: 1 + - uid: 7452 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 17.488253,-14.435939 + parent: 1 - uid: 8013 components: - type: Transform @@ -26449,11 +26432,6 @@ entities: parent: 1 - proto: ChairOfficeLight entities: - - uid: 1874 - components: - - type: Transform - pos: -19.5,15.5 - parent: 1 - uid: 5608 components: - type: Transform @@ -26472,6 +26450,12 @@ entities: rot: 3.141592653589793 rad pos: -8.5,6.5 parent: 1 + - uid: 5633 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -19.499619,14.564312 + parent: 1 - uid: 5921 components: - type: Transform @@ -26636,18 +26620,6 @@ entities: rot: 1.5707963267948966 rad pos: -22.5,-29.5 parent: 1 -- proto: chem_master - entities: - - uid: 5604 - components: - - type: Transform - pos: -8.5,14.5 - parent: 1 - - uid: 5605 - components: - - type: Transform - pos: -11.5,16.5 - parent: 1 - proto: ChemDispenser entities: - uid: 5606 @@ -26674,6 +26646,18 @@ entities: - type: Transform pos: -11.5,13.5 parent: 1 +- proto: ChemMaster + entities: + - uid: 5604 + components: + - type: Transform + pos: -8.5,14.5 + parent: 1 + - uid: 5605 + components: + - type: Transform + pos: -11.5,16.5 + parent: 1 - proto: ChessBoard entities: - uid: 5058 @@ -27514,6 +27498,13 @@ entities: - type: Transform pos: -13.503023,28.53958 parent: 1 +- proto: ClothingHeadHatBeretCmo + entities: + - uid: 7450 + components: + - type: Transform + pos: -20.687119,13.736187 + parent: 1 - proto: ClothingHeadHatFedoraBrown entities: - uid: 12535 @@ -27630,21 +27621,7 @@ entities: - uid: 6397 components: - type: Transform - pos: 4.585783,31.487268 - parent: 1 -- proto: ClothingNeckMantleCE - entities: - - uid: 5675 - components: - - type: Transform - pos: 18.495747,-13.358288 - parent: 1 -- proto: ClothingNeckMantleCMO - entities: - - uid: 1869 - components: - - type: Transform - pos: -20.496048,14.567978 + pos: 5.4722166,31.005795 parent: 1 - proto: ClothingNeckMantleHOP entities: @@ -27655,13 +27632,6 @@ entities: - type: Physics canCollide: False - type: InsideEntityStorage -- proto: ClothingNeckMantleRD - entities: - - uid: 1877 - components: - - type: Transform - pos: -22.452333,-1.4018333 - parent: 1 - proto: ClothingNeckScarfStripedBlue entities: - uid: 1899 @@ -27779,15 +27749,6 @@ entities: - type: Physics canCollide: False - type: InsideEntityStorage -- proto: ClothingOuterWinterCE - entities: - - uid: 5670 - components: - - type: Transform - parent: 5669 - - type: Physics - canCollide: False - - type: InsideEntityStorage - proto: ClothingOuterWinterCMO entities: - uid: 1868 @@ -27806,33 +27767,6 @@ entities: - type: Physics canCollide: False - type: InsideEntityStorage -- proto: ClothingOuterWinterHoS - entities: - - uid: 12478 - components: - - type: Transform - parent: 5374 - - type: Physics - canCollide: False - - type: InsideEntityStorage -- proto: ClothingOuterWinterQM - entities: - - uid: 7444 - components: - - type: Transform - parent: 7443 - - type: Physics - canCollide: False - - type: InsideEntityStorage -- proto: ClothingOuterWinterRD - entities: - - uid: 12418 - components: - - type: Transform - parent: 1845 - - type: Physics - canCollide: False - - type: InsideEntityStorage - proto: ClothingShoesBootsCombat entities: - uid: 8275 @@ -27914,16 +27848,17 @@ entities: parent: 1 - proto: ComfyChair entities: - - uid: 1711 + - uid: 794 components: - type: Transform - pos: 5.5,-14.5 + rot: 3.141592653589793 rad + pos: 26.5,12.5 parent: 1 - - uid: 1873 + - uid: 1848 components: - type: Transform - rot: 3.141592653589793 rad - pos: -19.5,13.5 + rot: -1.5707963267948966 rad + pos: 6.5,-15.5 parent: 1 - uid: 1876 components: @@ -27968,12 +27903,6 @@ entities: rot: -1.5707963267948966 rad pos: 4.5,25.5 parent: 1 - - uid: 5377 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: 26.5,13.5 - parent: 1 - uid: 5573 components: - type: Transform @@ -27986,6 +27915,11 @@ entities: rot: 3.141592653589793 rad pos: 2.5,5.5 parent: 1 + - uid: 7454 + components: + - type: Transform + pos: 19.5,-13.5 + parent: 1 - uid: 7712 components: - type: Transform @@ -28006,11 +27940,16 @@ entities: - ArtifactAnalyzerSender: ArtifactAnalyzerReceiver - proto: ComputerCargoBounty entities: - - uid: 7247 + - uid: 1880 components: - type: Transform - rot: -1.5707963267948966 rad - pos: 16.5,-23.5 + rot: 1.5707963267948966 rad + pos: 4.5,-16.5 + parent: 1 + - uid: 5669 + components: + - type: Transform + pos: 8.5,-19.5 parent: 1 - proto: ComputerCargoOrders entities: @@ -28020,18 +27959,11 @@ entities: rot: 3.141592653589793 rad pos: 8.5,-22.5 parent: 1 - - uid: 7395 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: 4.5,-14.5 - parent: 1 -- proto: ComputerCargoShuttle - entities: - - uid: 4918 + - uid: 5366 components: - type: Transform - pos: 8.5,-19.5 + rot: 3.141592653589793 rad + pos: 5.5,-17.5 parent: 1 - proto: ComputerComms entities: @@ -28048,6 +27980,12 @@ entities: parent: 1 - proto: ComputerCrewMonitoring entities: + - uid: 1844 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -20.5,14.5 + parent: 1 - uid: 1888 components: - type: Transform @@ -28066,10 +28004,11 @@ entities: - type: Transform pos: 14.5,15.5 parent: 1 - - uid: 5366 + - uid: 1869 components: - type: Transform - pos: 25.5,14.5 + rot: 3.141592653589793 rad + pos: 28.5,12.5 parent: 1 - uid: 5370 components: @@ -28114,14 +28053,6 @@ entities: rot: -1.5707963267948966 rad pos: 1.5,19.5 parent: 1 -- proto: ComputerMedicalRecords - entities: - - uid: 1871 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -20.5,13.5 - parent: 1 - proto: ComputerPowerMonitoring entities: - uid: 4072 @@ -28129,10 +28060,11 @@ entities: - type: Transform pos: -5.5,31.5 parent: 1 - - uid: 5415 + - uid: 5665 components: - type: Transform - pos: 19.5,-13.5 + rot: 1.5707963267948966 rad + pos: 16.5,-14.5 parent: 1 - uid: 5668 components: @@ -28156,11 +28088,11 @@ entities: rot: 1.5707963267948966 rad pos: -10.5,-3.5 parent: 1 - - uid: 5365 + - uid: 5385 components: - type: Transform - rot: 1.5707963267948966 rad - pos: -22.5,-0.5 + rot: 3.141592653589793 rad + pos: -21.5,-1.5 parent: 1 - proto: ComputerRoboticsControl entities: @@ -28186,6 +28118,14 @@ entities: rot: 3.141592653589793 rad pos: 12.5,-27.5 parent: 1 +- proto: ComputerShuttleSalvage + entities: + - uid: 5666 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 16.5,-23.5 + parent: 1 - proto: ComputerSolarControl entities: - uid: 2557 @@ -28244,6 +28184,12 @@ entities: rot: 3.141592653589793 rad pos: 14.5,12.5 parent: 1 + - uid: 1884 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: 27.5,13.5 + parent: 1 - uid: 3794 components: - type: Transform @@ -28266,11 +28212,6 @@ entities: rot: 1.5707963267948966 rad pos: 25.5,6.5 parent: 1 - - uid: 5369 - components: - - type: Transform - pos: 26.5,14.5 - parent: 1 - proto: ComputerTechnologyDiskTerminal entities: - uid: 3822 @@ -28822,6 +28763,39 @@ entities: - type: Transform pos: -41.5,-23.5 parent: 1 +- proto: CurtainsBlueOpen + entities: + - uid: 5391 + components: + - type: Transform + pos: -18.5,16.5 + parent: 1 +- proto: CurtainsOrangeOpen + entities: + - uid: 4933 + components: + - type: Transform + pos: 20.5,-15.5 + parent: 1 + - uid: 5625 + components: + - type: Transform + pos: 6.5,-14.5 + parent: 1 +- proto: CurtainsPurpleOpen + entities: + - uid: 5390 + components: + - type: Transform + pos: -20.5,-3.5 + parent: 1 +- proto: CurtainsRedOpen + entities: + - uid: 5394 + components: + - type: Transform + pos: 25.5,12.5 + parent: 1 - proto: d20Dice entities: - uid: 5591 @@ -32502,6 +32476,48 @@ entities: - type: Transform pos: 5.5,29.5 parent: 1 +- proto: DresserCaptainFilled + entities: + - uid: 7445 + components: + - type: Transform + pos: 4.5,31.5 + parent: 1 +- proto: DresserChiefEngineerFilled + entities: + - uid: 5659 + components: + - type: Transform + pos: 20.5,-14.5 + parent: 1 +- proto: DresserChiefMedicalOfficerFilled + entities: + - uid: 5657 + components: + - type: Transform + pos: -19.5,16.5 + parent: 1 +- proto: DresserHeadOfSecurityFilled + entities: + - uid: 6044 + components: + - type: Transform + pos: 25.5,13.5 + parent: 1 +- proto: DresserQuarterMasterFilled + entities: + - uid: 5373 + components: + - type: Transform + pos: 5.5,-14.5 + parent: 1 +- proto: DresserResearchDirectorFilled + entities: + - uid: 7442 + components: + - type: Transform + pos: -21.5,-3.5 + parent: 1 - proto: Drill entities: - uid: 9639 @@ -38592,10 +38608,14 @@ entities: - uid: 8794 components: - type: Transform + anchored: False pos: -14.5,-45.5 parent: 1 - type: AtmosPipeColor color: '#990000FF' + - type: Physics + canCollide: True + bodyType: Dynamic - uid: 10091 components: - type: Transform @@ -38830,11 +38850,15 @@ entities: - uid: 10130 components: - type: Transform + anchored: False rot: 1.5707963267948966 rad pos: 21.5,-11.5 parent: 1 - type: AtmosPipeColor color: '#990000FF' + - type: Physics + canCollide: True + bodyType: Dynamic - uid: 10131 components: - type: Transform @@ -43075,13 +43099,6 @@ entities: parent: 1 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 10974 - components: - - type: Transform - pos: -4.5,8.5 - parent: 1 - - type: AtmosPipeColor - color: '#0055CCFF' - uid: 10975 components: - type: Transform @@ -44040,11 +44057,15 @@ entities: - uid: 11152 components: - type: Transform + anchored: False rot: 3.141592653589793 rad pos: -37.5,0.5 parent: 1 - type: AtmosPipeColor color: '#0055CCFF' + - type: Physics + canCollide: True + bodyType: Dynamic - uid: 11153 components: - type: Transform @@ -47036,11 +47057,15 @@ entities: - uid: 12253 components: - type: Transform + anchored: False rot: -1.5707963267948966 rad pos: -4.5,56.5 parent: 1 - type: AtmosPipeColor color: '#0055CCFF' + - type: Physics + canCollide: True + bodyType: Dynamic - uid: 12254 components: - type: Transform @@ -54986,27 +55011,11 @@ entities: parent: 1 - proto: HospitalCurtainsOpen entities: - - uid: 794 - components: - - type: Transform - pos: 25.5,12.5 - parent: 1 - uid: 1804 components: - type: Transform pos: 28.5,5.5 parent: 1 - - uid: 1843 - components: - - type: Transform - pos: -20.5,-3.5 - parent: 1 - - uid: 1852 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -18.5,16.5 - parent: 1 - uid: 5371 components: - type: Transform @@ -55023,18 +55032,6 @@ entities: rot: -1.5707963267948966 rad pos: 27.5,16.5 parent: 1 - - uid: 5672 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: 16.5,-15.5 - parent: 1 - - uid: 7440 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: 4.5,-17.5 - parent: 1 - uid: 7718 components: - type: Transform @@ -55745,40 +55742,11 @@ entities: parent: 1 - proto: LockerChiefEngineerFilled entities: - - uid: 5669 + - uid: 5658 components: - type: Transform - pos: 20.5,-15.5 + pos: 20.5,-13.5 parent: 1 - - type: EntityStorage - air: - volume: 200 - immutable: False - temperature: 93.465614 - moles: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - type: ContainerContainer - containers: - entity_storage: !type:Container - showEnts: False - occludes: True - ents: - - 5670 - paper_label: !type:ContainerSlot - showEnts: False - occludes: True - ent: null - proto: LockerChiefMedicalOfficerFilled entities: - uid: 1867 @@ -55986,40 +55954,11 @@ entities: ent: null - proto: LockerHeadOfSecurityFilled entities: - - uid: 5374 + - uid: 7441 components: - type: Transform - pos: 29.5,12.5 + pos: 25.5,14.5 parent: 1 - - type: EntityStorage - air: - volume: 200 - immutable: False - temperature: 293.1496 - moles: - - 1.7459903 - - 6.568249 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - type: ContainerContainer - containers: - entity_storage: !type:Container - showEnts: False - occludes: True - ents: - - 12478 - paper_label: !type:ContainerSlot - showEnts: False - occludes: True - ent: null - proto: LockerMedicalFilled entities: - uid: 1908 @@ -56056,76 +55995,18 @@ entities: parent: 1 - proto: LockerQuarterMasterFilled entities: - - uid: 7443 + - uid: 5656 components: - type: Transform - pos: 4.5,-16.5 + pos: 4.5,-14.5 parent: 1 - - type: EntityStorage - air: - volume: 200 - immutable: False - temperature: 75.31249 - moles: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - type: ContainerContainer - containers: - entity_storage: !type:Container - showEnts: False - occludes: True - ents: - - 7444 - paper_label: !type:ContainerSlot - showEnts: False - occludes: True - ent: null - proto: LockerResearchDirectorFilled entities: - - uid: 1845 + - uid: 7395 components: - type: Transform - pos: -21.5,-3.5 + pos: -22.5,-2.5 parent: 1 - - type: EntityStorage - air: - volume: 200 - immutable: False - temperature: 293.1496 - moles: - - 1.7459903 - - 6.568249 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - type: ContainerContainer - containers: - entity_storage: !type:Container - showEnts: False - occludes: True - ents: - - 12418 - paper_label: !type:ContainerSlot - showEnts: False - occludes: True - ent: null - proto: LockerSalvageSpecialistFilled entities: - uid: 3594 @@ -56329,15 +56210,15 @@ entities: parent: 1 - proto: MagazinePistolSubMachineGunTopMounted entities: - - uid: 5386 + - uid: 1865 components: - type: Transform - pos: 27.431211,14.508017 + pos: 27.625902,12.337759 parent: 1 - - uid: 5387 + - uid: 5365 components: - type: Transform - pos: 27.431211,14.367392 + pos: 27.579027,12.494009 parent: 1 - proto: MagazineRifle entities: @@ -57473,12 +57354,6 @@ entities: - type: Transform pos: 5.5,-20.5 parent: 1 - - uid: 7447 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 4.5,-15.5 - parent: 1 - uid: 7782 components: - type: Transform @@ -57540,6 +57415,23 @@ entities: - type: Transform pos: 4.593648,27.643576 parent: 1 +- proto: PaperCargoInvoice + entities: + - uid: 798 + components: + - type: Transform + pos: 4.715157,-17.670078 + parent: 1 + - uid: 1711 + components: + - type: Transform + pos: 4.777657,-17.498203 + parent: 1 + - uid: 5392 + components: + - type: Transform + pos: 4.777657,-17.310703 + parent: 1 - proto: PaperOffice entities: - uid: 3999 @@ -57682,26 +57574,6 @@ entities: - type: Transform pos: -4.5472007,19.595882 parent: 1 - - uid: 5391 - components: - - type: Transform - pos: 27.337461,13.773642 - parent: 1 - - uid: 5392 - components: - - type: Transform - pos: 27.368711,13.758017 - parent: 1 - - uid: 5393 - components: - - type: Transform - pos: 27.415586,13.711142 - parent: 1 - - uid: 5394 - components: - - type: Transform - pos: 27.478086,13.679892 - parent: 1 - uid: 5398 components: - type: Transform @@ -57725,22 +57597,12 @@ entities: - uid: 5678 components: - type: Transform - pos: 18.339497,-14.389538 - parent: 1 - - uid: 5679 - components: - - type: Transform - pos: 18.339497,-14.295788 - parent: 1 - - uid: 5680 - components: - - type: Transform - pos: 18.339497,-14.186413 + pos: 17.441378,-15.404689 parent: 1 - uid: 5681 components: - type: Transform - pos: 18.355122,-14.061413 + pos: 17.332003,-15.56094 parent: 1 - uid: 5875 components: @@ -57872,25 +57734,10 @@ entities: - type: Transform pos: 11.453994,-18.162186 parent: 1 - - uid: 7450 - components: - - type: Transform - pos: 5.1056714,-15.299889 - parent: 1 - - uid: 7451 - components: - - type: Transform - pos: 5.1056714,-15.299889 - parent: 1 - - uid: 7452 - components: - - type: Transform - pos: 5.1056714,-15.299889 - parent: 1 - uid: 7453 components: - type: Transform - pos: 5.1056714,-15.299889 + pos: 17.566378,-15.264064 parent: 1 - uid: 8247 components: @@ -58038,15 +57885,10 @@ entities: parent: 1 - proto: Pen entities: - - uid: 1881 - components: - - type: Transform - pos: -19.882591,14.621025 - parent: 1 - - uid: 1882 + - uid: 1780 components: - type: Transform - pos: -21.958109,-1.4018333 + pos: -22.696238,-1.2729604 parent: 1 - uid: 3995 components: @@ -58092,11 +57934,10 @@ entities: rot: -1.5707963267948966 rad pos: 25.773567,10.670956 parent: 1 - - uid: 5395 + - uid: 5386 components: - type: Transform - rot: -1.5707963267948966 rad - pos: 27.587461,13.804892 + pos: -19.937119,13.673687 parent: 1 - uid: 5402 components: @@ -58119,11 +57960,10 @@ entities: - type: Transform pos: -39.229885,-5.2659664 parent: 1 - - uid: 5682 + - uid: 5675 components: - type: Transform - rot: -1.5707963267948966 rad - pos: 18.651997,-14.061413 + pos: 17.097628,-15.217189 parent: 1 - uid: 5879 components: @@ -58151,10 +57991,10 @@ entities: - type: Transform pos: 5.313369,-21.14656 parent: 1 - - uid: 7454 + - uid: 7451 components: - type: Transform - pos: 5.6369214,-15.503014 + pos: 4.230782,-17.216953 parent: 1 - uid: 9046 components: @@ -62393,32 +62233,32 @@ entities: parent: 1 - proto: RCD entities: - - uid: 7135 + - uid: 5679 components: - type: Transform - pos: 31.574986,-16.418343 + pos: 16.410128,-15.420314 parent: 1 - - uid: 12468 + - uid: 7135 components: - type: Transform - pos: 18.51267,-13.338883 + pos: 31.574986,-16.418343 parent: 1 - proto: RCDAmmo entities: - - uid: 7136 + - uid: 5663 components: - type: Transform - pos: 31.27811,-16.605843 + pos: 16.878878,-15.467189 parent: 1 - - uid: 12469 + - uid: 5680 components: - type: Transform - pos: 18.278296,-13.526383 + pos: 17.050753,-15.467189 parent: 1 - - uid: 12470 + - uid: 7136 components: - type: Transform - pos: 18.434546,-13.526383 + pos: 31.27811,-16.605843 parent: 1 - proto: ReagentContainerFlour entities: @@ -64453,10 +64293,10 @@ entities: parent: 1 - proto: ResearchAndDevelopmentServer entities: - - uid: 1848 + - uid: 4973 components: - type: Transform - pos: -22.5,-3.5 + pos: -22.5,-0.5 parent: 1 - proto: RightArmBorg entities: @@ -65035,7 +64875,7 @@ entities: parent: 1 - type: DeviceLinkSink links: - - 5671 + - 5682 - uid: 5684 components: - type: Transform @@ -65043,7 +64883,7 @@ entities: parent: 1 - type: DeviceLinkSink links: - - 5671 + - 5682 - uid: 5685 components: - type: Transform @@ -65051,7 +64891,7 @@ entities: parent: 1 - type: DeviceLinkSink links: - - 5671 + - 5682 - uid: 5686 components: - type: Transform @@ -65059,15 +64899,12 @@ entities: parent: 1 - type: DeviceLinkSink links: - - 5671 + - 5682 - uid: 5687 components: - type: Transform pos: 21.5,-15.5 parent: 1 - - type: DeviceLinkSink - links: - - 5671 - uid: 5887 components: - type: Transform @@ -65455,16 +65292,14 @@ entities: - Pressed: Toggle 1866: - Pressed: Toggle - - uid: 5671 + - uid: 5682 components: - type: Transform - rot: -1.5707963267948966 rad - pos: 21.5,-14.5 + rot: 3.141592653589793 rad + pos: 19.5,-16.5 parent: 1 - type: DeviceLinkSource linkedPorts: - 5687: - - Pressed: Toggle 5685: - Pressed: Toggle 5684: @@ -66405,7 +66240,7 @@ entities: - type: Transform pos: -43.500492,24.479343 parent: 1 -- proto: soda_dispenser +- proto: SodaDispenser entities: - uid: 5954 components: @@ -66949,10 +66784,11 @@ entities: parent: 1 - proto: SpawnMobShiva entities: - - uid: 8256 + - uid: 7440 components: - type: Transform - pos: 25.5,13.5 + rot: 3.141592653589793 rad + pos: 26.5,12.5 parent: 1 - proto: SpawnMobSmile entities: @@ -67055,10 +66891,10 @@ entities: parent: 1 - proto: SpawnPointChiefMedicalOfficer entities: - - uid: 1870 + - uid: 1843 components: - type: Transform - pos: -19.5,13.5 + pos: -19.5,14.5 parent: 1 - proto: SpawnPointClown entities: @@ -67083,10 +66919,10 @@ entities: parent: 1 - proto: SpawnPointHeadOfSecurity entities: - - uid: 6044 + - uid: 7448 components: - type: Transform - pos: 26.5,13.5 + pos: 28.5,13.5 parent: 1 - proto: SpawnPointJanitor entities: @@ -67195,10 +67031,10 @@ entities: parent: 1 - proto: SpawnPointQuartermaster entities: - - uid: 7477 + - uid: 5375 components: - type: Transform - pos: 5.5,-14.5 + pos: 6.5,-15.5 parent: 1 - proto: SpawnPointResearchAssistant entities: @@ -67671,17 +67507,17 @@ entities: parent: 1 - proto: SuitStorageCE entities: - - uid: 4933 + - uid: 7477 components: - type: Transform - pos: 20.5,-13.5 + pos: 18.5,-15.5 parent: 1 - proto: SuitStorageCMO entities: - - uid: 1865 + - uid: 5374 components: - type: Transform - pos: -20.5,15.5 + pos: -18.5,13.5 parent: 1 - proto: SuitStorageEngi entities: @@ -67736,17 +67572,17 @@ entities: parent: 1 - proto: SuitStorageHOS entities: - - uid: 4973 + - uid: 1864 components: - type: Transform - pos: 29.5,14.5 + pos: 29.5,12.5 parent: 1 - proto: SuitStorageRD entities: - - uid: 4929 + - uid: 5654 components: - type: Transform - pos: -22.5,-2.5 + pos: -22.5,-3.5 parent: 1 - proto: SuitStorageSalv entities: @@ -69595,11 +69431,6 @@ entities: rot: 1.5707963267948966 rad pos: -1.5,7.5 parent: 1 - - uid: 798 - components: - - type: Transform - pos: 27.5,13.5 - parent: 1 - uid: 1256 components: - type: Transform @@ -69624,11 +69455,6 @@ entities: rot: 1.5707963267948966 rad pos: -37.5,-4.5 parent: 1 - - uid: 1780 - components: - - type: Transform - pos: 27.5,14.5 - parent: 1 - uid: 1802 components: - type: Transform @@ -69639,22 +69465,11 @@ entities: - type: Transform pos: 28.5,16.5 parent: 1 - - uid: 1844 - components: - - type: Transform - pos: -21.5,-1.5 - parent: 1 - - uid: 1863 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -20.5,14.5 - parent: 1 - - uid: 1864 + - uid: 1882 components: - type: Transform - rot: -1.5707963267948966 rad - pos: -19.5,14.5 + rot: 3.141592653589793 rad + pos: 4.5,-17.5 parent: 1 - uid: 2782 components: @@ -69749,12 +69564,6 @@ entities: rot: 3.141592653589793 rad pos: -9.5,28.5 parent: 1 - - uid: 4091 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: 4.5,31.5 - parent: 1 - uid: 4092 components: - type: Transform @@ -69842,6 +69651,12 @@ entities: rot: 3.141592653589793 rad pos: 46.5,31.5 parent: 1 + - uid: 4929 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -19.5,13.5 + parent: 1 - uid: 4956 components: - type: Transform @@ -69898,17 +69713,16 @@ entities: - type: Transform pos: -22.5,-1.5 parent: 1 - - uid: 5665 + - uid: 5387 components: - type: Transform - rot: 3.141592653589793 rad - pos: 18.5,-13.5 + pos: 27.5,12.5 parent: 1 - - uid: 5666 + - uid: 5670 components: - type: Transform - rot: 3.141592653589793 rad - pos: 18.5,-14.5 + rot: 1.5707963267948966 rad + pos: 17.5,-15.5 parent: 1 - uid: 5947 components: @@ -69922,17 +69736,17 @@ entities: rot: 3.141592653589793 rad pos: -0.5,5.5 parent: 1 - - uid: 7445 + - uid: 7247 components: - type: Transform - rot: 3.141592653589793 rad - pos: 4.5,-15.5 + rot: 1.5707963267948966 rad + pos: 16.5,-15.5 parent: 1 - - uid: 7446 + - uid: 7443 components: - type: Transform - rot: 3.141592653589793 rad - pos: 5.5,-15.5 + rot: 1.5707963267948966 rad + pos: -20.5,13.5 parent: 1 - uid: 7710 components: @@ -70362,6 +70176,13 @@ entities: - type: Transform pos: -6.5061026,52.63185 parent: 1 +- proto: ToyFigurineChiefMedicalOfficer + entities: + - uid: 7449 + components: + - type: Transform + pos: -20.374619,13.548687 + parent: 1 - proto: ToyFireRipley entities: - uid: 8259 @@ -80010,10 +79831,10 @@ entities: parent: 1 - proto: WeaponSubMachineGunWt550 entities: - - uid: 5385 + - uid: 1710 components: - type: Transform - pos: 27.524961,14.648642 + pos: 27.516527,12.712759 parent: 1 - proto: WeaponTurretSyndicateBroken entities: From ca9830a2842b4889a20825d9d34da4c6fe891086 Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 5 Jun 2024 17:51:47 +0000 Subject: [PATCH 02/55] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 574ea1adb35..851ebffc64d 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Plykiya - changes: - - message: Lone operatives now start with 60TC instead of 40TC. - type: Tweak - id: 6183 - time: '2024-03-18T14:15:53.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/26130 - author: PJB3005 changes: - message: Fixed hardsuits in space causing high pressure damage @@ -3849,3 +3842,10 @@ id: 6682 time: '2024-06-04T18:48:24.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/28590 +- author: Boaz1111 + changes: + - message: Revamped Cluster's Head Offices + type: Tweak + id: 6683 + time: '2024-06-05T17:50:38.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/28627 From 192a3187dfb80cbfec423a7a9757342dec08ceba Mon Sep 17 00:00:00 2001 From: Hmeister-real <118129069+Hmeister-real@users.noreply.github.com> Date: Wed, 5 Jun 2024 21:10:27 +0100 Subject: [PATCH 03/55] minor banner changes (#28636) * minor banner changes * Uhrmm actchually it's you're, not your * Update banners.yml props Hyenh --- .../Prototypes/Entities/Structures/Decoration/banners.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Resources/Prototypes/Entities/Structures/Decoration/banners.yml b/Resources/Prototypes/Entities/Structures/Decoration/banners.yml index cc0c90503d0..c2567814ac1 100644 --- a/Resources/Prototypes/Entities/Structures/Decoration/banners.yml +++ b/Resources/Prototypes/Entities/Structures/Decoration/banners.yml @@ -91,7 +91,7 @@ id: BannerScience parent: BannerBase name: science banner - description: A banner displaying the colors of the science department. Where stupidity is proven greater than the universe. + description: A banner displaying the colors of the science department. Where science has no bounds, and regulations are rarely followed. components: - type: Sprite sprite: Structures/Decoration/banner.rsi @@ -101,7 +101,7 @@ id: BannerSecurity parent: BannerBase name: security banner - description: A banner displaying the colors of the shitcurity department. Security, my bad. + description: A banner displaying the colors of the security department. You're surprised it's not vandalised. components: - type: Sprite sprite: Structures/Decoration/banner.rsi From 4c0a878f6feccc8282d0d7acbe37de5c3e9f4528 Mon Sep 17 00:00:00 2001 From: lapatison <100279397+lapatison@users.noreply.github.com> Date: Wed, 5 Jun 2024 23:10:58 +0300 Subject: [PATCH 04/55] Revenant spell catalog locale (#28638) locale --- .../Locale/en-US/store/revenant-catalog.ftl | 11 +++++++++++ .../Prototypes/Catalog/revenant_catalog.yml | 16 ++++++++-------- 2 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 Resources/Locale/en-US/store/revenant-catalog.ftl diff --git a/Resources/Locale/en-US/store/revenant-catalog.ftl b/Resources/Locale/en-US/store/revenant-catalog.ftl new file mode 100644 index 00000000000..d3cbbf724fc --- /dev/null +++ b/Resources/Locale/en-US/store/revenant-catalog.ftl @@ -0,0 +1,11 @@ +revenant-defile-name = Defile +revenant-defile-desc = Defiles the surrounding area, ripping up floors, damaging windows, opening containers, and throwing items. Using it leaves you vulnerable to attacks for a short period of time. + +revenant-overload-name = Overload Lights +revenant-overload-desc = Overloads all nearby lights, causing lights to pulse and sending out dangerous lightning. Using it leaves you vulnerable to attacks for a long period of time. + +revenant-blight-name = Blight +revenant-blight-desc = Infects all nearby organisms with an infectious disease that causes toxic buildup and tiredness. Using it leaves you vulnerable to attacks for a medium period of time. + +revenant-malfunction-name = Malfunction +revenant-malfunction-desc = Makes nearby electronics stop working properly. Using it leaves you vulnerable to attacks for a long period of time. diff --git a/Resources/Prototypes/Catalog/revenant_catalog.yml b/Resources/Prototypes/Catalog/revenant_catalog.yml index 84f45d16073..ec1ef0a309b 100644 --- a/Resources/Prototypes/Catalog/revenant_catalog.yml +++ b/Resources/Prototypes/Catalog/revenant_catalog.yml @@ -1,7 +1,7 @@ - type: listing id: RevenantDefile - name: Defile - description: Defiles the surrounding area, ripping up floors, damaging windows, opening containers, and throwing items. Using it leaves you vulnerable to attacks for a short period of time. + name: revenant-defile-name + description: revenant-defile-desc productAction: ActionRevenantDefile cost: StolenEssence: 10 @@ -13,8 +13,8 @@ - type: listing id: RevenantOverloadLights - name: Overload Lights - description: Overloads all nearby lights, causing lights to pulse and sending out dangerous lightning. Using it leaves you vulnerable to attacks for a long period of time. + name: revenant-overload-name + description: revenant-overload-desc productAction: ActionRevenantOverloadLights cost: StolenEssence: 25 @@ -26,8 +26,8 @@ #- type: listing # id: RevenantBlight -# name: Blight -# description: Infects all nearby organisms with an infectious disease that causes toxic buildup and tiredness. Using it leaves you vulnerable to attacks for a medium period of time. +# name: revenant-blight-name +# description: revenant-blight-desc # productAction: ActionRevenantBlight # cost: # StolenEssence: 75 @@ -39,8 +39,8 @@ - type: listing id: RevenantMalfunction - name: Malfunction - description: Makes nearby electronics stop working properly. Using it leaves you vulnerable to attacks for a long period of time. + name: revenant-malfunction-name + description: revenant-malfunction-desc productAction: ActionRevenantMalfunction cost: StolenEssence: 125 From d75de9fa248cce1a1670616ba0af5a0f4759ce51 Mon Sep 17 00:00:00 2001 From: Plykiya <58439124+Plykiya@users.noreply.github.com> Date: Wed, 5 Jun 2024 13:14:56 -0700 Subject: [PATCH 05/55] Make cuff default range again (#28576) * Make cuff default range again * uncuff distance * how about ONE --------- Co-authored-by: plykiya --- Content.Shared/Cuffs/SharedCuffableSystem.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Content.Shared/Cuffs/SharedCuffableSystem.cs b/Content.Shared/Cuffs/SharedCuffableSystem.cs index f0f9a949839..1ced3c8d6cb 100644 --- a/Content.Shared/Cuffs/SharedCuffableSystem.cs +++ b/Content.Shared/Cuffs/SharedCuffableSystem.cs @@ -484,7 +484,7 @@ public bool TryCuffing(EntityUid user, EntityUid target, EntityUid handcuff, Han BreakOnWeightlessMove = false, BreakOnDamage = true, NeedHand = true, - DistanceThreshold = 0.3f + DistanceThreshold = 1f // shorter than default but still feels good }; if (!_doAfter.TryStartDoAfter(doAfterEventArgs)) @@ -581,7 +581,7 @@ public void TryUncuff(EntityUid target, EntityUid user, EntityUid? cuffsToRemove BreakOnDamage = true, NeedHand = true, RequireCanInteract = false, // Trust in UncuffAttemptEvent - DistanceThreshold = 0.3f + DistanceThreshold = 1f // shorter than default but still feels good }; if (!_doAfter.TryStartDoAfter(doAfterEventArgs)) From 8a7b0f675e1cf140f28cb6f0bb2d15c3fca9a14f Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 5 Jun 2024 20:16:02 +0000 Subject: [PATCH 06/55] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 851ebffc64d..e68ab9517d3 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: PJB3005 - changes: - - message: Fixed hardsuits in space causing high pressure damage - type: Fix - id: 6184 - time: '2024-03-18T16:46:31.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/26236 - author: potato1234x changes: - message: Added crafting recipes for wall lockers and secure lockers @@ -3849,3 +3842,10 @@ id: 6683 time: '2024-06-05T17:50:38.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/28627 +- author: Plykiya + changes: + - message: Handcuff range is buffed to one tile of distance. + type: Tweak + id: 6684 + time: '2024-06-05T20:14:56.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/28576 From 729e67af7f2892644d758c6ade5c9abc4ac6c66e Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Wed, 5 Jun 2024 16:23:23 -0400 Subject: [PATCH 07/55] Machine-code cleanup (#28489) --- .../UI/FlatpackCreatorMenu.xaml.cs | 3 +- .../Tests/MachineBoardTest.cs | 41 +- .../Tests/MaterialArbitrageTest.cs | 3 +- .../Construction/Components/IRefreshParts.cs | 10 - .../Components/MachineComponent.cs | 34 +- .../Components/MachineFrameComponent.cs | 19 +- .../Components/PartExchangerComponent.cs | 29 -- .../Conditions/MachineFrameComplete.cs | 28 +- .../Construction/ConstructionSystem.Graph.cs | 8 +- .../Construction/ConstructionSystem.Guided.cs | 6 +- .../ConstructionSystem.Initial.cs | 8 +- .../ConstructionSystem.Machine.cs | 176 +-------- .../Construction/ConstructionSystem.cs | 1 - .../Construction/MachineFrameSystem.cs | 128 +------ .../Construction/PartExchangerSystem.cs | 180 --------- Content.Server/Stack/StackSystem.cs | 9 + .../Components/MachineBoardComponent.cs | 89 ++--- .../Components/MachinePartComponent.cs | 24 -- .../Construction/MachinePartSystem.cs | 46 +-- .../Prototypes/MachinePartPrototype.cs | 28 -- .../Construction/SharedConstructionSystem.cs | 11 + .../Construction/SharedFlatpackSystem.cs | 9 +- Content.Shared/Lathe/LatheComponent.cs | 2 - ...bitrary-insert-construction-graph-step.ftl | 10 +- .../Devices/Circuitboards/Machine/cannons.yml | 17 +- .../Machine/particle_accelerator.yml | 17 +- .../Circuitboards/Machine/production.yml | 352 +++++++----------- .../Entities/Objects/Misc/machine_parts.yml | 11 +- .../Entities/Objects/Power/powercells.yml | 12 - .../Prototypes/MachineParts/machine_parts.yml | 20 - .../Prototypes/Stacks/science_stacks.yml | 2 +- 31 files changed, 352 insertions(+), 981 deletions(-) delete mode 100644 Content.Server/Construction/Components/IRefreshParts.cs delete mode 100644 Content.Server/Construction/Components/PartExchangerComponent.cs delete mode 100644 Content.Server/Construction/PartExchangerSystem.cs delete mode 100644 Content.Shared/Construction/Components/MachinePartComponent.cs delete mode 100644 Content.Shared/Construction/Prototypes/MachinePartPrototype.cs delete mode 100644 Resources/Prototypes/MachineParts/machine_parts.yml diff --git a/Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs b/Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs index ad19bc30f42..00261632378 100644 --- a/Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs +++ b/Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs @@ -75,8 +75,7 @@ protected override void FrameUpdate(FrameEventArgs args) else if (_currentBoard != null) { Dictionary cost; - if (_entityManager.TryGetComponent(_currentBoard, out machineBoardComp) && - machineBoardComp.Prototype is not null) + if (_entityManager.TryGetComponent(_currentBoard, out machineBoardComp)) cost = _flatpack.GetFlatpackCreationCost((_owner, flatpacker), (_currentBoard.Value, machineBoardComp)); else cost = _flatpack.GetFlatpackCreationCost((_owner, flatpacker)); diff --git a/Content.IntegrationTests/Tests/MachineBoardTest.cs b/Content.IntegrationTests/Tests/MachineBoardTest.cs index bd3a72f4c1d..e741935be34 100644 --- a/Content.IntegrationTests/Tests/MachineBoardTest.cs +++ b/Content.IntegrationTests/Tests/MachineBoardTest.cs @@ -2,6 +2,8 @@ using System.Linq; using Content.Server.Construction.Components; using Content.Shared.Construction.Components; +using Content.Shared.Prototypes; +using Robust.Shared.GameObjects; using Robust.Shared.Prototypes; namespace Content.IntegrationTests.Tests; @@ -49,12 +51,11 @@ await server.WaitAssertion(() => Assert.Multiple(() => { - Assert.That(mId, Is.Not.Null, $"Machine board {p.ID} does not have a corresponding machine."); Assert.That(protoMan.TryIndex(mId, out var mProto), $"Machine board {p.ID}'s corresponding machine has an invalid prototype."); Assert.That(mProto.TryGetComponent(out var mComp), $"Machine board {p.ID}'s corresponding machine {mId} does not have MachineComponent"); - Assert.That(mComp.BoardPrototype, Is.EqualTo(p.ID), + Assert.That(mComp.Board, Is.EqualTo(p.ID), $"Machine {mId}'s BoardPrototype is not equal to it's corresponding machine board, {p.ID}"); }); } @@ -101,4 +102,40 @@ await server.WaitAssertion(() => await pair.CleanReturnAsync(); } + + /// + /// Ensures that every single computer board's corresponding entity + /// is a computer that can be properly deconstructed to the correct board + /// + [Test] + public async Task TestValidateBoardComponentRequirements() + { + await using var pair = await PoolManager.GetServerClient(); + var server = pair.Server; + + var entMan = server.ResolveDependency(); + var protoMan = server.ResolveDependency(); + + await server.WaitAssertion(() => + { + foreach (var p in protoMan.EnumeratePrototypes() + .Where(p => !p.Abstract) + .Where(p => !pair.IsTestPrototype(p)) + .Where(p => !_ignoredPrototypes.Contains(p.ID))) + { + if (!p.TryGetComponent(out var board, entMan.ComponentFactory)) + continue; + + Assert.Multiple(() => + { + foreach (var component in board.ComponentRequirements.Keys) + { + Assert.That(entMan.ComponentFactory.TryGetRegistration(component, out _), $"Invalid component requirement {component} specified on machine board entity {p}"); + } + }); + } + }); + + await pair.CleanReturnAsync(); + } } diff --git a/Content.IntegrationTests/Tests/MaterialArbitrageTest.cs b/Content.IntegrationTests/Tests/MaterialArbitrageTest.cs index ed1e5549438..19780591bdb 100644 --- a/Content.IntegrationTests/Tests/MaterialArbitrageTest.cs +++ b/Content.IntegrationTests/Tests/MaterialArbitrageTest.cs @@ -60,7 +60,8 @@ public async Task NoMaterialArbitrage() } // Lets assume the possible lathe for resource multipliers: - var multiplier = MathF.Pow(LatheComponent.DefaultPartRatingMaterialUseMultiplier, MachinePartComponent.MaxRating - 1); + // TODO: each recipe can technically have its own cost multiplier associated with it, so this test needs redone to factor that in. + var multiplier = MathF.Pow(0.85f, 3); // create construction dictionary Dictionary constructionRecipes = new(); diff --git a/Content.Server/Construction/Components/IRefreshParts.cs b/Content.Server/Construction/Components/IRefreshParts.cs deleted file mode 100644 index 714ca72c971..00000000000 --- a/Content.Server/Construction/Components/IRefreshParts.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Content.Shared.Construction.Components; - -namespace Content.Server.Construction.Components -{ - [RequiresExplicitImplementation] - public interface IRefreshParts - { - void RefreshParts(IEnumerable parts); - } -} diff --git a/Content.Server/Construction/Components/MachineComponent.cs b/Content.Server/Construction/Components/MachineComponent.cs index 42c85e6d0b5..8a0f117712e 100644 --- a/Content.Server/Construction/Components/MachineComponent.cs +++ b/Content.Server/Construction/Components/MachineComponent.cs @@ -1,27 +1,17 @@ -using Robust.Shared.Containers; +using Content.Shared.Construction.Components; +using Robust.Shared.Containers; using Robust.Shared.Prototypes; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; -namespace Content.Server.Construction.Components -{ - [RegisterComponent, ComponentProtoName("Machine")] - public sealed partial class MachineComponent : Component - { - [DataField("board", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string? BoardPrototype { get; private set; } +namespace Content.Server.Construction.Components; - [ViewVariables] - public Container BoardContainer = default!; - [ViewVariables] - public Container PartContainer = default!; - } +[RegisterComponent] +public sealed partial class MachineComponent : Component +{ + [DataField] + public EntProtoId? Board { get; private set; } - /// - /// The different types of scaling that are available for machine upgrades - /// - public enum MachineUpgradeScalingType : byte - { - Linear, - Exponential - } + [ViewVariables] + public Container BoardContainer = default!; + [ViewVariables] + public Container PartContainer = default!; } diff --git a/Content.Server/Construction/Components/MachineFrameComponent.cs b/Content.Server/Construction/Components/MachineFrameComponent.cs index 75cc486f240..14e81e8dd32 100644 --- a/Content.Server/Construction/Components/MachineFrameComponent.cs +++ b/Content.Server/Construction/Components/MachineFrameComponent.cs @@ -1,7 +1,8 @@ using Content.Shared.Construction.Components; -using Content.Shared.Construction.Prototypes; +using Content.Shared.Stacks; +using Content.Shared.Tag; using Robust.Shared.Containers; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary; +using Robust.Shared.Prototypes; namespace Content.Server.Construction.Components { @@ -14,29 +15,23 @@ public sealed partial class MachineFrameComponent : Component [ViewVariables] public bool HasBoard => BoardContainer?.ContainedEntities.Count != 0; - [DataField("progress", customTypeSerializer: typeof(PrototypeIdDictionarySerializer))] - public Dictionary Progress = new(); - [ViewVariables] - public readonly Dictionary MaterialProgress = new(); + public readonly Dictionary, int> MaterialProgress = new(); [ViewVariables] public readonly Dictionary ComponentProgress = new(); [ViewVariables] - public readonly Dictionary TagProgress = new(); - - [DataField("requirements", customTypeSerializer: typeof(PrototypeIdDictionarySerializer))] - public Dictionary Requirements = new(); + public readonly Dictionary, int> TagProgress = new(); [ViewVariables] - public Dictionary MaterialRequirements = new(); + public Dictionary, int> MaterialRequirements = new(); [ViewVariables] public Dictionary ComponentRequirements = new(); [ViewVariables] - public Dictionary TagRequirements = new(); + public Dictionary, GenericPartInfo> TagRequirements = new(); [ViewVariables] public Container BoardContainer = default!; diff --git a/Content.Server/Construction/Components/PartExchangerComponent.cs b/Content.Server/Construction/Components/PartExchangerComponent.cs deleted file mode 100644 index a2579c92e80..00000000000 --- a/Content.Server/Construction/Components/PartExchangerComponent.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Robust.Shared.Audio; - -namespace Content.Server.Construction.Components; - -[RegisterComponent] -public sealed partial class PartExchangerComponent : Component -{ - /// - /// How long it takes to exchange the parts - /// - [DataField("exchangeDuration")] - public float ExchangeDuration = 3; - - /// - /// Whether or not the distance check is needed. - /// Good for BRPED. - /// - /// - /// I fucking hate BRPED and if you ever add it - /// i will personally kill your dog. - /// - [DataField("doDistanceCheck")] - public bool DoDistanceCheck = true; - - [DataField("exchangeSound")] - public SoundSpecifier ExchangeSound = new SoundPathSpecifier("/Audio/Items/rped.ogg"); - - public EntityUid? AudioStream; -} diff --git a/Content.Server/Construction/Conditions/MachineFrameComplete.cs b/Content.Server/Construction/Conditions/MachineFrameComplete.cs index fbba5eca996..33174bb9fb0 100644 --- a/Content.Server/Construction/Conditions/MachineFrameComplete.cs +++ b/Content.Server/Construction/Conditions/MachineFrameComplete.cs @@ -2,6 +2,7 @@ using Content.Shared.Construction; using Content.Shared.Examine; using JetBrains.Annotations; +using Robust.Shared.Prototypes; using Robust.Shared.Utility; namespace Content.Server.Construction.Conditions @@ -17,7 +18,7 @@ public sealed partial class MachineFrameComplete : IGraphCondition public SpriteSpecifier? GuideIconBoard { get; private set; } [DataField("guideIconParts")] - public SpriteSpecifier? GuideIconPart { get; private set; } + public SpriteSpecifier? GuideIconParts { get; private set; } public bool Condition(EntityUid uid, IEntityManager entityManager) @@ -33,6 +34,8 @@ public bool DoExamine(ExaminedEvent args) var entity = args.Examined; var entityManager = IoCManager.Resolve(); + var protoManager = IoCManager.Resolve(); + var constructionSys = entityManager.System(); if (!entityManager.TryGetComponent(entity, out MachineFrameComponent? machineFrame)) return false; @@ -47,17 +50,6 @@ public bool DoExamine(ExaminedEvent args) return false; args.PushMarkup(Loc.GetString("construction-condition-machine-frame-requirement-label")); - foreach (var (part, required) in machineFrame.Requirements) - { - var amount = required - machineFrame.Progress[part]; - - if(amount == 0) - continue; - - args.PushMarkup(Loc.GetString("construction-condition-machine-frame-required-element-entry", - ("amount", amount), - ("elementName", Loc.GetString(part)))); - } foreach (var (material, required) in machineFrame.MaterialRequirements) { @@ -65,10 +57,12 @@ public bool DoExamine(ExaminedEvent args) if(amount == 0) continue; + var stack = protoManager.Index(material); + var stackEnt = protoManager.Index(stack.Spawn); args.PushMarkup(Loc.GetString("construction-condition-machine-frame-required-element-entry", ("amount", amount), - ("elementName", Loc.GetString(material)))); + ("elementName", stackEnt.Name))); } foreach (var (compName, info) in machineFrame.ComponentRequirements) @@ -78,9 +72,10 @@ public bool DoExamine(ExaminedEvent args) if(amount == 0) continue; + var examineName = constructionSys.GetExamineName(info); args.PushMarkup(Loc.GetString("construction-condition-machine-frame-required-element-entry", ("amount", info.Amount), - ("elementName", Loc.GetString(info.ExamineName)))); + ("elementName", examineName))); } foreach (var (tagName, info) in machineFrame.TagRequirements) @@ -90,9 +85,10 @@ public bool DoExamine(ExaminedEvent args) if(amount == 0) continue; + var examineName = constructionSys.GetExamineName(info); args.PushMarkup(Loc.GetString("construction-condition-machine-frame-required-element-entry", ("amount", info.Amount), - ("elementName", Loc.GetString(info.ExamineName))) + ("elementName", examineName)) + "\n"); } @@ -111,7 +107,7 @@ public IEnumerable GenerateGuideEntry() yield return new ConstructionGuideEntry() { Localization = "construction-step-condition-machine-frame-parts", - Icon = GuideIconPart, + Icon = GuideIconParts, EntryNumber = 0, // Set this to anything so the guide generation takes this as a numbered step. }; } diff --git a/Content.Server/Construction/ConstructionSystem.Graph.cs b/Content.Server/Construction/ConstructionSystem.Graph.cs index 570360bf09a..1b74fd9d4e5 100644 --- a/Content.Server/Construction/ConstructionSystem.Graph.cs +++ b/Content.Server/Construction/ConstructionSystem.Graph.cs @@ -50,7 +50,7 @@ public bool AddContainer(EntityUid uid, string container, ConstructionComponent? // If the set graph prototype does not exist, also return null. This could be due to admemes changing values // in ViewVariables, so even though the construction state is invalid, just return null. - return _prototypeManager.TryIndex(construction.Graph, out ConstructionGraphPrototype? graph) ? graph : null; + return PrototypeManager.TryIndex(construction.Graph, out ConstructionGraphPrototype? graph) ? graph : null; } /// @@ -300,7 +300,7 @@ public bool ChangeNode(EntityUid uid, EntityUid? userUid, string id, bool perfor } // Exit if the new entity's prototype is the same as the original, or the prototype is invalid - if (newEntity == metaData.EntityPrototype?.ID || !_prototypeManager.HasIndex(newEntity)) + if (newEntity == metaData.EntityPrototype?.ID || !PrototypeManager.HasIndex(newEntity)) return null; // [Optional] Exit if the new entity's prototype is a parent of the original @@ -310,7 +310,7 @@ public bool ChangeNode(EntityUid uid, EntityUid? userUid, string id, bool perfor if (GetCurrentNode(uid, construction)?.DoNotReplaceInheritingEntities == true && metaData.EntityPrototype?.ID != null) { - var parents = _prototypeManager.EnumerateParents(metaData.EntityPrototype.ID)?.ToList(); + var parents = PrototypeManager.EnumerateParents(metaData.EntityPrototype.ID)?.ToList(); if (parents != null && parents.Any(x => x.ID == newEntity)) return null; @@ -427,7 +427,7 @@ public bool ChangeGraph(EntityUid uid, EntityUid? userUid, string graphId, strin if (!Resolve(uid, ref construction)) return false; - if (!_prototypeManager.TryIndex(graphId, out var graph)) + if (!PrototypeManager.TryIndex(graphId, out var graph)) return false; if(GetNodeFromGraph(graph, nodeId) is not {}) diff --git a/Content.Server/Construction/ConstructionSystem.Guided.cs b/Content.Server/Construction/ConstructionSystem.Guided.cs index e096bc02c31..157e4211586 100644 --- a/Content.Server/Construction/ConstructionSystem.Guided.cs +++ b/Content.Server/Construction/ConstructionSystem.Guided.cs @@ -25,7 +25,7 @@ private void InitializeGuided() private void OnGuideRequested(RequestConstructionGuide msg, EntitySessionEventArgs args) { - if (!_prototypeManager.TryIndex(msg.ConstructionId, out ConstructionPrototype? prototype)) + if (!PrototypeManager.TryIndex(msg.ConstructionId, out ConstructionPrototype? prototype)) return; if(GetGuide(prototype) is {} guide) @@ -41,7 +41,7 @@ private void AddDeconstructVerb(EntityUid uid, ConstructionComponent component, component.Node == component.DeconstructionNode) return; - if (!_prototypeManager.TryIndex(component.Graph, out ConstructionGraphPrototype? graph)) + if (!PrototypeManager.TryIndex(component.Graph, out ConstructionGraphPrototype? graph)) return; if (component.DeconstructionNode == null) @@ -145,7 +145,7 @@ private void HandleConstructionExamined(EntityUid uid, ConstructionComponent com return guide; // If the graph doesn't actually exist, do nothing. - if (!_prototypeManager.TryIndex(construction.Graph, out ConstructionGraphPrototype? graph)) + if (!PrototypeManager.TryIndex(construction.Graph, out ConstructionGraphPrototype? graph)) return null; // If either the start node or the target node are missing, do nothing. diff --git a/Content.Server/Construction/ConstructionSystem.Initial.cs b/Content.Server/Construction/ConstructionSystem.Initial.cs index 5161ac358ac..08dd139ef4c 100644 --- a/Content.Server/Construction/ConstructionSystem.Initial.cs +++ b/Content.Server/Construction/ConstructionSystem.Initial.cs @@ -325,13 +325,13 @@ private async void HandleStartItemConstruction(TryStartItemConstructionMessage e // LEGACY CODE. See warning at the top of the file! public async Task TryStartItemConstruction(string prototype, EntityUid user) { - if (!_prototypeManager.TryIndex(prototype, out ConstructionPrototype? constructionPrototype)) + if (!PrototypeManager.TryIndex(prototype, out ConstructionPrototype? constructionPrototype)) { Log.Error($"Tried to start construction of invalid recipe '{prototype}'!"); return false; } - if (!_prototypeManager.TryIndex(constructionPrototype.Graph, + if (!PrototypeManager.TryIndex(constructionPrototype.Graph, out ConstructionGraphPrototype? constructionGraph)) { Log.Error( @@ -404,14 +404,14 @@ public async Task TryStartItemConstruction(string prototype, EntityUid use // LEGACY CODE. See warning at the top of the file! private async void HandleStartStructureConstruction(TryStartStructureConstructionMessage ev, EntitySessionEventArgs args) { - if (!_prototypeManager.TryIndex(ev.PrototypeName, out ConstructionPrototype? constructionPrototype)) + if (!PrototypeManager.TryIndex(ev.PrototypeName, out ConstructionPrototype? constructionPrototype)) { Log.Error($"Tried to start construction of invalid recipe '{ev.PrototypeName}'!"); RaiseNetworkEvent(new AckStructureConstructionMessage(ev.Ack)); return; } - if (!_prototypeManager.TryIndex(constructionPrototype.Graph, out ConstructionGraphPrototype? constructionGraph)) + if (!PrototypeManager.TryIndex(constructionPrototype.Graph, out ConstructionGraphPrototype? constructionGraph)) { Log.Error($"Invalid construction graph '{constructionPrototype.Graph}' in recipe '{ev.PrototypeName}'!"); RaiseNetworkEvent(new AckStructureConstructionMessage(ev.Ack)); diff --git a/Content.Server/Construction/ConstructionSystem.Machine.cs b/Content.Server/Construction/ConstructionSystem.Machine.cs index 2e670dbe40d..eb922f198c7 100644 --- a/Content.Server/Construction/ConstructionSystem.Machine.cs +++ b/Content.Server/Construction/ConstructionSystem.Machine.cs @@ -1,23 +1,15 @@ -using System.Linq; using Content.Server.Construction.Components; -using Content.Server.Examine; using Content.Shared.Construction.Components; -using Content.Shared.Construction.Prototypes; -using Content.Shared.Verbs; using Robust.Shared.Containers; -using Robust.Shared.Utility; namespace Content.Server.Construction; public sealed partial class ConstructionSystem { - [Dependency] private readonly ExamineSystem _examineSystem = default!; - private void InitializeMachines() { SubscribeLocalEvent(OnMachineInit); SubscribeLocalEvent(OnMachineMapInit); - SubscribeLocalEvent>(OnMachineExaminableVerb); } private void OnMachineInit(EntityUid uid, MachineComponent component, ComponentInit args) @@ -29,84 +21,6 @@ private void OnMachineInit(EntityUid uid, MachineComponent component, ComponentI private void OnMachineMapInit(EntityUid uid, MachineComponent component, MapInitEvent args) { CreateBoardAndStockParts(uid, component); - RefreshParts(uid, component); - } - - private void OnMachineExaminableVerb(EntityUid uid, MachineComponent component, GetVerbsEvent args) - { - if (!args.CanInteract || !args.CanAccess) - return; - - var markup = new FormattedMessage(); - RaiseLocalEvent(uid, new UpgradeExamineEvent(ref markup)); - if (markup.IsEmpty) - return; // Not upgradable. - - markup = FormattedMessage.FromMarkup(markup.ToMarkup().TrimEnd('\n')); // Cursed workaround to https://github.com/space-wizards/RobustToolbox/issues/3371 - - var verb = new ExamineVerb() - { - Act = () => - { - _examineSystem.SendExamineTooltip(args.User, uid, markup, getVerbs: false, centerAtCursor: false); - }, - Text = Loc.GetString("machine-upgrade-examinable-verb-text"), - Message = Loc.GetString("machine-upgrade-examinable-verb-message"), - Category = VerbCategory.Examine, - Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/VerbIcons/pickup.svg.192dpi.png")) - }; - - args.Verbs.Add(verb); - } - - public List GetAllParts(EntityUid uid, MachineComponent? component = null) - { - if (!Resolve(uid, ref component)) - return new List(); - - return GetAllParts(component); - } - - public List GetAllParts(MachineComponent component) - { - var parts = new List(); - - foreach (var entity in component.PartContainer.ContainedEntities) - { - if (TryComp(entity, out var machinePart)) - parts.Add(machinePart); - } - - return parts; - } - - public Dictionary GetPartsRatings(List parts) - { - var output = new Dictionary(); - foreach (var type in _prototypeManager.EnumeratePrototypes()) - { - var amount = 0f; - var sumRating = 0f; - foreach (var part in parts.Where(part => part.PartType == type.ID)) - { - amount++; - sumRating += part.Rating; - } - var rating = amount != 0 ? sumRating / amount : 0; - output.Add(type.ID, rating); - } - - return output; - } - - public void RefreshParts(EntityUid uid, MachineComponent component) - { - var parts = GetAllParts(component); - EntityManager.EventBus.RaiseLocalEvent(uid, new RefreshPartsEvent - { - Parts = parts, - PartRatings = GetPartsRatings(parts), - }, true); } private void CreateBoardAndStockParts(EntityUid uid, MachineComponent component) @@ -115,54 +29,37 @@ private void CreateBoardAndStockParts(EntityUid uid, MachineComponent component) var boardContainer = _container.EnsureContainer(uid, MachineFrameComponent.BoardContainerName); var partContainer = _container.EnsureContainer(uid, MachineFrameComponent.PartContainerName); - if (string.IsNullOrEmpty(component.BoardPrototype)) + if (string.IsNullOrEmpty(component.Board)) return; // We're done here, let's suppose all containers are correct just so we don't screw SaveLoadSave. if (boardContainer.ContainedEntities.Count > 0) return; - var board = EntityManager.SpawnEntity(component.BoardPrototype, Transform(uid).Coordinates); - - if (!_container.Insert(board, component.BoardContainer)) + var xform = Transform(uid); + if (!TrySpawnInContainer(component.Board, uid, MachineFrameComponent.BoardContainerName, out var board)) { - throw new Exception($"Couldn't insert board with prototype {component.BoardPrototype} to machine with prototype {MetaData(uid).EntityPrototype?.ID ?? "N/A"}!"); + throw new Exception($"Couldn't insert board with prototype {component.Board} to machine with prototype {Prototype(uid)?.ID ?? "N/A"}!"); } if (!TryComp(board, out var machineBoard)) { - throw new Exception($"Entity with prototype {component.BoardPrototype} doesn't have a {nameof(MachineBoardComponent)}!"); - } - - var xform = Transform(uid); - foreach (var (part, amount) in machineBoard.Requirements) - { - var partProto = _prototypeManager.Index(part); - for (var i = 0; i < amount; i++) - { - var p = EntityManager.SpawnEntity(partProto.StockPartPrototype, xform.Coordinates); - - if (!_container.Insert(p, partContainer)) - throw new Exception($"Couldn't insert machine part of type {part} to machine with prototype {partProto.StockPartPrototype}!"); - } + throw new Exception($"Entity with prototype {component.Board} doesn't have a {nameof(MachineBoardComponent)}!"); } - foreach (var (stackType, amount) in machineBoard.MaterialRequirements) + foreach (var (stackType, amount) in machineBoard.StackRequirements) { - var stack = _stackSystem.Spawn(amount, stackType, Transform(uid).Coordinates); - + var stack = _stackSystem.Spawn(amount, stackType, xform.Coordinates); if (!_container.Insert(stack, partContainer)) - throw new Exception($"Couldn't insert machine material of type {stackType} to machine with prototype {MetaData(uid).EntityPrototype?.ID ?? "N/A"}"); + throw new Exception($"Couldn't insert machine material of type {stackType} to machine with prototype {Prototype(uid)?.ID ?? "N/A"}"); } foreach (var (compName, info) in machineBoard.ComponentRequirements) { for (var i = 0; i < info.Amount; i++) { - var c = EntityManager.SpawnEntity(info.DefaultPrototype, Transform(uid).Coordinates); - - if(!_container.Insert(c, partContainer)) - throw new Exception($"Couldn't insert machine component part with default prototype '{compName}' to machine with prototype {MetaData(uid).EntityPrototype?.ID ?? "N/A"}"); + if(!TrySpawnInContainer(info.DefaultPrototype, uid, MachineFrameComponent.PartContainerName, out _)) + throw new Exception($"Couldn't insert machine component part with default prototype '{compName}' to machine with prototype {Prototype(uid)?.ID ?? "N/A"}"); } } @@ -170,58 +67,9 @@ private void CreateBoardAndStockParts(EntityUid uid, MachineComponent component) { for (var i = 0; i < info.Amount; i++) { - var c = EntityManager.SpawnEntity(info.DefaultPrototype, Transform(uid).Coordinates); - - if(!_container.Insert(c, partContainer)) - throw new Exception($"Couldn't insert machine component part with default prototype '{tagName}' to machine with prototype {MetaData(uid).EntityPrototype?.ID ?? "N/A"}"); + if(!TrySpawnInContainer(info.DefaultPrototype, uid, MachineFrameComponent.PartContainerName, out _)) + throw new Exception($"Couldn't insert machine component part with default prototype '{tagName}' to machine with prototype {Prototype(uid)?.ID ?? "N/A"}"); } } } } - -public sealed class RefreshPartsEvent : EntityEventArgs -{ - public IReadOnlyList Parts = new List(); - - public Dictionary PartRatings = new(); -} - -public sealed class UpgradeExamineEvent : EntityEventArgs -{ - private FormattedMessage Message; - - public UpgradeExamineEvent(ref FormattedMessage message) - { - Message = message; - } - - /// - /// Add a line to the upgrade examine tooltip with a percentage-based increase or decrease. - /// - public void AddPercentageUpgrade(string upgradedLocId, float multiplier) - { - var percent = Math.Round(100 * MathF.Abs(multiplier - 1), 2); - var locId = multiplier switch { - < 1 => "machine-upgrade-decreased-by-percentage", - 1 or float.NaN => "machine-upgrade-not-upgraded", - > 1 => "machine-upgrade-increased-by-percentage", - }; - var upgraded = Loc.GetString(upgradedLocId); - this.Message.AddMarkup(Loc.GetString(locId, ("upgraded", upgraded), ("percent", percent)) + '\n'); - } - - /// - /// Add a line to the upgrade examine tooltip with a numeric increase or decrease. - /// - public void AddNumberUpgrade(string upgradedLocId, int number) - { - var difference = Math.Abs(number); - var locId = number switch { - < 0 => "machine-upgrade-decreased-by-amount", - 0 => "machine-upgrade-not-upgraded", - > 0 => "machine-upgrade-increased-by-amount", - }; - var upgraded = Loc.GetString(upgradedLocId); - this.Message.AddMarkup(Loc.GetString(locId, ("upgraded", upgraded), ("difference", difference)) + '\n'); - } -} diff --git a/Content.Server/Construction/ConstructionSystem.cs b/Content.Server/Construction/ConstructionSystem.cs index 44c6318b789..9d881dcef04 100644 --- a/Content.Server/Construction/ConstructionSystem.cs +++ b/Content.Server/Construction/ConstructionSystem.cs @@ -16,7 +16,6 @@ namespace Content.Server.Construction [UsedImplicitly] public sealed partial class ConstructionSystem : SharedConstructionSystem { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IRobustRandom _robustRandom = default!; [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; [Dependency] private readonly ContainerSystem _container = default!; diff --git a/Content.Server/Construction/MachineFrameSystem.cs b/Content.Server/Construction/MachineFrameSystem.cs index e20c36d8498..0fd5ad2e0e4 100644 --- a/Content.Server/Construction/MachineFrameSystem.cs +++ b/Content.Server/Construction/MachineFrameSystem.cs @@ -7,7 +7,7 @@ using Content.Shared.Tag; using Content.Shared.Popups; using Robust.Shared.Containers; -using Robust.Shared.Utility; +using Robust.Shared.Prototypes; namespace Content.Server.Construction; @@ -62,24 +62,7 @@ private void OnInteractUsing(EntityUid uid, MachineFrameComponent component, Int // If this changes in the future, then RegenerateProgress() also needs to be updated. // Note that one entity is ALLOWED to satisfy more than one kind of component or tag requirements. This is // necessary in order to avoid weird entity-ordering shenanigans in RegenerateProgress(). - var stack = CompOrNull(args.Used); - var machinePart = CompOrNull(args.Used); - if (stack != null && machinePart != null) - { - if (TryInsertPartStack(uid, args.Used, component, machinePart, stack)) - args.Handled = true; - return; - } - - // Handle parts - if (machinePart != null) - { - if (TryInsertPart(uid, args.Used, component, machinePart)) - args.Handled = true; - return; - } - - if (stack != null) + if (TryComp(args.Used, out var stack)) { if (TryInsertStack(uid, args.Used, component, stack)) args.Handled = true; @@ -172,67 +155,6 @@ private bool TryInsertBoard(EntityUid uid, EntityUid used, MachineFrameComponent return true; } - /// Whether or not the function had any effect. Does not indicate success. - private bool TryInsertPart(EntityUid uid, EntityUid used, MachineFrameComponent component, MachinePartComponent machinePart) - { - DebugTools.Assert(!HasComp(uid)); - if (!component.Requirements.ContainsKey(machinePart.PartType)) - return false; - - if (component.Progress[machinePart.PartType] >= component.Requirements[machinePart.PartType]) - return false; - - if (!_container.TryRemoveFromContainer(used)) - return false; - - if (!_container.Insert(used, component.PartContainer)) - return true; - - component.Progress[machinePart.PartType]++; - if (IsComplete(component)) - _popupSystem.PopupEntity(Loc.GetString("machine-frame-component-on-complete"), uid); - - return true; - } - - /// Whether or not the function had any effect. Does not indicate success. - private bool TryInsertPartStack(EntityUid uid, EntityUid used, MachineFrameComponent component, MachinePartComponent machinePart, StackComponent stack) - { - if (!component.Requirements.ContainsKey(machinePart.PartType)) - return false; - - var progress = component.Progress[machinePart.PartType]; - var requirement = component.Requirements[machinePart.PartType]; - - var needed = requirement - progress; - if (needed <= 0) - return false; - - var count = stack.Count; - if (count < needed) - { - if (!_container.Insert(used, component.PartContainer)) - return true; - - component.Progress[machinePart.PartType] += count; - return true; - } - - var splitStack = _stack.Split(used, needed, Transform(uid).Coordinates, stack); - - if (splitStack == null) - return false; - - if (!_container.Insert(splitStack.Value, component.PartContainer)) - return true; - - component.Progress[machinePart.PartType] += needed; - if (IsComplete(component)) - _popupSystem.PopupEntity(Loc.GetString("machine-frame-component-on-complete"), uid); - - return true; - } - /// Whether or not the function had any effect. Does not indicate success. private bool TryInsertStack(EntityUid uid, EntityUid used, MachineFrameComponent component, StackComponent stack) { @@ -281,12 +203,6 @@ public bool IsComplete(MachineFrameComponent component) if (!component.HasBoard) return false; - foreach (var (part, amount) in component.Requirements) - { - if (component.Progress[part] < amount) - return false; - } - foreach (var (type, amount) in component.MaterialRequirements) { if (component.MaterialProgress[type] < amount) @@ -310,21 +226,14 @@ public bool IsComplete(MachineFrameComponent component) public void ResetProgressAndRequirements(MachineFrameComponent component, MachineBoardComponent machineBoard) { - component.Requirements = new Dictionary(machineBoard.Requirements); - component.MaterialRequirements = new Dictionary(machineBoard.MaterialIdRequirements); + component.MaterialRequirements = new Dictionary, int>(machineBoard.StackRequirements); component.ComponentRequirements = new Dictionary(machineBoard.ComponentRequirements); - component.TagRequirements = new Dictionary(machineBoard.TagRequirements); + component.TagRequirements = new Dictionary, GenericPartInfo>(machineBoard.TagRequirements); - component.Progress.Clear(); component.MaterialProgress.Clear(); component.ComponentProgress.Clear(); component.TagProgress.Clear(); - foreach (var (machinePart, _) in component.Requirements) - { - component.Progress[machinePart] = 0; - } - foreach (var (stackType, _) in component.MaterialRequirements) { component.MaterialProgress[stackType] = 0; @@ -349,7 +258,6 @@ public void RegenerateProgress(MachineFrameComponent component) component.MaterialRequirements.Clear(); component.ComponentRequirements.Clear(); component.TagRequirements.Clear(); - component.Progress.Clear(); component.MaterialProgress.Clear(); component.ComponentProgress.Clear(); component.TagProgress.Clear(); @@ -368,19 +276,6 @@ public void RegenerateProgress(MachineFrameComponent component) foreach (var part in component.PartContainer.ContainedEntities) { - if (TryComp(part, out var machinePart)) - { - // Check this is part of the requirements... - if (!component.Requirements.ContainsKey(machinePart.PartType)) - continue; - - if (!component.Progress.ContainsKey(machinePart.PartType)) - component.Progress[machinePart.PartType] = 1; - else - component.Progress[machinePart.PartType]++; - continue; - } - if (TryComp(part, out var stack)) { var type = stack.StackTypeId; @@ -404,9 +299,7 @@ public void RegenerateProgress(MachineFrameComponent component) if (!HasComp(part, registration.Type)) continue; - if (!component.ComponentProgress.ContainsKey(compName)) - component.ComponentProgress[compName] = 1; - else + if (!component.ComponentProgress.TryAdd(compName, 1)) component.ComponentProgress[compName]++; } @@ -419,18 +312,17 @@ public void RegenerateProgress(MachineFrameComponent component) if (!_tag.HasTag(tagComp, tagName)) continue; - if (!component.TagProgress.ContainsKey(tagName)) - component.TagProgress[tagName] = 1; - else + if (!component.TagProgress.TryAdd(tagName, 1)) component.TagProgress[tagName]++; } } } private void OnMachineFrameExamined(EntityUid uid, MachineFrameComponent component, ExaminedEvent args) { - if (!args.IsInDetailsRange) + if (!args.IsInDetailsRange || !component.HasBoard) return; - if (component.HasBoard) - args.PushMarkup(Loc.GetString("machine-frame-component-on-examine-label", ("board", EntityManager.GetComponent(component.BoardContainer.ContainedEntities[0]).EntityName))); + + var board = component.BoardContainer.ContainedEntities[0]; + args.PushMarkup(Loc.GetString("machine-frame-component-on-examine-label", ("board", Name(board)))); } } diff --git a/Content.Server/Construction/PartExchangerSystem.cs b/Content.Server/Construction/PartExchangerSystem.cs deleted file mode 100644 index 174dd1d2faa..00000000000 --- a/Content.Server/Construction/PartExchangerSystem.cs +++ /dev/null @@ -1,180 +0,0 @@ -using System.Linq; -using Content.Server.Construction.Components; -using Content.Server.Storage.EntitySystems; -using Content.Shared.DoAfter; -using Content.Shared.Construction.Components; -using Content.Shared.Exchanger; -using Content.Shared.Interaction; -using Content.Shared.Popups; -using Content.Shared.Storage; -using Robust.Shared.Containers; -using Robust.Shared.Utility; -using Content.Shared.Wires; -using Robust.Shared.Audio.Systems; -using Robust.Shared.Collections; - -namespace Content.Server.Construction; - -public sealed class PartExchangerSystem : EntitySystem -{ - [Dependency] private readonly ConstructionSystem _construction = default!; - [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; - [Dependency] private readonly SharedPopupSystem _popup = default!; - [Dependency] private readonly SharedContainerSystem _container = default!; - [Dependency] private readonly SharedAudioSystem _audio = default!; - [Dependency] private readonly StorageSystem _storage = default!; - - /// - public override void Initialize() - { - SubscribeLocalEvent(OnAfterInteract); - SubscribeLocalEvent(OnDoAfter); - } - - private void OnDoAfter(EntityUid uid, PartExchangerComponent component, DoAfterEvent args) - { - if (args.Cancelled) - { - component.AudioStream = _audio.Stop(component.AudioStream); - return; - } - - if (args.Handled || args.Args.Target == null) - return; - - if (!TryComp(uid, out var storage)) - return; //the parts are stored in here - - var machinePartQuery = GetEntityQuery(); - var machineParts = new List<(EntityUid, MachinePartComponent)>(); - - foreach (var item in storage.Container.ContainedEntities) //get parts in RPED - { - if (machinePartQuery.TryGetComponent(item, out var part)) - machineParts.Add((item, part)); - } - - TryExchangeMachineParts(args.Args.Target.Value, uid, machineParts); - TryConstructMachineParts(args.Args.Target.Value, uid, machineParts); - - args.Handled = true; - } - - private void TryExchangeMachineParts(EntityUid uid, EntityUid storageUid, List<(EntityUid part, MachinePartComponent partComp)> machineParts) - { - if (!TryComp(uid, out var machine)) - return; - - var machinePartQuery = GetEntityQuery(); - var board = machine.BoardContainer.ContainedEntities.FirstOrNull(); - - if (board == null || !TryComp(board, out var macBoardComp)) - return; - - foreach (var item in new ValueList(machine.PartContainer.ContainedEntities)) //clone so don't modify during enumeration - { - if (machinePartQuery.TryGetComponent(item, out var part)) - { - machineParts.Add((item, part)); - _container.RemoveEntity(uid, item); - } - } - - machineParts.Sort((x, y) => y.partComp.Rating.CompareTo(x.partComp.Rating)); - - var updatedParts = new List<(EntityUid part, MachinePartComponent partComp)>(); - foreach (var (type, amount) in macBoardComp.Requirements) - { - var target = machineParts.Where(p => p.partComp.PartType == type).Take(amount); - updatedParts.AddRange(target); - } - foreach (var part in updatedParts) - { - _container.Insert(part.part, machine.PartContainer); - machineParts.Remove(part); - } - - //put the unused parts back into rped. (this also does the "swapping") - foreach (var (unused, _) in machineParts) - { - _storage.Insert(storageUid, unused, out _, playSound: false); - } - _construction.RefreshParts(uid, machine); - } - - private void TryConstructMachineParts(EntityUid uid, EntityUid storageEnt, List<(EntityUid part, MachinePartComponent partComp)> machineParts) - { - if (!TryComp(uid, out var machine)) - return; - - var machinePartQuery = GetEntityQuery(); - var board = machine.BoardContainer.ContainedEntities.FirstOrNull(); - - if (!machine.HasBoard || !TryComp(board, out var macBoardComp)) - return; - - foreach (var item in new ValueList(machine.PartContainer.ContainedEntities)) //clone so don't modify during enumeration - { - if (machinePartQuery.TryGetComponent(item, out var part)) - { - machineParts.Add((item, part)); - _container.RemoveEntity(uid, item); - machine.Progress[part.PartType]--; - } - } - - machineParts.Sort((x, y) => y.partComp.Rating.CompareTo(x.partComp.Rating)); - - var updatedParts = new List<(EntityUid part, MachinePartComponent partComp)>(); - foreach (var (type, amount) in macBoardComp.Requirements) - { - var target = machineParts.Where(p => p.partComp.PartType == type).Take(amount); - updatedParts.AddRange(target); - } - foreach (var pair in updatedParts) - { - var part = pair.partComp; - var partEnt = pair.part; - - if (!machine.Requirements.ContainsKey(part.PartType)) - continue; - - _container.Insert(partEnt, machine.PartContainer); - machine.Progress[part.PartType]++; - machineParts.Remove(pair); - } - - //put the unused parts back into rped. (this also does the "swapping") - foreach (var (unused, _) in machineParts) - { - _storage.Insert(storageEnt, unused, out _, playSound: false); - } - } - - private void OnAfterInteract(EntityUid uid, PartExchangerComponent component, AfterInteractEvent args) - { - if (component.DoDistanceCheck && !args.CanReach) - return; - - if (args.Target == null) - return; - - if (!HasComp(args.Target) && !HasComp(args.Target)) - return; - - if (TryComp(args.Target, out var panel) && !panel.Open) - { - _popup.PopupEntity(Loc.GetString("construction-step-condition-wire-panel-open"), - args.Target.Value); - return; - } - - component.AudioStream = _audio.PlayPvs(component.ExchangeSound, uid).Value.Entity; - - _doAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, component.ExchangeDuration, new ExchangerDoAfterEvent(), uid, target: args.Target, used: uid) - { - BreakOnDamage = true, - BreakOnMove = true - }); - } -} diff --git a/Content.Server/Stack/StackSystem.cs b/Content.Server/Stack/StackSystem.cs index e34592b45f9..bac789716ca 100644 --- a/Content.Server/Stack/StackSystem.cs +++ b/Content.Server/Stack/StackSystem.cs @@ -71,6 +71,15 @@ public override void SetCount(EntityUid uid, int amount, StackComponent? compone return entity; } + /// + /// Spawns a stack of a certain stack type. See . + /// + public EntityUid Spawn(int amount, ProtoId id, EntityCoordinates spawnPosition) + { + var proto = _prototypeManager.Index(id); + return Spawn(amount, proto, spawnPosition); + } + /// /// Spawns a stack of a certain stack type. See . /// diff --git a/Content.Shared/Construction/Components/MachineBoardComponent.cs b/Content.Shared/Construction/Components/MachineBoardComponent.cs index dbca3160616..0469b59fd1e 100644 --- a/Content.Shared/Construction/Components/MachineBoardComponent.cs +++ b/Content.Shared/Construction/Components/MachineBoardComponent.cs @@ -1,54 +1,47 @@ -using Content.Shared.Construction.Prototypes; using Content.Shared.Stacks; +using Content.Shared.Tag; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary; -namespace Content.Shared.Construction.Components +namespace Content.Shared.Construction.Components; + +[RegisterComponent, NetworkedComponent] +public sealed partial class MachineBoardComponent : Component +{ + /// + /// The stacks needed to construct this machine + /// + [DataField] + public Dictionary, int> StackRequirements = new(); + + /// + /// Entities needed to construct this machine, discriminated by tag. + /// + [DataField] + public Dictionary, GenericPartInfo> TagRequirements = new(); + + /// + /// Entities needed to construct this machine, discriminated by component. + /// + [DataField] + public Dictionary ComponentRequirements = new(); + + /// + /// The machine that's constructed when this machine board is completed. + /// + [DataField(required: true)] + public EntProtoId Prototype; +} + +[DataDefinition, Serializable] +public partial struct GenericPartInfo { - [RegisterComponent, NetworkedComponent] - public sealed partial class MachineBoardComponent : Component - { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - - [DataField("requirements", customTypeSerializer: typeof(PrototypeIdDictionarySerializer))] - public Dictionary Requirements = new(); - - [DataField("materialRequirements")] - public Dictionary MaterialIdRequirements = new(); - - [DataField("tagRequirements")] - public Dictionary TagRequirements = new(); - - [DataField("componentRequirements")] - public Dictionary ComponentRequirements = new(); - - [ViewVariables(VVAccess.ReadWrite)] - [DataField("prototype")] - public string? Prototype { get; private set; } - - public IEnumerable> MaterialRequirements - { - get - { - foreach (var (materialId, amount) in MaterialIdRequirements) - { - var material = _prototypeManager.Index(materialId); - yield return new KeyValuePair(material, amount); - } - } - } - } - - [Serializable] - [DataDefinition] - public partial struct GenericPartInfo - { - [DataField("Amount")] - public int Amount; - [DataField("ExamineName")] - public string ExamineName; - [DataField("DefaultPrototype")] - public string DefaultPrototype; - } + [DataField(required: true)] + public int Amount; + + [DataField(required: true)] + public EntProtoId DefaultPrototype; + + [DataField] + public LocId? ExamineName; } diff --git a/Content.Shared/Construction/Components/MachinePartComponent.cs b/Content.Shared/Construction/Components/MachinePartComponent.cs deleted file mode 100644 index a68e3495e29..00000000000 --- a/Content.Shared/Construction/Components/MachinePartComponent.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Content.Shared.Construction.Prototypes; -using Robust.Shared.GameStates; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; - -namespace Content.Shared.Construction.Components -{ - [RegisterComponent, NetworkedComponent] - public sealed partial class MachinePartComponent : Component - { - [DataField("part", required: true, customTypeSerializer: typeof(PrototypeIdSerializer))] - public string PartType { get; private set; } = default!; - - [ViewVariables(VVAccess.ReadWrite)] - [DataField("rating")] - public int Rating { get; private set; } = 1; - - /// - /// This number is used in tests to ensure that you can't use high quality machines for arbitrage. In - /// principle there is nothing wrong with using higher quality parts, but you have to be careful to not - /// allow them to be put into a lathe or something like that. - /// - public const int MaxRating = 4; - } -} diff --git a/Content.Shared/Construction/MachinePartSystem.cs b/Content.Shared/Construction/MachinePartSystem.cs index 359b58c8816..f357a395e64 100644 --- a/Content.Shared/Construction/MachinePartSystem.cs +++ b/Content.Shared/Construction/MachinePartSystem.cs @@ -1,10 +1,8 @@ using System.Linq; using Content.Shared.Construction.Components; -using Content.Shared.Construction.Prototypes; using Content.Shared.Examine; using Content.Shared.Lathe; using Content.Shared.Materials; -using Content.Shared.Stacks; using Robust.Shared.Prototypes; namespace Content.Shared.Construction @@ -16,6 +14,7 @@ public sealed class MachinePartSystem : EntitySystem { [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly SharedLatheSystem _lathe = default!; + [Dependency] private readonly SharedConstructionSystem _construction = default!; public override void Initialize() { @@ -31,32 +30,30 @@ private void OnMachineBoardExamined(EntityUid uid, MachineBoardComponent compone using (args.PushGroup(nameof(MachineBoardComponent))) { args.PushMarkup(Loc.GetString("machine-board-component-on-examine-label")); - foreach (var (part, amount) in component.Requirements) + foreach (var (material, amount) in component.StackRequirements) { - args.PushMarkup(Loc.GetString("machine-board-component-required-element-entry-text", - ("amount", amount), - ("requiredElement", Loc.GetString(_prototype.Index(part).Name)))); - } + var stack = _prototype.Index(material); + var name = _prototype.Index(stack.Spawn).Name; - foreach (var (material, amount) in component.MaterialRequirements) - { args.PushMarkup(Loc.GetString("machine-board-component-required-element-entry-text", ("amount", amount), - ("requiredElement", Loc.GetString(material.Name)))); + ("requiredElement", Loc.GetString(name)))); } foreach (var (_, info) in component.ComponentRequirements) { + var examineName = _construction.GetExamineName(info); args.PushMarkup(Loc.GetString("machine-board-component-required-element-entry-text", ("amount", info.Amount), - ("requiredElement", Loc.GetString(info.ExamineName)))); + ("requiredElement", examineName))); } foreach (var (_, info) in component.TagRequirements) { + var examineName = _construction.GetExamineName(info); args.PushMarkup(Loc.GetString("machine-board-component-required-element-entry-text", ("amount", info.Amount), - ("requiredElement", Loc.GetString(info.ExamineName)))); + ("requiredElement", examineName))); } } } @@ -66,30 +63,13 @@ public Dictionary GetMachineBoardMaterialCost(Entity(); - foreach (var (partId, amount) in comp.Requirements) - { - var partProto = _prototype.Index(partId); - - if (!_lathe.TryGetRecipesFromEntity(partProto.StockPartPrototype, out var recipes)) - continue; - - var partRecipe = recipes[0]; - if (recipes.Count > 1) - partRecipe = recipes.MinBy(p => p.RequiredMaterials.Values.Sum()); - - foreach (var (mat, matAmount) in partRecipe!.RequiredMaterials) - { - materials.TryAdd(mat, 0); - materials[mat] += matAmount * amount * coefficient; - } - } - foreach (var (stackId, amount) in comp.MaterialIdRequirements) + foreach (var (stackId, amount) in comp.StackRequirements) { - var stackProto = _prototype.Index(stackId); + var stackProto = _prototype.Index(stackId); var defaultProto = _prototype.Index(stackProto.Spawn); - if (defaultProto.TryGetComponent(out var physComp)) + if (defaultProto.TryGetComponent(out var physComp, EntityManager.ComponentFactory)) { foreach (var (mat, matAmount) in physComp.MaterialComposition) { @@ -130,7 +110,7 @@ public Dictionary GetMachineBoardMaterialCost(Entity(out var physComp)) + defaultProto.TryGetComponent(out var physComp, EntityManager.ComponentFactory)) { foreach (var (mat, matAmount) in physComp.MaterialComposition) { diff --git a/Content.Shared/Construction/Prototypes/MachinePartPrototype.cs b/Content.Shared/Construction/Prototypes/MachinePartPrototype.cs deleted file mode 100644 index 7a080c94a3f..00000000000 --- a/Content.Shared/Construction/Prototypes/MachinePartPrototype.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Robust.Shared.Prototypes; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; - -namespace Content.Shared.Construction.Prototypes; - -/// -/// This is a prototype for categorizing -/// different types of machine parts. -/// -[Prototype("machinePart")] -public sealed partial class MachinePartPrototype : IPrototype -{ - /// - [IdDataField] - public string ID { get; private set; } = default!; - - /// - /// A human-readable name for the machine part type. - /// - [DataField("name")] - public string Name = string.Empty; - - /// - /// A stock part entity based on the machine part. - /// - [DataField("stockPartPrototype", customTypeSerializer: typeof(PrototypeIdSerializer), required: true)] - public string StockPartPrototype = string.Empty; -} diff --git a/Content.Shared/Construction/SharedConstructionSystem.cs b/Content.Shared/Construction/SharedConstructionSystem.cs index 069290d1431..901b2f834d1 100644 --- a/Content.Shared/Construction/SharedConstructionSystem.cs +++ b/Content.Shared/Construction/SharedConstructionSystem.cs @@ -1,5 +1,7 @@ using System.Linq; +using Content.Shared.Construction.Components; using Robust.Shared.Map; +using Robust.Shared.Prototypes; using static Content.Shared.Interaction.SharedInteractionSystem; namespace Content.Shared.Construction @@ -7,6 +9,7 @@ namespace Content.Shared.Construction public abstract class SharedConstructionSystem : EntitySystem { [Dependency] private readonly IMapManager _mapManager = default!; + [Dependency] protected readonly IPrototypeManager PrototypeManager = default!; /// /// Get predicate for construction obstruction checks. @@ -22,5 +25,13 @@ public abstract class SharedConstructionSystem : EntitySystem var ignored = grid.GetAnchoredEntities(coords).ToHashSet(); return e => ignored.Contains(e); } + + public string GetExamineName(GenericPartInfo info) + { + if (info.ExamineName is not null) + return Loc.GetString(info.ExamineName.Value); + + return PrototypeManager.Index(info.DefaultPrototype).Name; + } } } diff --git a/Content.Shared/Construction/SharedFlatpackSystem.cs b/Content.Shared/Construction/SharedFlatpackSystem.cs index 8b21bca52ae..62d2089fb7c 100644 --- a/Content.Shared/Construction/SharedFlatpackSystem.cs +++ b/Content.Shared/Construction/SharedFlatpackSystem.cs @@ -1,4 +1,3 @@ -using System.Numerics; using Content.Shared.Construction.Components; using Content.Shared.Administration.Logs; using Content.Shared.Database; @@ -9,7 +8,6 @@ using Content.Shared.Tools.Systems; using Robust.Shared.Audio.Systems; using Robust.Shared.Containers; -using Robust.Shared.Map; using Robust.Shared.Map.Components; using Robust.Shared.Network; using Robust.Shared.Physics.Components; @@ -88,7 +86,8 @@ private void OnFlatpackInteractUsing(Entity ent, ref Interact if (_net.IsServer) { var spawn = Spawn(comp.Entity, _map.GridTileToLocal(grid, gridComp, buildPos)); - _adminLogger.Add(LogType.Construction, LogImpact.Low, + _adminLogger.Add(LogType.Construction, + LogImpact.Low, $"{ToPrettyString(args.User):player} unpacked {ToPrettyString(spawn):entity} at {xform.Coordinates} from {ToPrettyString(uid):entity}"); QueueDel(uid); } @@ -115,9 +114,7 @@ public void SetupFlatpack(Entity ent, EntityUid? board) return; var machinePrototypeId = new EntProtoId(); - if (TryComp(board, out var machineBoard) && machineBoard.Prototype is not null) - machinePrototypeId = machineBoard.Prototype; - else if (TryComp(board, out var computerBoard) && computerBoard.Prototype is not null) + if (TryComp(board, out var computerBoard) && computerBoard.Prototype is not null) machinePrototypeId = computerBoard.Prototype; var comp = ent.Comp!; diff --git a/Content.Shared/Lathe/LatheComponent.cs b/Content.Shared/Lathe/LatheComponent.cs index d4bf18b0507..88ac8c05bfb 100644 --- a/Content.Shared/Lathe/LatheComponent.cs +++ b/Content.Shared/Lathe/LatheComponent.cs @@ -59,8 +59,6 @@ public sealed partial class LatheComponent : Component /// [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public float MaterialUseMultiplier = 1; - - public const float DefaultPartRatingMaterialUseMultiplier = 0.85f; #endregion } diff --git a/Resources/Locale/en-US/construction/steps/arbitrary-insert-construction-graph-step.ftl b/Resources/Locale/en-US/construction/steps/arbitrary-insert-construction-graph-step.ftl index 6a7998e57a2..430888ed365 100644 --- a/Resources/Locale/en-US/construction/steps/arbitrary-insert-construction-graph-step.ftl +++ b/Resources/Locale/en-US/construction/steps/arbitrary-insert-construction-graph-step.ftl @@ -1,2 +1,10 @@ # Shown when examining an in-construction object -construction-insert-arbitrary-entity = Next, insert {$stepName}. \ No newline at end of file +construction-insert-arbitrary-entity = Next, insert {$stepName}. + +construction-insert-info-examine-name-instrument-brass = brass instrument +construction-insert-info-examine-name-instrument-keyed = keyed instrument +construction-insert-info-examine-name-instrument-percussion = percussion instrument +construction-insert-info-examine-name-instrument-string = string intrument +construction-insert-info-examine-name-instrument-woodwind = woodwind instrument +construction-insert-info-examine-name-knife = knife +construction-insert-info-examine-name-utensil = utensil diff --git a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/cannons.yml b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/cannons.yml index 6db7f4b385e..e4bde7ab84f 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/cannons.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/cannons.yml @@ -11,10 +11,9 @@ state: security - type: MachineBoard prototype: ShuttleGunSvalinnMachineGun - requirements: + stackRequirements: MatterBin: 2 Manipulator: 4 - materialRequirements: Steel: 5 CableHV: 5 @@ -29,10 +28,9 @@ state: security - type: MachineBoard prototype: ShuttleGunPerforator - requirements: + stackRequirements: MatterBin: 4 Manipulator: 6 - materialRequirements: Steel: 10 CableHV: 5 @@ -47,10 +45,9 @@ state: security - type: MachineBoard prototype: ShuttleGunFriendship - requirements: + stackRequirements: MatterBin: 3 Manipulator: 2 - materialRequirements: Steel: 7 CableHV: 5 @@ -65,10 +62,9 @@ state: security - type: MachineBoard prototype: ShuttleGunDuster - requirements: + stackRequirements: MatterBin: 6 Manipulator: 4 - materialRequirements: Steel: 10 CableHV: 5 Uranium: 2 @@ -84,9 +80,8 @@ state: security - type: MachineBoard prototype: ShuttleGunKinetic - requirements: + stackRequirements: MatterBin: 2 Manipulator: 3 - materialRequirements: Steel: 5 - CableHV: 2 \ No newline at end of file + CableHV: 2 diff --git a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/particle_accelerator.yml b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/particle_accelerator.yml index 78e17e07455..a1260f07c0c 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/particle_accelerator.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/particle_accelerator.yml @@ -8,7 +8,7 @@ state: engineering - type: MachineBoard prototype: ParticleAcceleratorEndCapUnfinished - materialRequirements: + stackRequirements: Glass: 15 Steel: 15 @@ -24,10 +24,9 @@ prototype: ParticleAcceleratorFuelChamberUnfinished componentRequirements: AmeFuelContainer: - Amount: 1 - DefaultPrototype: AmeJar - ExamineName: AME Fuel Jar - materialRequirements: + amount: 1 + defaultPrototype: AmeJar + stackRequirements: Glass: 10 Steel: 10 @@ -41,7 +40,7 @@ state: engineering - type: MachineBoard prototype: ParticleAcceleratorPowerBoxUnfinished - materialRequirements: + stackRequirements: Glass: 5 Steel: 5 @@ -57,7 +56,7 @@ state: engineering - type: MachineBoard prototype: ParticleAcceleratorEmitterStarboardUnfinished - materialRequirements: + stackRequirements: Glass: 5 Steel: 5 @@ -71,7 +70,7 @@ state: engineering - type: MachineBoard prototype: ParticleAcceleratorEmitterForeUnfinished - materialRequirements: + stackRequirements: Glass: 5 Steel: 5 @@ -85,6 +84,6 @@ state: engineering - type: MachineBoard prototype: ParticleAcceleratorEmitterPortUnfinished - materialRequirements: + stackRequirements: Glass: 5 Steel: 5 diff --git a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml index 587e56865b4..d41923b569d 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml @@ -6,10 +6,9 @@ components: - type: MachineBoard prototype: Autolathe - requirements: + stackRequirements: MatterBin: 3 Manipulator: 1 - materialRequirements: Glass: 1 - type: entity @@ -20,15 +19,13 @@ components: - type: MachineBoard prototype: AutolatheHyperConvection - requirements: + stackRequirements: MatterBin: 3 - materialRequirements: Glass: 1 tagRequirements: Igniter: - Amount: 1 - DefaultPrototype: Igniter - ExamineName: Igniter + amount: 1 + defaultPrototype: Igniter - type: entity id: ProtolatheMachineCircuitboard @@ -38,14 +35,13 @@ components: - type: MachineBoard prototype: Protolathe - requirements: + stackRequirements: MatterBin: 2 Manipulator: 2 tagRequirements: GlassBeaker: - Amount: 2 - DefaultPrototype: Beaker - ExamineName: Glass Beaker + amount: 2 + defaultPrototype: Beaker - type: entity parent: BaseMachineCircuitboard @@ -55,17 +51,15 @@ components: - type: MachineBoard prototype: ProtolatheHyperConvection - requirements: + stackRequirements: MatterBin: 2 tagRequirements: GlassBeaker: - Amount: 2 - DefaultPrototype: Beaker - ExamineName: Glass Beaker + amount: 2 + defaultPrototype: Beaker Igniter: - Amount: 1 - DefaultPrototype: Igniter - ExamineName: Igniter + amount: 1 + defaultPrototype: Igniter - type: entity id: BiofabricatorMachineCircuitboard @@ -75,9 +69,8 @@ components: - type: MachineBoard prototype: Biofabricator - requirements: + stackRequirements: MatterBin: 4 - materialRequirements: Glass: 1 - type: entity @@ -90,14 +83,13 @@ state: security - type: MachineBoard prototype: SecurityTechFab - requirements: + stackRequirements: MatterBin: 2 Manipulator: 2 tagRequirements: GlassBeaker: - Amount: 2 - DefaultPrototype: Beaker - ExamineName: Glass Beaker + amount: 2 + defaultPrototype: Beaker - type: entity id: AmmoTechFabCircuitboard @@ -109,7 +101,7 @@ state: security - type: MachineBoard prototype: AmmoTechFab - requirements: + stackRequirements: MatterBin: 1 Manipulator: 1 @@ -123,14 +115,13 @@ state: medical - type: MachineBoard prototype: MedicalTechFab - requirements: + stackRequirements: MatterBin: 2 Manipulator: 2 tagRequirements: GlassBeaker: - Amount: 2 - DefaultPrototype: Beaker - ExamineName: Glass Beaker + amount: 2 + defaultPrototype: Beaker - type: StealTarget stealGroup: MedicalTechFabCircuitboard @@ -143,14 +134,13 @@ state: science - type: MachineBoard prototype: CircuitImprinter - requirements: + stackRequirements: MatterBin: 1 Manipulator: 1 tagRequirements: GlassBeaker: - Amount: 2 - DefaultPrototype: Beaker - ExamineName: Glass Beaker + amount: 2 + defaultPrototype: Beaker - type: entity parent: BaseMachineCircuitboard @@ -162,17 +152,15 @@ state: science - type: MachineBoard prototype: CircuitImprinterHyperConvection - requirements: + stackRequirements: MatterBin: 2 tagRequirements: GlassBeaker: - Amount: 2 - DefaultPrototype: Beaker - ExamineName: Glass Beaker + amount: 2 + defaultPrototype: Beaker Igniter: - Amount: 1 - DefaultPrototype: Igniter - ExamineName: Igniter + amount: 1 + defaultPrototype: Igniter - type: entity id: ExosuitFabricatorMachineCircuitboard @@ -183,10 +171,9 @@ state: science - type: MachineBoard prototype: ExosuitFabricator - requirements: + stackRequirements: MatterBin: 1 Manipulator: 3 - materialRequirements: Glass: 5 - type: GuideHelp guides: @@ -203,7 +190,7 @@ state: science - type: MachineBoard prototype: ResearchAndDevelopmentServer - materialRequirements: + stackRequirements: Plasma: 5 - type: entity @@ -213,7 +200,7 @@ components: - type: MachineBoard prototype: UniformPrinter - requirements: + stackRequirements: MatterBin: 1 Manipulator: 2 @@ -226,16 +213,14 @@ state: medical - type: MachineBoard prototype: Vaccinator - requirements: + stackRequirements: MatterBin: 1 Manipulator: 1 - materialRequirements: Cable: 5 tagRequirements: GlassBeaker: - Amount: 1 - DefaultPrototype: Beaker - ExamineName: Glass Beaker + amount: 1 + defaultPrototype: Beaker - type: entity id: DiagnoserMachineCircuitboard @@ -246,18 +231,16 @@ state: medical - type: MachineBoard prototype: DiseaseDiagnoser - materialRequirements: + stackRequirements: Cable: 5 tagRequirements: GlassBeaker: - Amount: 1 - DefaultPrototype: Beaker - ExamineName: Glass Beaker + amount: 1 + defaultPrototype: Beaker componentRequirements: - DiseaseSwab: - Amount: 1 - DefaultPrototype: DiseaseSwab - ExamineName: Swab + BotanySwab: + amount: 1 + defaultPrototype: DiseaseSwab - type: entity id: ArtifactAnalyzerMachineCircuitboard @@ -269,10 +252,9 @@ state: science - type: MachineBoard prototype: MachineArtifactAnalyzer - requirements: + stackRequirements: Manipulator: 3 Capacitor: 1 - materialRequirements: Glass: 5 - type: entity @@ -285,9 +267,8 @@ state: science - type: MachineBoard prototype: MachineArtifactCrusher - requirements: + stackRequirements: Manipulator: 2 - materialRequirements: Glass: 1 Steel: 5 @@ -301,9 +282,8 @@ state: science - type: MachineBoard prototype: MachineAnomalyVessel - requirements: + stackRequirements: Capacitor: 3 - materialRequirements: Cable: 1 PlasmaGlass: 10 @@ -317,9 +297,8 @@ state: science - type: MachineBoard prototype: MachineAnomalyVesselExperimental - requirements: + stackRequirements: Capacitor: 3 - materialRequirements: Cable: 5 PlasmaGlass: 15 MetalRod: 4 @@ -334,10 +313,9 @@ state: science - type: MachineBoard prototype: MachineAnomalySynchronizer - requirements: + stackRequirements: Manipulator: 2 Capacitor: 5 - materialRequirements: PlasmaGlass: 5 Cable: 5 @@ -351,9 +329,8 @@ state: science - type: MachineBoard prototype: MachineAPE - requirements: + stackRequirements: Capacitor: 2 - materialRequirements: Cable: 1 Glass: 1 @@ -367,10 +344,9 @@ state: engineering - type: MachineBoard prototype: GasThermoMachineFreezer - requirements: + stackRequirements: MatterBin: 2 Capacitor: 2 - materialRequirements: Cable: 5 - type: Construction deconstructionTarget: null @@ -387,10 +363,9 @@ state: engineering - type: MachineBoard prototype: GasThermoMachineHeater - requirements: + stackRequirements: MatterBin: 2 Capacitor: 2 - materialRequirements: Cable: 5 - type: Construction graph: ThermomachineBoard @@ -407,10 +382,9 @@ state: engineering - type: MachineBoard prototype: GasThermoMachineHellfireFreezer - requirements: + stackRequirements: MatterBin: 2 Capacitor: 2 - materialRequirements: Plasma: 1 - type: Construction deconstructionTarget: null @@ -427,10 +401,9 @@ state: engineering - type: MachineBoard prototype: GasThermoMachineHellfireHeater - requirements: + stackRequirements: MatterBin: 2 Capacitor: 2 - materialRequirements: Plasma: 1 - type: Construction graph: ThermomachineBoard @@ -447,9 +420,8 @@ state: engineering - type: MachineBoard prototype: BaseGasCondenser - requirements: + stackRequirements: MatterBin: 1 - materialRequirements: Glass: 1 - type: entity @@ -462,10 +434,9 @@ state: engineering - type: MachineBoard prototype: PortableScrubber - requirements: + stackRequirements: MatterBin: 1 Manipulator: 2 - materialRequirements: Cable: 5 Glass: 2 @@ -479,10 +450,9 @@ state: engineering - type: MachineBoard prototype: SpaceHeater - requirements: + stackRequirements: MatterBin: 1 Capacitor: 2 - materialRequirements: Cable: 5 - type: entity @@ -495,10 +465,9 @@ state: medical - type: MachineBoard prototype: CloningPod - requirements: + stackRequirements: MatterBin: 2 Manipulator: 2 - materialRequirements: Glass: 1 Cable: 1 @@ -512,9 +481,8 @@ state: medical - type: MachineBoard prototype: MedicalScanner - requirements: + stackRequirements: Capacitor: 1 - materialRequirements: Glass: 5 Cable: 1 @@ -526,7 +494,7 @@ components: - type: MachineBoard prototype: CrewMonitoringServer - materialRequirements: + stackRequirements: Steel: 1 Cable: 2 @@ -540,7 +508,7 @@ state: medical - type: MachineBoard prototype: CryoPod - materialRequirements: + stackRequirements: Glass: 5 Cable: 1 @@ -554,16 +522,14 @@ state: medical - type: MachineBoard prototype: ChemMaster - requirements: + stackRequirements: Capacitor: 1 - materialRequirements: Glass: 1 Cable: 1 tagRequirements: GlassBeaker: - Amount: 2 - DefaultPrototype: Beaker - ExamineName: Glass Beaker + amount: 2 + defaultPrototype: Beaker - type: entity id: ChemDispenserMachineCircuitboard @@ -575,16 +541,14 @@ state: medical - type: MachineBoard prototype: ChemDispenserEmpty - requirements: + stackRequirements: Capacitor: 1 - materialRequirements: Glass: 1 Steel: 3 tagRequirements: GlassBeaker: - Amount: 2 - DefaultPrototype: Beaker - ExamineName: Glass Beaker + amount: 2 + defaultPrototype: Beaker - type: entity id: BiomassReclaimerMachineCircuitboard @@ -594,16 +558,15 @@ components: - type: MachineBoard prototype: BiomassReclaimer - requirements: + stackRequirements: MatterBin: 2 Manipulator: 1 + Steel: 5 tagRequirements: Knife: - Amount: 2 - DefaultPrototype: KitchenKnife - ExamineName: Knife - materialRequirements: - Steel: 5 + amount: 2 + defaultPrototype: KitchenKnife + examineName: construction-insert-info-examine-name-knife - type: entity id: HydroponicsTrayMachineCircuitboard @@ -615,15 +578,14 @@ state: service - type: MachineBoard prototype: HydroponicsTrayEmpty - materialRequirements: + stackRequirements: # replacing the console screen Glass: 5 Cable: 2 tagRequirements: GlassBeaker: - Amount: 2 - DefaultPrototype: Beaker - ExamineName: Glass Beaker + amount: 2 + defaultPrototype: Beaker - type: entity id: SeedExtractorMachineCircuitboard @@ -635,10 +597,9 @@ state: service - type: MachineBoard prototype: SeedExtractor - requirements: + stackRequirements: Manipulator: 2 Capacitor: 1 - materialRequirements: # replacing the console screen Glass: 1 Cable: 2 @@ -654,11 +615,13 @@ state: power_mod - type: MachineBoard prototype: SMESBasicEmpty - requirements: + stackRequirements: Capacitor: 1 - PowerCell: 4 - materialRequirements: CableHV: 10 + componentRequirements: + PowerCell: + amount: 4 + defaultPrototype: PowerCellSmall - type: entity id: CellRechargerCircuitboard @@ -671,9 +634,8 @@ state: charger_APC - type: MachineBoard prototype: PowerCellRecharger - requirements: + stackRequirements: Capacitor: 2 - materialRequirements: Cable: 5 - type: PhysicalComposition materialComposition: @@ -693,9 +655,8 @@ state: charger_APC - type: MachineBoard prototype: PowerCageRecharger - requirements: + stackRequirements: Capacitor: 4 - materialRequirements: Steel: 5 Cable: 10 - type: PhysicalComposition @@ -716,9 +677,8 @@ state: charger_APC - type: MachineBoard prototype: BorgCharger - requirements: + stackRequirements: Capacitor: 2 - materialRequirements: Cable: 5 - type: PhysicalComposition materialComposition: @@ -738,9 +698,8 @@ state: charger_APC - type: MachineBoard prototype: WeaponCapacitorRecharger - requirements: + stackRequirements: Capacitor: 2 - materialRequirements: CableMV: 5 - type: PhysicalComposition materialComposition: @@ -760,9 +719,8 @@ state: charger_APC - type: MachineBoard prototype: TurboItemRecharger - requirements: + stackRequirements: Capacitor: 2 - materialRequirements: CableMV: 5 - type: PhysicalComposition materialComposition: @@ -777,12 +735,14 @@ components: - type: MachineBoard prototype: SubstationBasicEmpty - requirements: + stackRequirements: Capacitor: 1 - PowerCell: 1 - materialRequirements: CableMV: 5 CableHV: 5 + componentRequirements: + PowerCell: + amount: 1 + defaultPrototype: PowerCellSmall - type: PhysicalComposition materialComposition: Glass: 200 @@ -798,31 +758,31 @@ components: - type: MachineBoard prototype: DawInstrument - materialRequirements: + stackRequirements: Glass: 1 Cable: 1 tagRequirements: # One instrument to bring them all and in the darkness bind them... KeyedInstrument: - Amount: 1 - DefaultPrototype: SynthesizerInstrument - ExamineName: Keyed Instrument + amount: 1 + defaultPrototype: SynthesizerInstrument + examineName: construction-insert-info-examine-name-instrument-keyed StringInstrument: - Amount: 1 - DefaultPrototype: AcousticGuitarInstrument - ExamineName: String Instrument + amount: 1 + defaultPrototype: AcousticGuitarInstrument + examineName: construction-insert-info-examine-name-instrument-string PercussionInstrument: - Amount: 1 - DefaultPrototype: GlockenspielInstrument - ExamineName: Percussion Instrument + amount: 1 + defaultPrototype: GlockenspielInstrument + examineName: construction-insert-info-examine-name-instrument-percussion BrassInstrument: - Amount: 1 - DefaultPrototype: TrumpetInstrument - ExamineName: Brass Instrument + amount: 1 + defaultPrototype: TrumpetInstrument + examineName: construction-insert-info-examine-name-instrument-brass WoodwindInstrument: - Amount: 1 - DefaultPrototype: SaxophoneInstrument - ExamineName: Woodwind Instrument + amount: 1 + defaultPrototype: SaxophoneInstrument + examineName: construction-insert-info-examine-name-instrument-woodwind - type: entity id: PortableGeneratorPacmanMachineCircuitboard @@ -833,9 +793,8 @@ state: engineering - type: MachineBoard prototype: PortableGeneratorPacman - requirements: + stackRequirements: Capacitor: 1 - materialRequirements: CableHV: 5 - type: PhysicalComposition materialComposition: @@ -852,9 +811,8 @@ components: - type: MachineBoard prototype: Thruster - requirements: + stackRequirements: Capacitor: 4 - materialRequirements: Steel: 5 - type: entity @@ -864,10 +822,9 @@ components: - type: MachineBoard prototype: Gyroscope - requirements: + stackRequirements: Manipulator: 2 Capacitor: 1 - materialRequirements: Glass: 2 - type: entity @@ -879,9 +836,8 @@ state: engineering - type: MachineBoard prototype: PortableGeneratorSuperPacman - requirements: + stackRequirements: Capacitor: 2 - materialRequirements: CableHV: 10 - type: PhysicalComposition materialComposition: @@ -900,9 +856,8 @@ state: engineering - type: MachineBoard prototype: PortableGeneratorJrPacman - requirements: + stackRequirements: Capacitor: 1 - materialRequirements: Cable: 10 - type: PhysicalComposition materialComposition: @@ -920,14 +875,13 @@ components: - type: MachineBoard prototype: KitchenReagentGrinder - requirements: + stackRequirements: MatterBin: 2 Manipulator: 2 tagRequirements: GlassBeaker: - Amount: 1 - DefaultPrototype: Beaker - ExamineName: Glass Beaker + amount: 1 + defaultPrototype: Beaker - type: entity id: HotplateMachineCircuitboard @@ -937,9 +891,8 @@ components: - type: MachineBoard prototype: ChemistryHotplate - requirements: + stackRequirements: Capacitor: 2 - materialRequirements: Glass: 1 - type: entity @@ -950,9 +903,8 @@ components: - type: MachineBoard prototype: KitchenElectricGrill - requirements: + stackRequirements: Capacitor: 4 - materialRequirements: Glass: 2 Cable: 5 @@ -965,10 +917,9 @@ state: medical - type: MachineBoard prototype: StasisBed - requirements: + stackRequirements: Capacitor: 1 Manipulator: 1 - materialRequirements: Cable: 3 Steel: 2 @@ -982,9 +933,8 @@ state: medical - type: MachineBoard prototype: MachineElectrolysisUnit - requirements: + stackRequirements: Capacitor: 2 - materialRequirements: Cable: 1 - type: entity @@ -997,9 +947,8 @@ state: medical - type: MachineBoard prototype: MachineCentrifuge - requirements: + stackRequirements: Manipulator: 1 - materialRequirements: Steel: 1 - type: entity @@ -1011,9 +960,8 @@ state: supply - type: MachineBoard prototype: MaterialReclaimer - requirements: + stackRequirements: Manipulator: 2 - materialRequirements: Steel: 5 Plastic: 5 @@ -1026,10 +974,9 @@ state: supply - type: MachineBoard prototype: OreProcessor - requirements: + stackRequirements: MatterBin: 1 Manipulator: 3 - materialRequirements: Glass: 1 - type: entity @@ -1041,10 +988,9 @@ state: supply - type: MachineBoard prototype: OreProcessorIndustrial - requirements: + stackRequirements: MatterBin: 1 Manipulator: 3 - materialRequirements: Glass: 1 - type: entity @@ -1054,7 +1000,7 @@ components: - type: MachineBoard prototype: Sheetifier - requirements: + stackRequirements: MatterBin: 1 Manipulator: 1 @@ -1067,9 +1013,8 @@ state: service - type: MachineBoard prototype: KitchenMicrowave - requirements: + stackRequirements: Capacitor: 1 - materialRequirements: Glass: 2 Cable: 2 - type: Tag @@ -1085,13 +1030,13 @@ state: service - type: MachineBoard prototype: FatExtractor - requirements: + stackRequirements: Manipulator: 1 componentRequirements: Utensil: - Amount: 1 - DefaultPrototype: ForkPlastic - ExamineName: Utensil + amount: 1 + defaultPrototype: ForkPlastic + examineName: construction-insert-info-examine-name-utensil - type: entity parent: BaseMachineCircuitboard @@ -1100,10 +1045,9 @@ components: - type: MachineBoard prototype: MachineFlatpacker - requirements: + stackRequirements: Manipulator: 2 MatterBin: 1 - materialRequirements: Steel: 1 - type: entity @@ -1115,9 +1059,8 @@ state: engineering - type: MachineBoard prototype: Emitter - requirements: + stackRequirements: Capacitor: 2 - materialRequirements: CableHV: 5 Glass: 2 @@ -1129,7 +1072,7 @@ components: - type: MachineBoard prototype: SurveillanceCameraRouterConstructed - materialRequirements: + stackRequirements: Cable: 1 - type: entity @@ -1140,7 +1083,7 @@ components: - type: MachineBoard prototype: SurveillanceCameraWirelessRouterConstructed - materialRequirements: + stackRequirements: Cable: 2 Glass: 1 @@ -1152,7 +1095,7 @@ components: - type: MachineBoard prototype: SurveillanceWirelessCameraMovableConstructed - materialRequirements: + stackRequirements: Glass: 2 Cable: 2 @@ -1164,7 +1107,7 @@ components: - type: MachineBoard prototype: SurveillanceWirelessCameraAnchoredConstructed - materialRequirements: + stackRequirements: Cable: 2 Glass: 1 @@ -1176,10 +1119,9 @@ components: - type: MachineBoard prototype: GasRecycler - requirements: + stackRequirements: Capacitor: 1 Manipulator: 1 - materialRequirements: Steel: 10 Plasma: 5 @@ -1193,13 +1135,12 @@ state: service - type: MachineBoard prototype: BoozeDispenserEmpty - materialRequirements: + stackRequirements: Steel: 5 tagRequirements: GlassBeaker: - Amount: 1 - DefaultPrototype: Beaker - ExamineName: Glass Beaker + amount: 1 + defaultPrototype: Beaker - type: entity id: CargoTelepadMachineCircuitboard @@ -1211,9 +1152,8 @@ state: supply - type: MachineBoard prototype: CargoTelepad - requirements: + stackRequirements: Capacitor: 2 - materialRequirements: Steel: 5 - type: entity @@ -1226,13 +1166,12 @@ state: service - type: MachineBoard prototype: SodaDispenserEmpty - materialRequirements: + stackRequirements: Steel: 5 tagRequirements: GlassBeaker: - Amount: 1 - DefaultPrototype: Beaker - ExamineName: Glass Beaker + amount: 1 + defaultPrototype: Beaker - type: entity id: TelecomServerCircuitboard @@ -1242,7 +1181,7 @@ components: - type: MachineBoard prototype: TelecomServer - materialRequirements: + stackRequirements: Steel: 1 Cable: 2 @@ -1254,9 +1193,8 @@ components: - type: MachineBoard prototype: SalvageMagnet - requirements: + stackRequirements: Capacitor: 4 - materialRequirements: Steel: 5 CableHV: 5 Cable: 2 @@ -1269,10 +1207,9 @@ components: - type: MachineBoard prototype: GravityGeneratorMini - requirements: + stackRequirements: Capacitor: 4 MatterBin: 3 - materialRequirements: Steel: 5 CableHV: 5 Uranium: 2 @@ -1284,10 +1221,9 @@ components: - type: MachineBoard prototype: ReagentGrinderIndustrial - requirements: + stackRequirements: MatterBin: 1 Manipulator: 3 - materialRequirements: Glass: 1 - type: entity @@ -1298,7 +1234,7 @@ components: - type: MachineBoard prototype: Jukebox - materialRequirements: + stackRequirements: WoodPlank: 5 Steel: 2 Glass: 5 diff --git a/Resources/Prototypes/Entities/Objects/Misc/machine_parts.yml b/Resources/Prototypes/Entities/Objects/Misc/machine_parts.yml index 37de294cce8..2f257db3965 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/machine_parts.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/machine_parts.yml @@ -21,9 +21,6 @@ components: - type: Sprite state: capacitor - - type: MachinePart - part: Capacitor - rating: 1 - type: Tag tags: - CapacitorStockPart @@ -39,11 +36,8 @@ components: - type: Sprite state: micro_mani - - type: MachinePart - part: Manipulator - rating: 1 - type: Stack - stackType: MicroManipulator + stackType: Manipulator - type: entity id: MatterBinStockPart @@ -54,8 +48,5 @@ components: - type: Sprite state: matter_bin - - type: MachinePart - part: MatterBin - rating: 1 - type: Stack stackType: MatterBin diff --git a/Resources/Prototypes/Entities/Objects/Power/powercells.yml b/Resources/Prototypes/Entities/Objects/Power/powercells.yml index 7397bcaa517..90f987fdc69 100644 --- a/Resources/Prototypes/Entities/Objects/Power/powercells.yml +++ b/Resources/Prototypes/Entities/Objects/Power/powercells.yml @@ -73,9 +73,6 @@ - type: Battery maxCharge: 360 startingCharge: 360 - - type: MachinePart - part: PowerCell - rating: 1 - type: Tag tags: - PowerCellSmall @@ -114,9 +111,6 @@ - type: Battery maxCharge: 720 startingCharge: 720 - - type: MachinePart - part: PowerCell - rating: 2 - type: entity id: PowerCellMediumPrinted @@ -152,9 +146,6 @@ - type: Battery maxCharge: 1080 startingCharge: 1080 - - type: MachinePart - part: PowerCell - rating: 3 - type: entity id: PowerCellHighPrinted @@ -190,9 +181,6 @@ - type: Battery maxCharge: 1800 startingCharge: 1800 - - type: MachinePart - part: PowerCell - rating: 4 - type: entity id: PowerCellHyperPrinted diff --git a/Resources/Prototypes/MachineParts/machine_parts.yml b/Resources/Prototypes/MachineParts/machine_parts.yml deleted file mode 100644 index 317e4b80866..00000000000 --- a/Resources/Prototypes/MachineParts/machine_parts.yml +++ /dev/null @@ -1,20 +0,0 @@ -- type: machinePart - id: Capacitor - name: machine-part-name-capacitor - stockPartPrototype: CapacitorStockPart - -- type: machinePart - id: Manipulator - name: machine-part-name-manipulator - stockPartPrototype: MicroManipulatorStockPart - -- type: machinePart - id: MatterBin - name: machine-part-name-matter-bin - stockPartPrototype: MatterBinStockPart - -- type: machinePart - id: PowerCell - name: machine-part-name-power-cell - stockPartPrototype: PowerCellSmall - diff --git a/Resources/Prototypes/Stacks/science_stacks.yml b/Resources/Prototypes/Stacks/science_stacks.yml index bf58fad9154..0d273c324e6 100644 --- a/Resources/Prototypes/Stacks/science_stacks.yml +++ b/Resources/Prototypes/Stacks/science_stacks.yml @@ -11,7 +11,7 @@ maxCount: 10 - type: stack - id: MicroManipulator + id: Manipulator name: micro manipulator spawn: MicroManipulatorStockPart maxCount: 10 From c368d5d36f4cf086fc39f026acca762dbfe9b4f8 Mon Sep 17 00:00:00 2001 From: Cojoke <83733158+Cojoke-dot@users.noreply.github.com> Date: Wed, 5 Jun 2024 15:47:27 -0500 Subject: [PATCH 08/55] Make Projectiles Only Hit a Variety of Station Objects Unless Clicked on (#28571) --- .../Fun/Instruments/base_instruments.yml | 3 ++- .../Dispensers/base_structuredispensers.yml | 2 +- .../Computers/base_structurecomputers.yml | 1 + .../Machines/Medical/chemistry_machines.yml | 2 +- .../Machines/Medical/disease_diagnoser.yml | 4 +--- .../Machines/Medical/vaccinator.yml | 1 + .../Structures/Machines/artifact_analyzer.yml | 3 ++- .../Machines/base_structuremachines.yml | 7 +++++++ .../Structures/Machines/fax_machine.yml | 1 + .../Entities/Structures/Machines/lathe.yml | 1 + .../Structures/Machines/microwave.yml | 4 ++-- .../Structures/Machines/reagent_grinder.yml | 2 +- .../Machines/wireless_surveillance_camera.yml | 4 +++- .../Piping/Atmospherics/portable.yml | 2 +- .../Structures/Piping/Atmospherics/unary.yml | 2 +- .../Structures/Piping/Disposal/units.yml | 1 + .../Power/Generation/Singularity/emitter.yml | 2 +- .../Power/Generation/portable_generator.yml | 4 ++-- .../Structures/Power/Generation/solar.yml | 3 +++ .../Entities/Structures/Power/chargers.yml | 3 +++ .../Structures/Storage/filing_cabinets.yml | 1 + .../Entities/Structures/Walls/fence_wood.yml | 19 +++++++++++++++++-- .../Entities/Structures/hydro_tray.yml | 4 +++- 23 files changed, 57 insertions(+), 19 deletions(-) diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/base_instruments.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/base_instruments.yml index 122ff42eb20..614af2a4886 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/base_instruments.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/base_instruments.yml @@ -1,4 +1,4 @@ -- type: entity +- type: entity abstract: true parent: BaseItem id: BaseHandheldInstrument @@ -71,6 +71,7 @@ - BulletImpassable - type: StaticPrice price: 300 + - type: RequireProjectileTarget - type: entity parent: BasePlaceableInstrument diff --git a/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml b/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml index 082f5e07992..213ad47d88f 100644 --- a/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml +++ b/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml @@ -1,7 +1,7 @@ - type: entity abstract: true id: ReagentDispenserBase - parent: ConstructibleMachine + parent: SmallConstructibleMachine placement: mode: SnapgridCenter components: diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/base_structurecomputers.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/base_structurecomputers.yml index a5e26463b99..204e06c8600 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Computers/base_structurecomputers.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/base_structurecomputers.yml @@ -60,3 +60,4 @@ ents: [] - type: LightningTarget priority: 1 + - type: RequireProjectileTarget diff --git a/Resources/Prototypes/Entities/Structures/Machines/Medical/chemistry_machines.yml b/Resources/Prototypes/Entities/Structures/Machines/Medical/chemistry_machines.yml index 23789730d0c..65eaf04d78f 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Medical/chemistry_machines.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Medical/chemistry_machines.yml @@ -1,6 +1,6 @@ - type: entity id: BaseTabletopChemicalMachine - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, SmallConstructibleMachine ] abstract: true components: - type: Transform diff --git a/Resources/Prototypes/Entities/Structures/Machines/Medical/disease_diagnoser.yml b/Resources/Prototypes/Entities/Structures/Machines/Medical/disease_diagnoser.yml index e46c62053a9..ad98f47e36a 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Medical/disease_diagnoser.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Medical/disease_diagnoser.yml @@ -1,6 +1,6 @@ - type: entity id: DiseaseDiagnoser - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, SmallConstructibleMachine ] name: Disease Diagnoser Delta Extreme description: A machine that analyzes disease samples. placement: @@ -43,5 +43,3 @@ contentMargin: 12.0, 0.0, 12.0, 0.0 # This is a narrow piece of paper maxWritableArea: 128.0, 0.0 - - diff --git a/Resources/Prototypes/Entities/Structures/Machines/Medical/vaccinator.yml b/Resources/Prototypes/Entities/Structures/Machines/Medical/vaccinator.yml index 041bca7c905..53542cdfa91 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Medical/vaccinator.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Medical/vaccinator.yml @@ -24,3 +24,4 @@ containers: machine_board: !type:Container machine_parts: !type:Container + - type: RequireProjectileTarget diff --git a/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml b/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml index 8b0c5787631..9c878c7e7c5 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml @@ -1,6 +1,6 @@ - type: entity id: MachineArtifactAnalyzer - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, SmallConstructibleMachine ] name: artifact analyzer description: A platform capable of performing analysis on various types of artifacts. components: @@ -35,6 +35,7 @@ - Impassable - MidImpassable - LowImpassable + - BulletImpassable hard: False - type: Transform anchored: true diff --git a/Resources/Prototypes/Entities/Structures/Machines/base_structuremachines.yml b/Resources/Prototypes/Entities/Structures/Machines/base_structuremachines.yml index 621d9a1a7ec..fb5ed4440a9 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/base_structuremachines.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/base_structuremachines.yml @@ -70,3 +70,10 @@ - machine_board - type: LightningTarget priority: 1 + +- type: entity + abstract: true + parent: ConstructibleMachine + id: SmallConstructibleMachine + components: + - type: RequireProjectileTarget diff --git a/Resources/Prototypes/Entities/Structures/Machines/fax_machine.yml b/Resources/Prototypes/Entities/Structures/Machines/fax_machine.yml index 36be6451d20..849c9fa4f2d 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/fax_machine.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/fax_machine.yml @@ -66,6 +66,7 @@ deviceNetId: Wireless receiveFrequencyId: Fax transmitFrequencyId: Fax + - type: RequireProjectileTarget # Special - type: entity diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 575144a2c22..537c42346ea 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -508,6 +508,7 @@ - Sheet - RawMaterial - Ingot + - type: RequireProjectileTarget - type: entity id: CircuitImprinterHyperConvection diff --git a/Resources/Prototypes/Entities/Structures/Machines/microwave.yml b/Resources/Prototypes/Entities/Structures/Machines/microwave.yml index fe4eb145183..994269f71b4 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/microwave.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/microwave.yml @@ -1,6 +1,6 @@ -- type: entity +- type: entity id: KitchenMicrowave - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, SmallConstructibleMachine ] name: microwave description: It's magic. components: diff --git a/Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml b/Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml index d6e73333133..28aa464d210 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml @@ -1,6 +1,6 @@ - type: entity id: KitchenReagentGrinder - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, SmallConstructibleMachine ] name: reagent grinder description: From BlenderTech. Will It Blend? Let's find out! suffix: grinder/juicer diff --git a/Resources/Prototypes/Entities/Structures/Machines/wireless_surveillance_camera.yml b/Resources/Prototypes/Entities/Structures/Machines/wireless_surveillance_camera.yml index fc8f31535cd..95079b5c858 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/wireless_surveillance_camera.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/wireless_surveillance_camera.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: [ BaseStructureDynamic, ConstructibleMachine ] + parent: [ BaseStructureDynamic, SmallConstructibleMachine ] id: SurveillanceWirelessCameraBase name: wireless camera description: A camera. It's watching you. Kinda. @@ -23,6 +23,8 @@ density: 80 mask: - MachineMask + layer: + - BulletImpassable - type: SurveillanceCameraMicrophone blacklist: components: diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/portable.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/portable.yml index 200df727b3b..87e71400f73 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/portable.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/portable.yml @@ -1,6 +1,6 @@ - type: entity id: PortableScrubber - parent: [BaseMachinePowered, ConstructibleMachine, StructureWheeled] + parent: [BaseMachinePowered, SmallConstructibleMachine, StructureWheeled] name: portable scrubber description: It scrubs, portably! components: diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml index d301f43c788..2b00fec246f 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml @@ -383,7 +383,7 @@ board: HellfireHeaterMachineCircuitBoard - type: entity - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, SmallConstructibleMachine ] id: BaseGasCondenser name: condenser description: Condenses gases into liquids. Now we just need some plumbing. diff --git a/Resources/Prototypes/Entities/Structures/Piping/Disposal/units.yml b/Resources/Prototypes/Entities/Structures/Piping/Disposal/units.yml index 2198c854a01..e7d3d3c9977 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Disposal/units.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Disposal/units.yml @@ -84,6 +84,7 @@ enum.DisposalUnitUiKey.Key: type: DisposalUnitBoundUserInterface - type: RatKingRummageable + - type: RequireProjectileTarget - type: entity id: MailingUnit diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml index b999b2bdede..6946dcbf835 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml @@ -1,7 +1,7 @@ - type: entity id: Emitter name: emitter - parent: ConstructibleMachine + parent: SmallConstructibleMachine description: A heavy duty industrial laser. Shoots non-stop when turned on. placement: mode: SnapgridCenter diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml index d735d9607c3..86cfb0f7991 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml @@ -1,4 +1,4 @@ -# +# # You can use this Desmos sheet to calculate fuel burn rate values: # https://www.desmos.com/calculator/qcektq5dqs # @@ -6,7 +6,7 @@ - type: entity abstract: true id: PortableGeneratorBase - parent: [ BaseMachine, ConstructibleMachine, StructureWheeled] + parent: [ BaseMachine, SmallConstructibleMachine, StructureWheeled] components: # Basic properties - type: Transform diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/solar.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/solar.yml index 5a28c4962c1..c512266e974 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/solar.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/solar.yml @@ -49,6 +49,7 @@ onBump: false requirePower: true highVoltageNode: output + - type: RequireProjectileTarget - type: entity id: SolarPanel @@ -157,6 +158,7 @@ graph: SolarPanel node: solarassembly defaultTarget: solarpanel + - type: RequireProjectileTarget - type: entity id: SolarTracker @@ -201,3 +203,4 @@ - type: Construction graph: SolarPanel node: solartracker + - type: RequireProjectileTarget diff --git a/Resources/Prototypes/Entities/Structures/Power/chargers.yml b/Resources/Prototypes/Entities/Structures/Power/chargers.yml index 582a5b0dee4..f5f0748b819 100644 --- a/Resources/Prototypes/Entities/Structures/Power/chargers.yml +++ b/Resources/Prototypes/Entities/Structures/Power/chargers.yml @@ -58,12 +58,15 @@ density: 500 mask: - TabletopMachineMask + layer: + - BulletImpassable - type: PowerChargerVisuals - type: ContainerContainer containers: charger_slot: !type:ContainerSlot machine_board: !type:Container machine_parts: !type:Container + - type: RequireProjectileTarget - type: entity parent: BaseItemRecharger diff --git a/Resources/Prototypes/Entities/Structures/Storage/filing_cabinets.yml b/Resources/Prototypes/Entities/Structures/Storage/filing_cabinets.yml index 08db462be01..cfda95fc2f9 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/filing_cabinets.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/filing_cabinets.yml @@ -156,6 +156,7 @@ node: chestDrawer - type: StaticPrice price: 15 + - type: RequireProjectileTarget - type: entity abstract: true diff --git a/Resources/Prototypes/Entities/Structures/Walls/fence_wood.yml b/Resources/Prototypes/Entities/Structures/Walls/fence_wood.yml index 55b7e40803b..41dbe21d5f1 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/fence_wood.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/fence_wood.yml @@ -72,7 +72,7 @@ acts: [ "Destruction" ] - type: Climbable delay: 2.5 - + - type: RequireProjectileTarget #High - type: entity @@ -96,8 +96,10 @@ mask: - FullTileMask layer: + - Opaque - MidImpassable - LowImpassable + - BulletImpassable - type: Construction graph: FenceWood node: straight @@ -123,8 +125,10 @@ mask: - FullTileMask layer: + - Opaque - MidImpassable - LowImpassable + - BulletImpassable - type: Construction graph: FenceWood node: end @@ -159,8 +163,10 @@ mask: - TableMask layer: + - Opaque - MidImpassable - LowImpassable + - BulletImpassable - type: Construction graph: FenceWood node: corner @@ -195,8 +201,10 @@ mask: - TableMask layer: + - Opaque - MidImpassable - LowImpassable + - BulletImpassable - type: Construction graph: FenceWood node: tjunction @@ -221,8 +229,10 @@ mask: - FullTileMask layer: + - Opaque - MidImpassable - LowImpassable + - BulletImpassable - type: InteractionOutline - type: Door openSpriteState: door_opened @@ -271,6 +281,7 @@ layer: - MidImpassable - LowImpassable + - BulletImpassable - type: Construction graph: FenceWood node: straight_small @@ -298,6 +309,7 @@ layer: - MidImpassable - LowImpassable + - BulletImpassable - type: Construction graph: FenceWood node: end_small @@ -334,6 +346,7 @@ layer: - MidImpassable - LowImpassable + - BulletImpassable - type: Construction graph: FenceWood node: corner_small @@ -370,6 +383,7 @@ layer: - MidImpassable - LowImpassable + - BulletImpassable - type: Construction graph: FenceWood node: tjunction_small @@ -396,6 +410,7 @@ layer: - MidImpassable - LowImpassable + - BulletImpassable - type: InteractionOutline - type: Door openSpriteState: door_opened_small @@ -418,4 +433,4 @@ path: /Audio/Effects/door_close.ogg - type: Construction graph: FenceWood - node: gate_small \ No newline at end of file + node: gate_small diff --git a/Resources/Prototypes/Entities/Structures/hydro_tray.yml b/Resources/Prototypes/Entities/Structures/hydro_tray.yml index 8ea7172d8b4..68a0cbd38e4 100644 --- a/Resources/Prototypes/Entities/Structures/hydro_tray.yml +++ b/Resources/Prototypes/Entities/Structures/hydro_tray.yml @@ -1,6 +1,6 @@ - type: entity name: hydroponics tray - parent: [ hydroponicsSoil, ConstructibleMachine] + parent: [ hydroponicsSoil, SmallConstructibleMachine] id: hydroponicsTray description: An interstellar-grade space farmplot allowing for rapid growth and selective breeding of crops. Just... keep in mind the space weeds. components: @@ -14,6 +14,8 @@ hard: true mask: - MachineMask + layer: + - BulletImpassable - type: Anchorable - type: Pullable - type: Sprite From a710c7580918123bf0e30583c411852cad80f30b Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 5 Jun 2024 20:48:33 +0000 Subject: [PATCH 09/55] Automatic changelog update --- Resources/Changelog/Changelog.yml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index e68ab9517d3..6adbf16221d 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,13 +1,4 @@ Entries: -- author: potato1234x - changes: - - message: Added crafting recipes for wall lockers and secure lockers - type: Add - - message: Fixed secure lockers and wall lockers not being deconstructible - type: Fix - id: 6185 - time: '2024-03-18T20:53:13.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/24942 - author: brainfood1183 changes: - message: Added Spray Paints. @@ -3849,3 +3840,11 @@ id: 6684 time: '2024-06-05T20:14:56.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/28576 +- author: Cojoke-dot + changes: + - message: A variety of objects around the station now need to be clicked on in + order for bullets to hit them. + type: Tweak + id: 6685 + time: '2024-06-05T20:47:28.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/28571 From 513023a9f0f5b899af20ad96751bb855c5252ebc Mon Sep 17 00:00:00 2001 From: DrSmugleaf <10968691+DrSmugleaf@users.noreply.github.com> Date: Wed, 5 Jun 2024 14:06:24 -0700 Subject: [PATCH 10/55] Fix Smoke-grenade.ogg not being mono (#28593) --- Resources/Audio/Effects/Smoke-grenade.ogg | Bin 98191 -> 93809 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Resources/Audio/Effects/Smoke-grenade.ogg b/Resources/Audio/Effects/Smoke-grenade.ogg index c697214c2a571e1b6cc900b51c284fb073b8625c..945290ede54be1e189c4d05b32e8dd09bc5e2379 100644 GIT binary patch literal 93809 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

;E4dzooTn~OAhh>Ou*Ov+%=UA{n!z{P} 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

=Qb~! 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 literal 98191 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

i(GW1h<} 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
eGzdw3onk5@dGzMCb~AEszid(?G;!V}u1 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 From f223931ed3a723641e7dddf93bc09a83895b162b Mon Sep 17 00:00:00 2001 From: Ps3Moira <113228053+ps3moira@users.noreply.github.com> Date: Wed, 5 Jun 2024 14:16:32 -0700 Subject: [PATCH 11/55] Fix Cigars Sprites + YAML fix for Inhand unlit cigars/cigs (#28641) --- .../Smokeables/Cigarettes/cigarette.yml | 2 ++ .../Consumable/Smokeables/Cigars/cigar.yml | 2 ++ .../Cigars/cigar-gold.rsi/lit-inhand-left.png | Bin 769 -> 1374 bytes .../Cigars/cigar-gold.rsi/lit-inhand-right.png | Bin 542 -> 1220 bytes .../cigar-gold.rsi/unlit-inhand-left.png | Bin 246 -> 306 bytes .../cigar-gold.rsi/unlit-inhand-right.png | Bin 263 -> 335 bytes .../Cigars/cigar.rsi/lit-inhand-left.png | Bin 769 -> 1374 bytes .../Cigars/cigar.rsi/lit-inhand-right.png | Bin 542 -> 1220 bytes .../Cigars/cigar.rsi/unlit-inhand-left.png | Bin 246 -> 306 bytes .../Cigars/cigar.rsi/unlit-inhand-right.png | Bin 263 -> 335 bytes 10 files changed, 4 insertions(+) diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cigarette.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cigarette.yml index f811afafba1..146fac039d0 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cigarette.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cigarette.yml @@ -18,6 +18,8 @@ equippedPrefix: unlit - type: Item size: Tiny + sprite: Objects/Consumable/Smokeables/Cigarettes/cigarette.rsi + heldPrefix: unlit - type: Construction graph: smokeableCigarette node: cigarette diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/cigar.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/cigar.yml index dc8d4eaf3c4..93419993dc0 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/cigar.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/cigar.yml @@ -20,6 +20,8 @@ equippedPrefix: unlit - type: Item size: Tiny + sprite: Objects/Consumable/Smokeables/Cigars/cigar.rsi + heldPrefix: unlit - type: entity id: CigarSpent diff --git a/Resources/Textures/Objects/Consumable/Smokeables/Cigars/cigar-gold.rsi/lit-inhand-left.png b/Resources/Textures/Objects/Consumable/Smokeables/Cigars/cigar-gold.rsi/lit-inhand-left.png index 353efa3f395a6167f2bcc1f68b75b1b6b2f5c950..c08f70d091d56f6538f7c3f7322d9d692c5a5fed 100644 GIT binary patch literal 1374 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE4M+yv$zcaljKx9jP7LeL$-HD>V3qK6aSW-L z^Y*S`k#IP}@rT=IPPr2Dkl{#)jKjMbJC-WPI6r>K!s9$s+hXN{uRc~a47+A5X;-uT zyNtp6(8bH^mc(YB{r_7lWyAe-7yMUG-THni6VL`^Abj=BZ{}N<*8Tl;)Bo%v{kZ$u zPoKOmd%tm8;kSg;Kl8mUe-{7vxPINbRrTLr{d`&U=lRk(du$&4+pqQX$<2@7{(t&= zIq2Pf%UA#Gf0h1CuHC|r72npJ?Ukv;|5cuEkEVeplfo>94mE~FoDCUBOnbR%=DwAg ze7|o0Y~7aIZ)NA*$KWE&aFNBqgi*kk1m;_V*UU22b$@iPv+t<8vE}pm)3>M3zgC~0 zd+M#8x%koW=V3>zUtr-3{-8nSbAF|6RnQ5cP%2Q0Cg(^xv8_eP;wwf&s}8T+Cayyp?X( z&)=5be_t=}`m=U>TU*)G#m8pI|J&v(KK1@Q`Tv__D(e27`o-YvBfYOm^3etHCI3HN zo-Y6ISDa@5Kgs7=-)~P3T=(v9(x3IO9ly-9NO-&dMYVgssj*}9t&7jk<+hkjJEa29qyuG}$nQna9vDP*$R^a44 z7MpwA(*P7<`i&B<>&=7I3RXSfKt!Kffz%C%!*lz5k@$p>1zY0X=_@Ej9gW zzm3fQ&b{XD;8YREv~hB+e*^#8vO{l?^y5tlJn4(%TkkFT{*|FN?Uz;cg_@c3|5j?M z>u;YOy#GAwrP$jWB>snLs-NF=eE+UpQNO>IzLv|`{D1oU`O}L2pFJne_O57S#buMz zKR;T3t6y_6`}@!T@+H9FVgB-SUflnTj#kNCJc0)T!nQvRNG{8DKWi?&?9QLU!`n@l zN~$z?#tCfBo4zlv|10CRf-~%YR~;=gv3-7Lzq9ya|5k<{b!)1(y{`xoU}&Cw%KL=f zHT_BDExq%8$sXPQ>l~*^>&^RSAI&sC!SQ~)S=hyzSjTu?5X{k`M2iH-ZayDsejagA{&hU z9Y1`|y&f$uJUsq?apv>qr*9{}tdpJn%o%fgm- z$*42@IM&y1uiuE7tHEj5>?gyqnACz-+7g>uUmf~7+uqaQCqse{uJnzqbbzTXUB@3# p49wi8jn4h~5F9HHE4OAW`p+=+u=8Bk{cnRoVxF#kF6*2UngE@xakKyc literal 769 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE4M+yv$zf+;U^?OH;uumf=j~m?ERjTshKKbk zOP5B>yeDDJpYUo+*(~OY#s`8b5mjt!x9~>1W7KJ8zo2}he~Dq2q~e;{y_NIZQxns= z^8ekfOkDjJXdDW-6LQ(=yJ`Q=OP|~Mm(3TycSkn)|LHx~=B&25^EdV1V#9Cte}Dg6 zeKqUjt&r=UHAWE_tWP!%8WX5+p^8)?w=
eA=$_uAZe_v^m@ z=Z~w;o{x|Ee|hir&krZ}OV8i`r2lLE?q7el=2ggj{waNjhui=2m+8mv_$!bbD_8?z t?RNVEyEE diff --git a/Resources/Textures/Objects/Consumable/Smokeables/Cigars/cigar-gold.rsi/lit-inhand-right.png b/Resources/Textures/Objects/Consumable/Smokeables/Cigars/cigar-gold.rsi/lit-inhand-right.png index cdeedb4c24b6843544fa4ca348296f2536b90cd6..7c685a0a408cf76f0ffc0fc229a211e6413efa31 100644 GIT binary patch literal 1220 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE4M+yv$zcaljKx9jP7LeL$-HD>V5#$TaSW-L z^Y*T7p0v9J+k=}5slQB$@?G8)F|6FAxYcXw4=zpC$AQ~CGill%M63@r{_Pu@(ZGWCA9-FPX`5@c{-+N)oAdn%${y{y0ddjJ2s z_4`AwMpftUueo^jviz;#6}6>n{*}l6zZ|zm-~5;Twfpi=TlxdvD?YPU)aud~OwU!eo|)3?>H?Muk}n0=^6#Y78#I42w7!E)o#Fb-mX7-aPsLYkG|B z|1P`EF7c@4Pt>pZk1N*i{&)0tzSqtFd+u5O>z{vS%l}x--}QHL>&t=~Qhn4WKYM>~ zkIkHI|2Iwf8~^*Z{OODLzVuf9UN$A&J~A2VXobUW{QTFW%&qkQ3%uR#r5I&?UTW3* z&Dk?{4>>HQvxZWBLDW(w`sa zC)E9rerx{h`2Jd_+U<|j&h6{_yoTT4dhxm){|;)Y-@E_4+%W(DoFDukceZ?1)r?N= zdF&V-b(~p-Qw?Za?$e--*z0rd*Sly>w>h)(Y;0x4-i9whjXxNAa%1b?=p5G*z!R)q ziZ?W!uj@%Ng5qE^_YuFyCu=rVmQC-0#YhcXLiUz#H;>QJJ;dR#<(}XJt-{GCm;5|% z^XLEQ&-cH-^!{nYx!?Bx|9}0b&(`l>bMqU>hbN!UufDyW{q4TBMFG!`{rS`TufNjn z)2g<7f4b?DnEt~@KP}#V|GIVi|NTC<_rI@8&b@y0_rGt)iwca<%ktIqR7| zRqv}SDl9T?uRXqS?H_@P&{lTZNC3W8n%~#y~*L`*yIAH-J<4x0l#+4ECn|qkj>OgVh M>FVdQ&MBb@07DZjVgLXD literal 542 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE4M+yv$zf+;V0`N7;uumf=j~lXFJ?!Hwuh1% zw`>vSSJ1R|*e1MY?H+f5euX&aH#tWy$tYDZSZ~}Szp+!{rpClx&ikKBcAwq9`80R* zSrMRd#DJo!`=)NcwkZD0n-$wm{=WY8ulMWP@a8l2D|0`Y{Q2{;WY>p(|D3O@nIAs? z-gx)g+@g=We{Nm(FM}!J^@Bh5s8{~HWb?vtIpQq=3{xAHTdBasZ{vR)P=oGv2 VvzR7}3vsJKlAf-9F6*2UngAYTyTJee diff --git a/Resources/Textures/Objects/Consumable/Smokeables/Cigars/cigar-gold.rsi/unlit-inhand-left.png b/Resources/Textures/Objects/Consumable/Smokeables/Cigars/cigar-gold.rsi/unlit-inhand-left.png index 9c3943fbf26ecf93db9b406f4955db7941abaa35..c1ca9c4d489e08820423c02af465fb7535ae8dd4 100644 GIT binary patch delta 279 zcmeyyxQS_kNGZx^prw85kJec)B=-RLpsMYolnBfk^AaBgw8$8G0J5Z@fCR z?OlRf0)y7=h?SNmPA5)(o$-J52F~f)PAwMfK#d^4`!S4pezkb~?f%0L@*eK1h+qCt zVz=fV`*`==bE;Q2#s=k88F-fj8(2Ts8M{{Yuh!;ekDrUzZzopr09zY+EdT%j literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=dp%toLn`LHy}41a$w9>RV!v}r z3ga{e+ZngE+B$HGIi&1TGw4gR`d6EOqgu)6-M+>QW}q$*h`N+I=WA8pCR=+y=R40d zpW4pfCEs^>`PMakr{{d>`fm|&J#@mS%xTx<1AZFZmtX!w1&&=LGiJ#v sysp~Qb=qLs_SfI5&!y@E?JrYTnzyNvH{Q*6Z!5?>p00i_>zopr01r%D7ytkO diff --git a/Resources/Textures/Objects/Consumable/Smokeables/Cigars/cigar-gold.rsi/unlit-inhand-right.png b/Resources/Textures/Objects/Consumable/Smokeables/Cigars/cigar-gold.rsi/unlit-inhand-right.png index 0f4ab68d1569e959c7cd17c2ad9f83e6a37ff345..9fc2e5ba275c279ff1ba67a04e0fc3e5d38cb12f 100644 GIT binary patch delta 308 zcmZo?I?psgrJk`k$lZxy-8q?;3=E8%o-U3d6?5L+vgT`Y5NUnby>U^I;+un!9o`F; zn@szr*JyjAuR1|7Y+KY14-;c$&O?kp_qQBTIQlS!<9bgT0|Xc-N4|KnOJm*7ot3-S zt=en({7kjI$A)c5Grvif*VgS@!)0yi`yozz;pE+i6*t#cTb@tuiu?Jw_{X!eN~~v2 z8hvvO{mq#C=U)21#l;6-r|oCbaFBKAWxB$61;ohx#JWZDY-|dffp^c&%Wdx#qR z6uofu4fl^<-tXn*Smhd7xB}P%7BiGGn1UGIVi%6{OsG=V-T*TKZkFyY%U`-@pa1)v t?7dg~_NJQO`<+66ugts2%)pRflJ`-~V1t`D!&{K2JYD@<);T3K0RVE$hAjX9 literal 263 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC==R92;Ln`LHy}6P1kO6~BpmgBU zqzP{t*c17)yngi@P)K9vpVVb$!l~(}6m{z_xSiX1U{qlFvR> zYR=2w*=ce;I4W+xe7oTt@0Ih4!*>_XT(*O)D|(^N-g5rpzaM5ZRt2t|Tr9o*w|c@709Ovok K=d#Wzp$Pz&BwsrK diff --git a/Resources/Textures/Objects/Consumable/Smokeables/Cigars/cigar.rsi/lit-inhand-left.png b/Resources/Textures/Objects/Consumable/Smokeables/Cigars/cigar.rsi/lit-inhand-left.png index 353efa3f395a6167f2bcc1f68b75b1b6b2f5c950..c08f70d091d56f6538f7c3f7322d9d692c5a5fed 100644 GIT binary patch literal 1374 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE4M+yv$zcaljKx9jP7LeL$-HD>V3qK6aSW-L z^Y*S`k#IP}@rT=IPPr2Dkl{#)jKjMbJC-WPI6r>K!s9$s+hXN{uRc~a47+A5X;-uT zyNtp6(8bH^mc(YB{r_7lWyAe-7yMUG-THni6VL`^Abj=BZ{}N<*8Tl;)Bo%v{kZ$u zPoKOmd%tm8;kSg;Kl8mUe-{7vxPINbRrTLr{d`&U=lRk(du$&4+pqQX$<2@7{(t&= zIq2Pf%UA#Gf0h1CuHC|r72npJ?Ukv;|5cuEkEVeplfo>94mE~FoDCUBOnbR%=DwAg ze7|o0Y~7aIZ)NA*$KWE&aFNBqgi*kk1m;_V*UU22b$@iPv+t<8vE}pm)3>M3zgC~0 zd+M#8x%koW=V3>zUtr-3{-8nSbAF|6RnQ5cP%2Q0Cg(^xv8_eP;wwf&s}8T+Cayyp?X( z&)=5be_t=}`m=U>TU*)G#m8pI|J&v(KK1@Q`Tv__D(e27`o-YvBfYOm^3etHCI3HN zo-Y6ISDa@5Kgs7=-)~P3T=(v9(x3IO9ly-9NO-&dMYVgssj*}9t&7jk<+hkjJEa29qyuG}$nQna9vDP*$R^a44 z7MpwA(*P7<`i&B<>&=7I3RXSfKt!Kffz%C%!*lz5k@$p>1zY0X=_@Ej9gW zzm3fQ&b{XD;8YREv~hB+e*^#8vO{l?^y5tlJn4(%TkkFT{*|FN?Uz;cg_@c3|5j?M z>u;YOy#GAwrP$jWB>snLs-NF=eE+UpQNO>IzLv|`{D1oU`O}L2pFJne_O57S#buMz zKR;T3t6y_6`}@!T@+H9FVgB-SUflnTj#kNCJc0)T!nQvRNG{8DKWi?&?9QLU!`n@l zN~$z?#tCfBo4zlv|10CRf-~%YR~;=gv3-7Lzq9ya|5k<{b!)1(y{`xoU}&Cw%KL=f zHT_BDExq%8$sXPQ>l~*^>&^RSAI&sC!SQ~)S=hyzSjTu?5X{k`M2iH-ZayDsejagA{&hU z9Y1`|y&f$uJUsq?apv>qr*9{}tdpJn%o%fgm- z$*42@IM&y1uiuE7tHEj5>?gyqnACz-+7g>uUmf~7+uqaQCqse{uJnzqbbzTXUB@3# p49wi8jn4h~5F9HHE4OAW`p+=+u=8Bk{cnRoVxF#kF6*2UngE@xakKyc literal 769 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE4M+yv$zf+;U^?OH;uumf=j~m?ERjTshKKbk zOP5B>yeDDJpYUo+*(~OY#s`8b5mjt!x9~>1W7KJ8zo2}he~Dq2q~e;{y_NIZQxns= z^8ekfOkDjJXdDW-6LQ(=yJ`Q=OP|~Mm(3TycSkn)|LHx~=B&25^EdV1V#9Cte}Dg6 zeKqUjt&r=UHAWE_tWP!%8WX5+p^8)?w=eA=$_uAZe_v^m@ z=Z~w;o{x|Ee|hir&krZ}OV8i`r2lLE?q7el=2ggj{waNjhui=2m+8mv_$!bbD_8?z t?RNVEyEE diff --git a/Resources/Textures/Objects/Consumable/Smokeables/Cigars/cigar.rsi/lit-inhand-right.png b/Resources/Textures/Objects/Consumable/Smokeables/Cigars/cigar.rsi/lit-inhand-right.png index cdeedb4c24b6843544fa4ca348296f2536b90cd6..7c685a0a408cf76f0ffc0fc229a211e6413efa31 100644 GIT binary patch literal 1220 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE4M+yv$zcaljKx9jP7LeL$-HD>V5#$TaSW-L z^Y*T7p0v9J+k=}5slQB$@?G8)F|6FAxYcXw4=zpC$AQ~CGill%M63@r{_Pu@(ZGWCA9-FPX`5@c{-+N)oAdn%${y{y0ddjJ2s z_4`AwMpftUueo^jviz;#6}6>n{*}l6zZ|zm-~5;Twfpi=TlxdvD?YPU)aud~OwU!eo|)3?>H?Muk}n0=^6#Y78#I42w7!E)o#Fb-mX7-aPsLYkG|B z|1P`EF7c@4Pt>pZk1N*i{&)0tzSqtFd+u5O>z{vS%l}x--}QHL>&t=~Qhn4WKYM>~ zkIkHI|2Iwf8~^*Z{OODLzVuf9UN$A&J~A2VXobUW{QTFW%&qkQ3%uR#r5I&?UTW3* z&Dk?{4>>HQvxZWBLDW(w`sa zC)E9rerx{h`2Jd_+U<|j&h6{_yoTT4dhxm){|;)Y-@E_4+%W(DoFDukceZ?1)r?N= zdF&V-b(~p-Qw?Za?$e--*z0rd*Sly>w>h)(Y;0x4-i9whjXxNAa%1b?=p5G*z!R)q ziZ?W!uj@%Ng5qE^_YuFyCu=rVmQC-0#YhcXLiUz#H;>QJJ;dR#<(}XJt-{GCm;5|% z^XLEQ&-cH-^!{nYx!?Bx|9}0b&(`l>bMqU>hbN!UufDyW{q4TBMFG!`{rS`TufNjn z)2g<7f4b?DnEt~@KP}#V|GIVi|NTC<_rI@8&b@y0_rGt)iwca<%ktIqR7| zRqv}SDl9T?uRXqS?H_@P&{lTZNC3W8n%~#y~*L`*yIAH-J<4x0l#+4ECn|qkj>OgVh M>FVdQ&MBb@07DZjVgLXD literal 542 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE4M+yv$zf+;V0`N7;uumf=j~lXFJ?!Hwuh1% zw`>vSSJ1R|*e1MY?H+f5euX&aH#tWy$tYDZSZ~}Szp+!{rpClx&ikKBcAwq9`80R* zSrMRd#DJo!`=)NcwkZD0n-$wm{=WY8ulMWP@a8l2D|0`Y{Q2{;WY>p(|D3O@nIAs? z-gx)g+@g=We{Nm(FM}!J^@Bh5s8{~HWb?vtIpQq=3{xAHTdBasZ{vR)P=oGv2 VvzR7}3vsJKlAf-9F6*2UngAYTyTJee diff --git a/Resources/Textures/Objects/Consumable/Smokeables/Cigars/cigar.rsi/unlit-inhand-left.png b/Resources/Textures/Objects/Consumable/Smokeables/Cigars/cigar.rsi/unlit-inhand-left.png index 9c3943fbf26ecf93db9b406f4955db7941abaa35..c1ca9c4d489e08820423c02af465fb7535ae8dd4 100644 GIT binary patch delta 279 zcmeyyxQS_kNGZx^prw85kJec)B=-RLpsMYolnBfk^AaBgw8$8G0J5Z@fCR z?OlRf0)y7=h?SNmPA5)(o$-J52F~f)PAwMfK#d^4`!S4pezkb~?f%0L@*eK1h+qCt zVz=fV`*`==bE;Q2#s=k88F-fj8(2Ts8M{{Yuh!;ekDrUzZzopr09zY+EdT%j literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=dp%toLn`LHy}41a$w9>RV!v}r z3ga{e+ZngE+B$HGIi&1TGw4gR`d6EOqgu)6-M+>QW}q$*h`N+I=WA8pCR=+y=R40d zpW4pfCEs^>`PMakr{{d>`fm|&J#@mS%xTx<1AZFZmtX!w1&&=LGiJ#v sysp~Qb=qLs_SfI5&!y@E?JrYTnzyNvH{Q*6Z!5?>p00i_>zopr01r%D7ytkO diff --git a/Resources/Textures/Objects/Consumable/Smokeables/Cigars/cigar.rsi/unlit-inhand-right.png b/Resources/Textures/Objects/Consumable/Smokeables/Cigars/cigar.rsi/unlit-inhand-right.png index 0f4ab68d1569e959c7cd17c2ad9f83e6a37ff345..9fc2e5ba275c279ff1ba67a04e0fc3e5d38cb12f 100644 GIT binary patch delta 308 zcmZo?I?psgrJk`k$lZxy-8q?;3=E8%o-U3d6?5L+vgT`Y5NUnby>U^I;+un!9o`F; zn@szr*JyjAuR1|7Y+KY14-;c$&O?kp_qQBTIQlS!<9bgT0|Xc-N4|KnOJm*7ot3-S zt=en({7kjI$A)c5Grvif*VgS@!)0yi`yozz;pE+i6*t#cTb@tuiu?Jw_{X!eN~~v2 z8hvvO{mq#C=U)21#l;6-r|oCbaFBKAWxB$61;ohx#JWZDY-|dffp^c&%Wdx#qR z6uofu4fl^<-tXn*Smhd7xB}P%7BiGGn1UGIVi%6{OsG=V-T*TKZkFyY%U`-@pa1)v t?7dg~_NJQO`<+66ugts2%)pRflJ`-~V1t`D!&{K2JYD@<);T3K0RVE$hAjX9 literal 263 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC==R92;Ln`LHy}6P1kO6~BpmgBU zqzP{t*c17)yngi@P)K9vpVVb$!l~(}6m{z_xSiX1U{qlFvR> zYR=2w*=ce;I4W+xe7oTt@0Ih4!*>_XT(*O)D|(^N-g5rpzaM5ZRt2t|Tr9o*w|c@709Ovok K=d#Wzp$Pz&BwsrK From 014c5eb3e8d36c7a72a0b2d647ca580b903ebdf9 Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 5 Jun 2024 21:17:38 +0000 Subject: [PATCH 12/55] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 6adbf16221d..adbad1269bb 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: brainfood1183 - changes: - - message: Added Spray Paints. - type: Add - id: 6186 - time: '2024-03-18T21:29:48.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/23003 - author: PJB3005 changes: - message: Bans are now shown in the "adminremarks" command. @@ -3848,3 +3841,10 @@ id: 6685 time: '2024-06-05T20:47:28.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/28571 +- author: ps3moira + changes: + - message: Lit cigars inhand sprites are now visible. + type: Fix + id: 6686 + time: '2024-06-05T21:16:32.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/28641 From 27a5d08db497348db591e318a2ea7e7f72cf0662 Mon Sep 17 00:00:00 2001 From: Cojoke <83733158+Cojoke-dot@users.noreply.github.com> Date: Wed, 5 Jun 2024 17:03:31 -0500 Subject: [PATCH 13/55] Clean up Eva and Hardsuit helm yml + Lets atmos firesuit helm work as a BreathMask (#28602) --- .../Clothing/Head/base_clothinghead.yml | 2 ++ .../Entities/Clothing/Head/eva-helmets.yml | 6 ---- .../Clothing/Head/hardsuit-helmets.yml | 31 ------------------- .../Entities/Clothing/Head/helmets.yml | 1 + 4 files changed, 3 insertions(+), 37 deletions(-) diff --git a/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml b/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml index 40f9e0a3d4e..866fe962ca5 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml @@ -119,6 +119,7 @@ id: ClothingHeadEVAHelmetBase name: base space helmet components: + - type: BreathMask - type: Item size: Normal - type: PressureProtection @@ -150,6 +151,7 @@ name: base hardsuit helmet noSpawn: true components: + - type: BreathMask - type: Sprite state: icon # default state used by most inheritors - type: Clickable diff --git a/Resources/Prototypes/Entities/Clothing/Head/eva-helmets.yml b/Resources/Prototypes/Entities/Clothing/Head/eva-helmets.yml index 963bcdedd78..530c23a5781 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/eva-helmets.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/eva-helmets.yml @@ -5,7 +5,6 @@ name: EVA helmet description: An old-but-gold helmet designed for extravehicular activites. Infamous for making security officers paranoid. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Helmets/eva.rsi - type: Clothing @@ -22,7 +21,6 @@ name: EVA helmet description: An old-but-gold helmet designed for extravehicular activites. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Helmets/eva_large.rsi - type: Clothing @@ -35,7 +33,6 @@ name: syndicate EVA helmet description: A simple, stylish EVA helmet. Designed for maximum humble space-badassery. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Helmets/eva_syndicate.rsi - type: Clothing @@ -48,7 +45,6 @@ name: cosmonaut helmet description: Ancient design, but advanced manufacturing. #Description here originally started with " A deceptively well armored space helmet." Potentially had armor values in SS13 that weren't brought over? components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Helmets/cosmonaut.rsi - type: Clothing @@ -61,7 +57,6 @@ name: paramedic void helmet description: A void helmet made for paramedics. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Helmets/paramedhelm.rsi - type: Clothing @@ -81,7 +76,6 @@ name: NTSRA void helmet description: An ancient space helmet, designed by the NTSRA branch of CentCom. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Helmets/ancientvoidsuit.rsi - type: Clothing diff --git a/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml b/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml index 072dd53d9ae..0c660e09b80 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml @@ -12,7 +12,6 @@ name: basic hardsuit helmet description: A basic-looking hardsuit helmet that provides minor protection against most sources of damage. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/basic.rsi - type: Clothing @@ -28,7 +27,6 @@ name: atmos hardsuit helmet description: A special hardsuit helmet designed for working in low-pressure, high thermal environments. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/atmospherics.rsi layers: @@ -68,7 +66,6 @@ name: engineering hardsuit helmet description: An engineering hardsuit helmet designed for working in low-pressure, high radioactive environments. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/engineering.rsi - type: Clothing @@ -86,7 +83,6 @@ name: spationaut hardsuit helmet description: A sturdy helmet designed for complex industrial operations in space. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/spatiohelm.rsi layers: @@ -121,7 +117,6 @@ name: salvage hardsuit helmet description: A special helmet designed for work in a hazardous, low pressure environment. Has reinforced plating for wildlife encounters and dual floodlights. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/salvage.rsi - type: Clothing @@ -140,7 +135,6 @@ name: salvager maxim helmet description: A predication of decay washes over your mind. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/maxim.rsi - type: Clothing @@ -163,7 +157,6 @@ name: security hardsuit helmet description: Armored hardsuit helmet for security needs. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/security.rsi - type: Clothing @@ -188,7 +181,6 @@ name: brigmedic hardsuit helmet description: The lightweight helmet of the brigmedic hardsuit. Protects against viruses, and clowns. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/brigmedic.rsi - type: Clothing @@ -215,7 +207,6 @@ name: warden's hardsuit helmet description: A modified riot helmet. Oddly comfortable. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/security-warden.rsi - type: Clothing @@ -240,7 +231,6 @@ name: captain's hardsuit helmet description: Special hardsuit helmet, made for the captain of the station. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/capspace.rsi - type: Clothing @@ -256,7 +246,6 @@ name: chief engineer's hardsuit helmet description: Special hardsuit helmet, made for the chief engineer of the station. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/engineering-white.rsi - type: Clothing @@ -274,7 +263,6 @@ name: chief medical officer's hardsuit helmet description: Lightweight medical hardsuit helmet that doesn't restrict your head movements. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/medical.rsi - type: Clothing @@ -292,7 +280,6 @@ name: experimental research hardsuit helmet description: Lightweight hardsuit helmet that doesn't restrict your head movements. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/rd.rsi - type: Clothing @@ -310,7 +297,6 @@ name: head of security's hardsuit helmet description: Security hardsuit helmet with the latest top secret NT-HUD software. Belongs to the HoS. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/security-red.rsi - type: Clothing @@ -335,7 +321,6 @@ name: luxury mining hardsuit helmet description: A refurbished mining hardsuit helmet, fitted with satin cushioning and an extra (non-functioning) antenna, because you're that extra. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/luxury.rsi - type: Clothing @@ -355,7 +340,6 @@ name: blood-red hardsuit helmet description: A heavily armored helmet designed for work in special operations. Property of Gorlex Marauders. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/syndicate.rsi - type: Clothing @@ -380,7 +364,6 @@ name: blood-red medic hardsuit helmet description: An advanced red hardsuit helmet specifically designed for field medic operations. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/syndiemedic.rsi - type: Clothing @@ -405,7 +388,6 @@ name: syndicate elite helmet description: An elite version of the blood-red hardsuit's helmet, with improved armor and fireproofing. Property of Gorlex Marauders. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/syndieelite.rsi - type: Clothing @@ -434,7 +416,6 @@ name: syndicate commander helmet description: A bulked up version of the blood-red hardsuit's helmet, purpose-built for the commander of a syndicate operative squad. Has significantly improved armor for those deadly front-lines firefights. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/syndiecommander.rsi - type: Clothing @@ -459,7 +440,6 @@ name: cybersun juggernaut helmet description: Made of compressed red matter, this helmet was designed in the Tau chromosphere facility. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/cybersun.rsi - type: Clothing @@ -482,7 +462,6 @@ name: wizard hardsuit helmet description: A bizarre gem-encrusted helmet that radiates magical energies. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/wizard.rsi - type: Clothing @@ -507,7 +486,6 @@ name: organic space helmet description: A spaceworthy biomass of pressure and temperature resistant tissue. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/lingspacehelmet.rsi - type: Clothing @@ -524,7 +502,6 @@ suffix: Pirate description: A deep space EVA helmet, very heavy but provides good protection. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/pirateeva.rsi - type: Clothing @@ -541,7 +518,6 @@ suffix: Pirate description: A special hardsuit helmet, made for the captain of a pirate ship. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/piratecaptainhelm.rsi - type: Clothing @@ -558,7 +534,6 @@ name: ERT leader hardsuit helmet description: A special hardsuit helmet worn by members of an emergency response team. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/ERThelmets/ertleader.rsi - type: Clothing @@ -580,7 +555,6 @@ name: ERT chaplain hardsuit helmet description: A special hardsuit helmet worn by members of an emergency response team. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/ERThelmets/ertchaplain.rsi - type: Clothing @@ -595,7 +569,6 @@ name: ERT engineer hardsuit helmet description: A special hardsuit helmet worn by members of an emergency response team. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/ERThelmets/ertengineer.rsi - type: Clothing @@ -617,7 +590,6 @@ name: ERT medic hardsuit helmet description: A special hardsuit helmet worn by members of an emergency response team. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/ERThelmets/ertmedical.rsi - type: Clothing @@ -632,7 +604,6 @@ name: ERT security hardsuit helmet description: A special hardsuit helmet worn by members of an emergency response team. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/ERThelmets/ertsecurity.rsi - type: Clothing @@ -654,7 +625,6 @@ name: ERT janitor hardsuit helmet description: A special hardsuit helmet worn by members of an emergency response team. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/ERThelmets/ertjanitor.rsi - type: Clothing @@ -669,7 +639,6 @@ name: CBURN exosuit helmet description: A pressure resistant and fireproof hood worn by special cleanup units. components: - - type: BreathMask - type: Sprite sprite: Clothing/Head/Hardsuits/cburn.rsi layers: diff --git a/Resources/Prototypes/Entities/Clothing/Head/helmets.yml b/Resources/Prototypes/Entities/Clothing/Head/helmets.yml index 720e52ee588..d585518ece8 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/helmets.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/helmets.yml @@ -263,6 +263,7 @@ slots: - Hair - Snout + - type: BreathMask #Chitinous Helmet - type: entity From 72df1a0ae58679cf482006c08b242b94ce00c661 Mon Sep 17 00:00:00 2001 From: Cojoke <83733158+Cojoke-dot@users.noreply.github.com> Date: Wed, 5 Jun 2024 17:04:09 -0500 Subject: [PATCH 14/55] Shifts borgs hats to the right a bit (#28600) --- Resources/Prototypes/InventoryTemplates/borg.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Resources/Prototypes/InventoryTemplates/borg.yml b/Resources/Prototypes/InventoryTemplates/borg.yml index a03be16708d..d43519f61cf 100644 --- a/Resources/Prototypes/InventoryTemplates/borg.yml +++ b/Resources/Prototypes/InventoryTemplates/borg.yml @@ -7,7 +7,7 @@ uiWindowPos: 1,0 strippingWindowPos: 0,0 displayName: Head - offset: 0, -0.09375 + offset: 0.015625, -0.09375 - type: inventoryTemplate id: borgShort @@ -18,7 +18,7 @@ uiWindowPos: 1,0 strippingWindowPos: 0,0 displayName: Head - offset: 0, -0.1875 + offset: 0.015625, -0.1875 - type: inventoryTemplate id: borgTall @@ -30,6 +30,7 @@ uiWindowPos: 0,0 strippingWindowPos: 0,0 displayName: Head + offset: 0.015625, 0 # taller than tall - type: inventoryTemplate From 110c8a96e0f7593a1caad4c6be842161d9428eb6 Mon Sep 17 00:00:00 2001 From: Verm <32827189+Vermidia@users.noreply.github.com> Date: Wed, 5 Jun 2024 17:06:57 -0500 Subject: [PATCH 15/55] Fix mouse inhands (#28623) --- Resources/Prototypes/Entities/Mobs/NPCs/animals.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index 51647f69852..971d05823a5 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -1533,6 +1533,7 @@ state: mouse-0 - type: Item size: Tiny + heldPrefix: 0 - type: Clothing quickEquip: false sprite: Mobs/Animals/mouse.rsi @@ -1706,6 +1707,9 @@ Base: dead-1 Dead: Base: splat-1 + - type: Item + size: Tiny + heldPrefix: 1 - type: entity parent: MobMouse @@ -1732,6 +1736,9 @@ Base: dead-2 Dead: Base: splat-2 + - type: Item + size: Tiny + heldPrefix: 2 - type: entity name: cancer mouse From 8a1f3f497184cb14fca9cea6af0ab87f6df5e632 Mon Sep 17 00:00:00 2001 From: Tayrtahn Date: Wed, 5 Jun 2024 18:08:41 -0400 Subject: [PATCH 16/55] Adjust some touch reaction damage levels (#28591) --- Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml | 2 +- Resources/Prototypes/Entities/Mobs/Species/diona.yml | 8 ++++---- Resources/Prototypes/Entities/Mobs/Species/slime.yml | 2 +- Resources/Prototypes/Entities/Objects/Misc/kudzu.yml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml b/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml index d2ca7804381..ffca699bfcc 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml @@ -84,7 +84,7 @@ scaleByQuantity: true damage: types: - Heat: 3 + Heat: 0.15 - !type:PopupMessage type: Local messages: [ "slime-hurt-by-water-popup" ] diff --git a/Resources/Prototypes/Entities/Mobs/Species/diona.yml b/Resources/Prototypes/Entities/Mobs/Species/diona.yml index 1cac380cd03..7edb3a19dba 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/diona.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/diona.yml @@ -49,9 +49,9 @@ scaleByQuantity: true damage: types: - Blunt: 2 - Slash: 2 - Piercing: 3 + Blunt: 0.1 + Slash: 0.1 + Piercing: 0.15 - !type:PopupMessage type: Local visualType: Large @@ -64,7 +64,7 @@ scaleByQuantity: true damage: types: - Poison: 5 + Poison: 0.25 - !type:PopupMessage type: Local visualType: Large diff --git a/Resources/Prototypes/Entities/Mobs/Species/slime.yml b/Resources/Prototypes/Entities/Mobs/Species/slime.yml index 2ab26ffcd61..caa3690e5d2 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/slime.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/slime.yml @@ -91,7 +91,7 @@ scaleByQuantity: true damage: types: - Heat: 2 + Heat: 0.1 - !type:PopupMessage type: Local visualType: Large diff --git a/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml b/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml index a1005004946..ca56ef5acbb 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml @@ -76,7 +76,7 @@ scaleByQuantity: true damage: types: - Heat: 10 + Heat: 0.5 - type: AtmosExposed - type: Kudzu growthTickChance: 0.3 From 8e85bec2cef641e5624241ce33cdbdbba2921e5d Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 5 Jun 2024 22:09:47 +0000 Subject: [PATCH 17/55] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index adbad1269bb..25f48ec5f79 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: PJB3005 - changes: - - message: Bans are now shown in the "adminremarks" command. - type: Add - id: 6187 - time: '2024-03-18T21:31:34.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/26240 - author: Terraspark4941 changes: - message: The TEG page in the guidebook has been updated with proper information! @@ -3848,3 +3841,11 @@ id: 6686 time: '2024-06-05T21:16:32.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/28641 +- author: Tayrtahn + changes: + - message: Slimes, diona, and kudzu are less dramatically affected by having certain + chemicals splashed on them. + type: Tweak + id: 6687 + time: '2024-06-05T22:08:41.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/28591 From ba57e3e4d9b95bad457f93f7e1f9bbd433d8eebd Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Thu, 6 Jun 2024 10:14:25 +1200 Subject: [PATCH 18/55] Add closing storage UIs to StorageInteractionTest (#28633) --- .../Tests/Storage/StorageInteractionTest.cs | 12 ++++++++++++ .../Storage/EntitySystems/SharedStorageSystem.cs | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Content.IntegrationTests/Tests/Storage/StorageInteractionTest.cs b/Content.IntegrationTests/Tests/Storage/StorageInteractionTest.cs index 34402dd5e62..8d0de707f3b 100644 --- a/Content.IntegrationTests/Tests/Storage/StorageInteractionTest.cs +++ b/Content.IntegrationTests/Tests/Storage/StorageInteractionTest.cs @@ -4,6 +4,7 @@ using Content.Shared.Input; using Content.Shared.PDA; using Content.Shared.Storage; +using Content.Shared.Timing; using Robust.Client.UserInterface; using Robust.Shared.Containers; using Robust.Shared.GameObjects; @@ -27,11 +28,22 @@ public async Task UiInteractTest() Assert.That(IsUiOpen(StorageComponent.StorageUiKey.Key), Is.False); Assert.That(IsUiOpen(PdaUiKey.Key), Is.False); + await Server.WaitPost(() => SEntMan.RemoveComponent(STarget!.Value)); + await RunTicks(5); + // Activating the backpack opens the UI await Activate(); Assert.That(IsUiOpen(StorageComponent.StorageUiKey.Key), Is.True); Assert.That(IsUiOpen(PdaUiKey.Key), Is.False); + // Activating it again closes the UI + await Activate(); + Assert.That(IsUiOpen(StorageComponent.StorageUiKey.Key), Is.False); + + // Open it again + await Activate(); + Assert.That(IsUiOpen(StorageComponent.StorageUiKey.Key), Is.True); + // Pick up a PDA var pda = await PlaceInHands("PassengerPDA"); var sPda = ToServer(pda); diff --git a/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs b/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs index d87b57bfc8d..f20e2f9ab1f 100644 --- a/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs +++ b/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs @@ -298,7 +298,7 @@ public void OpenStorageUI(EntityUid uid, EntityUid entity, StorageComponent? sto return; // prevent spamming bag open / honkerton honk sound - silent |= TryComp(uid, out var useDelay) && UseDelay.IsDelayed((uid, useDelay)); + silent |= TryComp(uid, out var useDelay) && UseDelay.IsDelayed((uid, useDelay), id: OpenUiUseDelayID); if (!CanInteract(entity, (uid, storageComp), silent: silent)) return; @@ -308,7 +308,7 @@ public void OpenStorageUI(EntityUid uid, EntityUid entity, StorageComponent? sto Audio.PlayPredicted(storageComp.StorageOpenSound, uid, entity); if (useDelay != null) - UseDelay.TryResetDelay((uid, useDelay)); + UseDelay.TryResetDelay((uid, useDelay), id: OpenUiUseDelayID); } _ui.OpenUi(uid, StorageComponent.StorageUiKey.Key, entity); From fea2bc942263b3cda6cb61a9f8959493931e8b8d Mon Sep 17 00:00:00 2001 From: Chief-Engineer <119664036+Chief-Engineer@users.noreply.github.com> Date: Wed, 5 Jun 2024 18:59:22 -0500 Subject: [PATCH 19/55] Update rules (#28452) --- .github/CODEOWNERS | 2 + .../Guidebook/Controls/GuidebookWindow.xaml | 2 +- Resources/Locale/en-US/guidebook/guides.ftl | 55 ++ Resources/Prototypes/Guidebook/rules.yml | 369 +++++++ Resources/Prototypes/Guidebook/ss14.yml | 1 + .../Guidebook/ServerRules/BanDurations.xml | 17 + .../Guidebook/ServerRules/BanTypes.xml | 11 + .../ServerRules/CoreRules/RuleC0.xml | 19 + .../ServerRules/CoreRules/RuleC10AHelp.xml | 29 + .../CoreRules/RuleC11AhelpThreats.xml | 20 + .../ServerRules/CoreRules/RuleC12MinAge.xml | 6 + .../CoreRules/RuleC13CharacterNames.xml | 66 ++ .../ServerRules/CoreRules/RuleC14ICinOOC.xml | 13 + .../ServerRules/CoreRules/RuleC1Admins.xml | 6 + .../ServerRules/CoreRules/RuleC2DBAD.xml | 7 + .../ServerRules/CoreRules/RuleC3NoHate.xml | 20 + .../ServerRules/CoreRules/RuleC4NoERP.xml | 23 + .../ServerRules/CoreRules/RuleC5Metacomms.xml | 18 + .../CoreRules/RuleC6BanEvasion.xml | 15 + .../CoreRules/RuleC7EnglishOnly.xml | 10 + .../ServerRules/CoreRules/RuleC8Exploits.xml | 12 + .../ServerRules/CoreRules/RuleC9Multikey.xml | 7 + .../Guidebook/ServerRules/DefaultRules.xml | 5 + .../Guidebook/ServerRules/README.txt | 5 + .../Guidebook/ServerRules/RoleTypes.xml | 21 + .../ServerRules/RoleplayRules/RuleR0.xml | 26 + .../RoleplayRules/RuleR10Subordination.xml | 26 + .../RuleR11-1AnimalEscalation.xml | 36 + .../RoleplayRules/RuleR11-2ConflictTypes.xml | 30 + .../RoleplayRules/RuleR11Escalation.xml | 67 ++ .../RoleplayRules/RuleR12RoleAbandonment.xml | 28 + .../RoleplayRules/RuleR13PerformRole.xml | 26 + .../RoleplayRules/RuleR14SecComStandard.xml | 37 + .../RoleplayRules/RuleR15SpaceLaw.xml | 21 + .../RoleplayRules/RuleR1Silicons.xml | 4 + .../RoleplayRules/RuleR2Familiars.xml | 6 + .../RoleplayRules/RuleR3NormalRP.xml | 20 + .../RoleplayRules/RuleR4Metashield.xml | 103 ++ .../RoleplayRules/RuleR5Arrivals.xml | 22 + .../RoleplayRules/RuleR6SelfAntag.xml | 22 + .../RoleplayRules/RuleR7RoundStalling.xml | 16 + .../RoleplayRules/RuleR8NoFriendlyAntag.xml | 22 + .../RoleplayRules/RuleR9MassSabotage.xml | 23 + .../ServerRules/SiliconRules/RuleS0.xml | 15 + .../SiliconRules/RuleS10OrderConflicts.xml | 9 + .../ServerRules/SiliconRules/RuleS1Laws.xml | 6 + .../SiliconRules/RuleS2LawPriority.xml | 9 + .../SiliconRules/RuleS3LawRedefinition.xml | 8 + .../SiliconRules/RuleS4RequestChanges.xml | 6 + .../SiliconRules/RuleS5FreeSilicon.xml | 4 + .../SiliconRules/RuleS6UnreasonableOrders.xml | 22 + .../SiliconRules/RuleS7Consistency.xml | 6 + .../RuleS8DefaultCrewDefinition.xml | 4 + .../RuleS9DefaultHarmDefinition.xml | 25 + .../SpaceLaw/SLControlledSubstances.xml | 14 + .../ServerRules/SpaceLaw/SLCrimeList.xml | 934 ++++++++++++++++++ .../ServerRules/SpaceLaw/SLRestrictedGear.xml | 21 + .../SpaceLaw/SLRestrictedWeapons.xml | 11 + .../ServerRules/SpaceLaw/SpaceLaw.xml | 67 ++ .../ServerRules/WizDenCoreOnlyRules.xml | 26 + .../Guidebook/ServerRules/WizDenLRPRules.xml | 65 ++ .../Guidebook/ServerRules/WizDenMRPRules.xml | 65 ++ Resources/ServerInfo/RP_Rules.txt | 127 --- Resources/ServerInfo/Rules.txt | 115 --- 64 files changed, 2610 insertions(+), 243 deletions(-) create mode 100644 Resources/Prototypes/Guidebook/rules.yml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/BanDurations.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/BanTypes.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC0.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC10AHelp.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC11AhelpThreats.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC12MinAge.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC13CharacterNames.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC14ICinOOC.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC1Admins.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC2DBAD.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC3NoHate.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC4NoERP.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC5Metacomms.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC6BanEvasion.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC7EnglishOnly.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC8Exploits.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC9Multikey.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/DefaultRules.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/README.txt create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/RoleTypes.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR0.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR10Subordination.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR11-1AnimalEscalation.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR11-2ConflictTypes.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR11Escalation.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR12RoleAbandonment.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR13PerformRole.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR14SecComStandard.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR15SpaceLaw.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR1Silicons.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR2Familiars.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR3NormalRP.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR4Metashield.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR5Arrivals.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR6SelfAntag.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR7RoundStalling.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR8NoFriendlyAntag.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR9MassSabotage.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS0.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS10OrderConflicts.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS1Laws.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS2LawPriority.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS3LawRedefinition.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS4RequestChanges.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS5FreeSilicon.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS6UnreasonableOrders.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS7Consistency.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS8DefaultCrewDefinition.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS9DefaultHarmDefinition.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/SpaceLaw/SLControlledSubstances.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/SpaceLaw/SLCrimeList.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/SpaceLaw/SLRestrictedGear.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/SpaceLaw/SLRestrictedWeapons.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/SpaceLaw/SpaceLaw.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/WizDenCoreOnlyRules.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/WizDenLRPRules.xml create mode 100644 Resources/ServerInfo/Guidebook/ServerRules/WizDenMRPRules.xml delete mode 100644 Resources/ServerInfo/RP_Rules.txt delete mode 100644 Resources/ServerInfo/Rules.txt diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 21c3070b802..da9d4d693a8 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -15,6 +15,7 @@ /Content.*/GameTicking/ @moonheart08 @EmoGarbage404 /Resources/ServerInfo/ @moonheart08 @Chief-Engineer /Resources/ServerInfo/Guidebook/ @moonheart08 @EmoGarbage404 +/Resources/ServerInfo/Guidebook/ServerRules/ @Chief-Engineer /Resources/engineCommandPerms.yml @moonheart08 @Chief-Engineer /Resources/clientCommandPerms.yml @moonheart08 @Chief-Engineer @@ -23,6 +24,7 @@ /Resources/Prototypes/Body/ @DrSmugleaf # suffering /Resources/Prototypes/Entities/Mobs/Player/ @DrSmugleaf /Resources/Prototypes/Entities/Mobs/Species/ @DrSmugleaf +/Resources/Prototypes/Guidebook/rules.yml @Chief-Engineer /Content.*/Body/ @DrSmugleaf /Content.YAMLLinter @DrSmugleaf /Content.Shared/Damage/ @DrSmugleaf diff --git a/Content.Client/Guidebook/Controls/GuidebookWindow.xaml b/Content.Client/Guidebook/Controls/GuidebookWindow.xaml index 8dbfde3c475..cc6cc6e82b0 100644 --- a/Content.Client/Guidebook/Controls/GuidebookWindow.xaml +++ b/Content.Client/Guidebook/Controls/GuidebookWindow.xaml @@ -18,7 +18,7 @@ Name="SearchBar" PlaceHolder="{Loc 'guidebook-filter-placeholder-text'}" HorizontalExpand="True" - Margin="0 5 10 5"> + Margin="0 5 10 5"> diff --git a/Resources/Locale/en-US/guidebook/guides.ftl b/Resources/Locale/en-US/guidebook/guides.ftl index ff1ffbf5eaf..66c1a42adf2 100644 --- a/Resources/Locale/en-US/guidebook/guides.ftl +++ b/Resources/Locale/en-US/guidebook/guides.ftl @@ -68,5 +68,60 @@ guide-entry-revolutionaries = Revolutionaries guide-entry-minor-antagonists = Minor Antagonists guide-entry-space-ninja = Space Ninja +guide-entry-rules = Server Rules +guide-entry-rules-core-only = Core Only Ruleset +guide-entry-rules-lrp = Standard Ruleset +guide-entry-rules-mrp = MRP Ruleset +guide-entry-rules-role-types = Role Types +guide-entry-rules-core = Core Rules +guide-entry-rules-c1 = C1 +guide-entry-rules-c2 = C2 +guide-entry-rules-c3 = C3 +guide-entry-rules-c4 = C4 +guide-entry-rules-c5 = C5 +guide-entry-rules-c6 = C6 +guide-entry-rules-c7 = C7 +guide-entry-rules-c8 = C8 +guide-entry-rules-c9 = C9 +guide-entry-rules-c10 = C10 +guide-entry-rules-c11 = C11 +guide-entry-rules-c12 = C12 +guide-entry-rules-c13 = C13 +guide-entry-rules-c14 = C14 +guide-entry-rules-roleplay = Roleplay Rules +guide-entry-rules-r1 = R1 +guide-entry-rules-r2 = R2 +guide-entry-rules-r3 = R3 +guide-entry-rules-r4 = R4 +guide-entry-rules-r5 = R5 +guide-entry-rules-r6 = R6 +guide-entry-rules-r7 = R7 +guide-entry-rules-r8 = R8 +guide-entry-rules-r9 = R9 +guide-entry-rules-r10 = R10 +guide-entry-rules-r11 = R11 +guide-entry-rules-r12 = R12 +guide-entry-rules-r13 = R13 +guide-entry-rules-r14 = R14 +guide-entry-rules-r15 = R15 +guide-entry-rules-silicon = Silicon Rules +guide-entry-rules-s1 = S1 +guide-entry-rules-s2 = S2 +guide-entry-rules-s3 = S3 +guide-entry-rules-s4 = S4 +guide-entry-rules-s5 = S5 +guide-entry-rules-s6 = S6 +guide-entry-rules-s7 = S7 +guide-entry-rules-s8 = S8 +guide-entry-rules-s9 = S9 +guide-entry-rules-s10 = S10 +guide-entry-rules-space-law = Space Law +guide-entry-rules-sl-crime-list = Crime List +guide-entry-rules-sl-controlled-substances = Controlled Substances +guide-entry-rules-sl-restricted-gear = Restricted Gear +guide-entry-rules-sl-restricted-weapons = Restricted Weapons +guide-entry-rules-ban-types = Ban Types +guide-entry-rules-ban-durations = Ban Durations + guide-entry-writing = Writing guide-entry-glossary = Glossary diff --git a/Resources/Prototypes/Guidebook/rules.yml b/Resources/Prototypes/Guidebook/rules.yml new file mode 100644 index 00000000000..4aad4494855 --- /dev/null +++ b/Resources/Prototypes/Guidebook/rules.yml @@ -0,0 +1,369 @@ +- type: guideEntry # Default for forks and stuff. Should not be listed anywhere if the server is using a custom ruleset. + id: DefaultRuleset + name: guide-entry-rules + text: "/ServerInfo/Guidebook/ServerRules/DefaultRules.xml" + +- type: guideEntry + id: CoreRuleset + name: guide-entry-rules-core-only + priority: 0 + text: "/ServerInfo/Guidebook/ServerRules/WizDenCoreOnlyRules.xml" + +- type: guideEntry + id: StandardRuleset + name: guide-entry-rules-lrp + priority: 5 + text: "/ServerInfo/Guidebook/ServerRules/WizDenLRPRules.xml" + +- type: guideEntry + id: MRPRuleset + name: guide-entry-rules-mrp + priority: 10 + text: "/ServerInfo/Guidebook/ServerRules/WizDenMRPRules.xml" + +- type: guideEntry + id: RoleTypes + name: guide-entry-rules-role-types + priority: 20 + text: "/ServerInfo/Guidebook/ServerRules/RoleTypes.xml" + +- type: guideEntry + id: CoreRules + name: guide-entry-rules-core + priority: 30 + text: "/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC0.xml" + children: + - RuleC1 + - RuleC2 + - RuleC3 + - RuleC4 + - RuleC5 + - RuleC6 + - RuleC7 + - RuleC8 + - RuleC9 + - RuleC10 + - RuleC11 + - RuleC12 + - RuleC13 + - RuleC14 + +- type: guideEntry + id: RuleC1 + name: guide-entry-rules-c1 + priority: 1 + text: "/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC1Admins.xml" + +- type: guideEntry + id: RuleC2 + name: guide-entry-rules-c2 + priority: 2 + text: "/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC2DBAD.xml" + +- type: guideEntry + id: RuleC3 + name: guide-entry-rules-c3 + priority: 3 + text: "/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC3NoHate.xml" + +- type: guideEntry + id: RuleC4 + name: guide-entry-rules-c4 + priority: 4 + text: "/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC4NoERP.xml" + +- type: guideEntry + id: RuleC5 + name: guide-entry-rules-c5 + priority: 5 + text: "/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC5Metacomms.xml" + +- type: guideEntry + id: RuleC6 + name: guide-entry-rules-c6 + priority: 6 + text: "/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC6BanEvasion.xml" + +- type: guideEntry + id: RuleC7 + name: guide-entry-rules-c7 + priority: 7 + text: "/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC7EnglishOnly.xml" + +- type: guideEntry + id: RuleC8 + name: guide-entry-rules-c8 + priority: 8 + text: "/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC8Exploits.xml" + +- type: guideEntry + id: RuleC9 + name: guide-entry-rules-c9 + priority: 9 + text: "/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC9Multikey.xml" + +- type: guideEntry + id: RuleC10 + name: guide-entry-rules-c10 + priority: 10 + text: "/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC10AHelp.xml" + +- type: guideEntry + id: RuleC11 + name: guide-entry-rules-c11 + priority: 11 + text: "/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC11AhelpThreats.xml" + +- type: guideEntry + id: RuleC12 + name: guide-entry-rules-c12 + priority: 12 + text: "/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC12MinAge.xml" + +- type: guideEntry + id: RuleC13 + name: guide-entry-rules-c13 + priority: 13 + text: "/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC13CharacterNames.xml" + +- type: guideEntry + id: RuleC14 + name: guide-entry-rules-c14 + priority: 14 + text: "/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC14ICinOOC.xml" + +- type: guideEntry + id: RoleplayRules + name: guide-entry-rules-roleplay + priority: 40 + text: "/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR0.xml" + children: + - RuleR1 + - RuleR2 + - RuleR3 + - RuleR4 + - RuleR5 + - RuleR6 + - RuleR7 + - RuleR8 + - RuleR9 + - RuleR10 + - RuleR11 + - RuleR12 + - RuleR13 + - RuleR14 + - RuleR15 + +- type: guideEntry + id: RuleR1 + name: guide-entry-rules-r1 + priority: 1 + text: "/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR1Silicons.xml" + +- type: guideEntry + id: RuleR2 + name: guide-entry-rules-r2 + priority: 2 + text: "/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR2Familiars.xml" + +- type: guideEntry + id: RuleR3 + name: guide-entry-rules-r3 + priority: 3 + text: "/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR3NormalRP.xml" + +- type: guideEntry + id: RuleR4 + name: guide-entry-rules-r4 + priority: 4 + text: "/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR4Metashield.xml" + +- type: guideEntry + id: RuleR5 + name: guide-entry-rules-r5 + priority: 5 + text: "/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR5Arrivals.xml" + +- type: guideEntry + id: RuleR6 + name: guide-entry-rules-r6 + priority: 6 + text: "/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR6SelfAntag.xml" + +- type: guideEntry + id: RuleR7 + name: guide-entry-rules-r7 + priority: 7 + text: "/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR7RoundStalling.xml" + +- type: guideEntry + id: RuleR8 + name: guide-entry-rules-r8 + priority: 8 + text: "/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR8NoFriendlyAntag.xml" + +- type: guideEntry + id: RuleR9 + name: guide-entry-rules-r9 + priority: 9 + text: "/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR9MassSabotage.xml" + +- type: guideEntry + id: RuleR10 + name: guide-entry-rules-r10 + priority: 10 + text: "/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR10Subordination.xml" + +- type: guideEntry + id: RuleR11 + name: guide-entry-rules-r11 + priority: 11 + text: "/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR11Escalation.xml" + +- type: guideEntry + id: RuleR12 + name: guide-entry-rules-r12 + priority: 12 + text: "/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR12RoleAbandonment.xml" + +- type: guideEntry + id: RuleR13 + name: guide-entry-rules-r13 + priority: 13 + text: "/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR13PerformRole.xml" + +- type: guideEntry + id: RuleR14 + name: guide-entry-rules-r14 + priority: 14 + text: "/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR14SecComStandard.xml" + +- type: guideEntry + id: RuleR15 + name: guide-entry-rules-r15 + priority: 15 + text: "/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR15SpaceLaw.xml" + +- type: guideEntry + id: SiliconRules + name: guide-entry-rules-silicon + priority: 50 + text: "/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS0.xml" + children: + - RuleS1 + - RuleS2 + - RuleS3 + - RuleS4 + - RuleS5 + - RuleS6 + - RuleS7 + - RuleS8 + - RuleS9 + - RuleS10 + +- type: guideEntry + id: RuleS1 + name: guide-entry-rules-s1 + priority: 1 + text: "/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS1Laws.xml" + +- type: guideEntry + id: RuleS2 + name: guide-entry-rules-s2 + priority: 2 + text: "/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS2LawPriority.xml" + +- type: guideEntry + id: RuleS3 + name: guide-entry-rules-s3 + priority: 3 + text: "/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS3LawRedefinition.xml" + +- type: guideEntry + id: RuleS4 + name: guide-entry-rules-s4 + priority: 4 + text: "/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS4RequestChanges.xml" + +- type: guideEntry + id: RuleS5 + name: guide-entry-rules-s5 + priority: 5 + text: "/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS5FreeSilicon.xml" + +- type: guideEntry + id: RuleS6 + name: guide-entry-rules-s6 + priority: 6 + text: "/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS6UnreasonableOrders.xml" + +- type: guideEntry + id: RuleS7 + name: guide-entry-rules-s7 + priority: 7 + text: "/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS7Consistency.xml" + +- type: guideEntry + id: RuleS8 + name: guide-entry-rules-s8 + priority: 8 + text: "/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS8DefaultCrewDefinition.xml" + +- type: guideEntry + id: RuleS9 + name: guide-entry-rules-s9 + priority: 9 + text: "/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS9DefaultHarmDefinition.xml" + +- type: guideEntry + id: RuleS10 + name: guide-entry-rules-s10 + priority: 10 + text: "/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS10OrderConflicts.xml" + +- type: guideEntry + id: SpaceLaw + name: guide-entry-rules-space-law + priority: 60 + text: "/ServerInfo/Guidebook/ServerRules/SpaceLaw/SpaceLaw.xml" + children: + - SpaceLawCrimeList + - SpaceLawControlledSubstances + - SpaceLawRestrictedGear + - SpaceLawRestrictedWeapons + +- type: guideEntry + id: SpaceLawCrimeList + name: guide-entry-rules-sl-crime-list + priority: 5 + text: "/ServerInfo/Guidebook/ServerRules/SpaceLaw/SLCrimeList.xml" + +- type: guideEntry + id: SpaceLawControlledSubstances + name: guide-entry-rules-sl-controlled-substances + priority: 20 + text: "/ServerInfo/Guidebook/ServerRules/SpaceLaw/SLControlledSubstances.xml" + +- type: guideEntry + id: SpaceLawRestrictedGear + name: guide-entry-rules-sl-restricted-gear + priority: 30 + text: "/ServerInfo/Guidebook/ServerRules/SpaceLaw/SLRestrictedGear.xml" + +- type: guideEntry + id: SpaceLawRestrictedWeapons + name: guide-entry-rules-sl-restricted-weapons + priority: 40 + text: "/ServerInfo/Guidebook/ServerRules/SpaceLaw/SLRestrictedWeapons.xml" + +- type: guideEntry + id: BanTypes + name: guide-entry-rules-ban-types + priority: 90 + text: "/ServerInfo/Guidebook/ServerRules/BanTypes.xml" + +- type: guideEntry + id: BanDurations + name: guide-entry-rules-ban-durations + priority: 100 + text: "/ServerInfo/Guidebook/ServerRules/BanDurations.xml" diff --git a/Resources/Prototypes/Guidebook/ss14.yml b/Resources/Prototypes/Guidebook/ss14.yml index c1017fefcae..5b1f1dd8f97 100644 --- a/Resources/Prototypes/Guidebook/ss14.yml +++ b/Resources/Prototypes/Guidebook/ss14.yml @@ -3,6 +3,7 @@ name: guide-entry-ss14 text: "/ServerInfo/Guidebook/SpaceStation14.xml" children: + - SpaceLaw - Controls - Jobs - Survival diff --git a/Resources/ServerInfo/Guidebook/ServerRules/BanDurations.xml b/Resources/ServerInfo/Guidebook/ServerRules/BanDurations.xml new file mode 100644 index 00000000000..2c85346b49d --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/BanDurations.xml @@ -0,0 +1,17 @@ + + # Ban Durations + + Bans can be appealed at forum.ss14.io in the ban appeals section. + + ## Temporary + Temporary bans will be lifted automatically after a certain amount of time. If they are a game ban, they will tell you how much time is remaining when you try to connect. + + ## Indefinite + These bans will only be removed on a successful appeal on the forums. Any ban which doesn't tell you when it expires and doesn't specify otherwise can be presumed to be an indefinite ban. + + ## Voucher + This is an indefinite ban which may only be appealed both with a successful appeal and which require a voucher of good behavior from the administrative team of a well-known or at least decently active SS13/SS14 server in order for the appeal to be considered. Voucher bans typically cannot be appealed for at least six months after being issued. Without a voucher, a player can only attempt to appeal a voucher ban once, and only if the ban was inappropriately placed. Voucher bans are typically only placed as a result of an unsuccessful appeal of an indefinite game ban by players with a history of bans and of causing issues. + + ## Permanent + This is a ban that is only appealable if the ban was inappropriately placed, including if the ban should not have been permanent. If the result of the appeal is that the ban was appropriately placed, the ban may not be appealed again and will not be lifted. These bans are extremely rare, but are applied to players who continually cause problems even after a voucher ban or users who have completely unacceptable behavior may be permanently removed. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/BanTypes.xml b/Resources/ServerInfo/Guidebook/ServerRules/BanTypes.xml new file mode 100644 index 00000000000..b10ea3c393b --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/BanTypes.xml @@ -0,0 +1,11 @@ + + # Ban Types + + Bans can be appealed at forum.ss14.io in the ban appeals section. + + ## Role Ban + Also called a "job ban", this ban prevents your character from joining or late-joining a round as one or more jobs or roles. These are often used in response to problematic behavior in particular departments or address gross inexperience in important roles such as heads of staff. These bans do not mechanically prevent you from switching to the role during a round or acting as that role, but doing so is considered ban evasion. + + ## Game Ban + Also called a "server ban", this ban prevents you from connecting to all Wizard's Den servers. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC0.xml b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC0.xml new file mode 100644 index 00000000000..7b8cfbcf61e --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC0.xml @@ -0,0 +1,19 @@ + + # Core Rules + These rules apply at all times, including between rounds. + + - [textlink="1. Admins have final say" link="RuleC1"] + - [textlink="2. Don't be a dick" link="RuleC2"] + - [textlink="3. No Hate Speech or Discriminatory Language" link="RuleC3"] + - [textlink="4. No sexual content/themes, including erotic roleplay (ERP) and no shock content" link="RuleC4"] + - [textlink="5. Do not use out of game methods to communicate with other players" link="RuleC5"] + - [textlink="6. Do not attempt to evade bans" link="RuleC6"] + - [textlink="7. Only use English" link="RuleC7"] + - [textlink="8. Do not exploit the game, use cheats, or macros" link="RuleC8"] + - [textlink="9. Do not use multiple accounts, or alt accounts, and do not share accounts" link="RuleC9"] + - [textlink="10. Do not abuse or ignore admin messages" link="RuleC10"] + - [textlink="11. Do not threaten to ahelp other players or argue with them about rules" link="RuleC11"] + - [textlink="12. Players must be and act at least 16 years old" link="RuleC12"] + - [textlink="13. Use realistic character names, and do not use names of famous people" link="RuleC13"] + - [textlink="14. Do not use LOOC or OOC to share current round information" link="RuleC14"] + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC10AHelp.xml b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC10AHelp.xml new file mode 100644 index 00000000000..2d639c5b84a --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC10AHelp.xml @@ -0,0 +1,29 @@ + + # Core Rule 10 - Do not abuse or ignore admin messages + Admin help, or "ahelp", is the system used by admins to communicate with specific players in the game. Only use admin help for things requiring admin attention. If you ignore messages admins send to you via ahelp, or disconnect during an ahelp, you may be banned. If you urgently need to leave during an ahelp, you may do so but will likely need to continue the ahelp on the forums. Do not admin check, be hostile/aggressive, request events, or spam. IC methods of contacting admins, like prayers, faxes, red phones, and banana phones, should be used when there is not an issue. + + Admins are not always online, but all ahelps are automatically relayed to discord. For various reasons, admins might not respond to an ahelp even if they've handled it. A lack of response does not necessarily mean that an ahelp was ignored. + + ## Should I ahelp X? + You can ahelp anytime you genuinely think a player is breaking a rule. Not all ahelps end up being for something that an admin needs to intervene in, but that's ok, admins would rather have people occasionally report things that turn out to not be an issue than miss reports for actual issues because someone was unsure, or get those reports late because someone waited until the end of the round to be more sure. + + The most common reason players give for not ahelping issues is that they don't want to waste admin time, but it only takes a few seconds for an admin to check if someone is an antagonist. If you are ahelping too many things, an admin will let you know. If you're not being told to stop reporting something or to report less things, then you can safely assume that you aren't causing any issues. + + # What should I include in an ahelp? + At a minimum, admins need to know what the issue is to be able to address an ahelp. Don't send ahelp messages with no information about what your question or the issue is. Messages like "hello" are often considered admin checking. + + If you can, an ideal ahelp message includes what the issue is along with who is causing it and their character's name if possible. + + # Examples + Appropriate uses of ahelp: + - reporting people who you think are violating rules, + - asking questions about rules, + - asking for a temporary exemption from a rule, and + - request a minor gimmick, like a TC trade or item spawn. + + Inappropriate uses of ahelp: + - checking if an admin is online, including sending messages without any information about the issue like "hello" or incomprehensible messages, + - being hostile or aggressive, + - requesting events, and + - spamming messages about the same issue. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC11AhelpThreats.xml b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC11AhelpThreats.xml new file mode 100644 index 00000000000..47420264946 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC11AhelpThreats.xml @@ -0,0 +1,20 @@ + + # Core Rule 11 - Do not threaten to ahelp other players or argue with them about rules + Don't threaten to ahelp a player, don't tell them you are ahelping them, and don't tell them you did ahelp them. You can argue in character about Space Law, but do not argue about whether something is or is not against the rules. If you think someone is breaking a rule, ahelp them. If you don't think someone is breaking a rule, don't ahelp them. Either way, the best thing that you can do once you after is to continue in-character. + + ## Example Scenario 1 + You are a security officer and think someone who is causing a ton of problems for security is not an antag and is breaking the rules by doing so. + + [color=#a4885c]Good:[/color] Since you think they are breaking a rule, you ahelp them when you're able to. You continue in-character by arresting them for the crimes that they committed. + + [color=#a4885c]Bad:[/color] You decide not to ahelp them. You kill them and tell them "you're lucky I didn't report you to the admins". + + [color=#a4885c]Bad:[/color] Since you think they are breaking a rule, you ahelp them when you're able to. You arrest them for the crimes that they committed and tell them "I ahelped you so enjoy your ban". + + ## Example Scenario 2 + A mouse is using emotes to bypass speech restrictions. + + [color=#a4885c]Good:[/color] You ahelp them then respond in-character by acting like you can't understand what the mouse is doing. + + [color=#a4885c]Bad:[/color] You use in character chat to tell the mouse that it is breaking a rule. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC12MinAge.xml b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC12MinAge.xml new file mode 100644 index 00000000000..baa30a09faf --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC12MinAge.xml @@ -0,0 +1,6 @@ + + # Core Rule 12 - Players must be and act at least 16 years old + All players must be at least 16 years old. Additionally, all players must act at least as mature as a 16 year old. Admins may ban someone who they believe is acting less mature than a 16 year old, even if the player is known to be significantly older than 16 years old. + + Anyone who connects to the servers is a player, even if they don't actually play in a round. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC13CharacterNames.xml b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC13CharacterNames.xml new file mode 100644 index 00000000000..ec393ecdc17 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC13CharacterNames.xml @@ -0,0 +1,66 @@ + + # Core Rule 13 - Use realistic character names, and do not use names of famous people + - No names of people or characters from the real world + - No titles/honorifics + - Must follow all other rules (no slurs/sexual names/etc) + - Usernames, objects, random characters, very "low effort" names, "meta" names, or otherwise implausible names cannot be used as names. See examples below. + - Admin rulings on IC names are final and disputes should be done through the forums, not by refusing to comply with an admin + + ## Clarification on "Meta" Names + Meta names are ones which attempt to take advantage of some game mechanic or game design choice. "Urist McHands" is a meta name because it is the default name used for admin spawned humans. "Operator Whiskey" is a meta name because it follows the naming pattern of nuclear operatives. This rule is not intended to prevent things like nuclear operatives using a fake ID with names that appear to be nuclear operative names if they decide that they want to do that. + + ## Conventions and Examples + [color=#994444]Bad[/color] cannot be used by any species. [color=#449944]Acceptable[/color] names can be used by any species. + + Humans typically use the Firstname Lastname convention. + - [color=#449944]Acceptable:[/color] Tom Fisher + - [color=#449944]Acceptable:[/color] Spacey Chapman + - [color=#994444]Bad:[/color] Dr. Tom Fisher + - [color=#994444]Bad:[/color] Walter White + - [color=#994444]Bad:[/color] George Washington + - [color=#994444]Bad:[/color] Joe Biden + - [color=#994444]Bad:[/color] Ben Dover + - [color=#994444]Bad:[/color] Mike Hunt + + Dwarfs typically use the human convention in a viking theme. + - [color=#449944]Acceptable:[/color] Ingrid Firebreath + - [color=#449944]Acceptable:[/color] Erik Lightningclaw + + Lizards typically use the Verb-article-Noun convention. + - [color=#449944]Acceptable:[/color] Cleans-the-Airlocks + - [color=#994444]Bad:[/color] Bans-the-Admins + + Slimes typically have names that are onomonopia. A last name is optional. + - [color=#449944]Acceptable:[/color] Foolp Suub + - [color=#449944]Acceptable:[/color] Foolp + - [color=#994444]Bad:[/color] Slime + + Diona typically have calm, nature themed, Noun of Noun style names. + - [color=#449944]Acceptable:[/color] Petal of Tranquility + - [color=#449944]Acceptable:[/color] Garden of Relaxation + - [color=#994444]Bad:[/color] Tree but Alive + + Mothmen typically use latin sounding names, or light themed names. + - [color=#449944]Acceptable:[/color] Socrates Temnora + - [color=#449944]Acceptable:[/color] Sierra Lightseeker + - [color=#449944]Acceptable:[/color] James Nightflitter + + Arachnids typically use latin sounding names. + - [color=#449944]Acceptable:[/color] Argyroneta Reticulatus + - [color=#449944]Acceptable:[/color] Loxosceles Domesticus + - [color=#994444]Bad:[/color] Spider-Man + + Usernames, objects, random characters, very "low effort" names, "meta" names, or otherwise implausible names are not permitted. + - [color=#994444]Bad:[/color] XxRobustxX + - [color=#994444]Bad:[/color] SDpksSodjdfk + - [color=#994444]Bad:[/color] Lkdsoisgoieun + - [color=#994444]Bad:[/color] F4ith H3arth + - [color=#994444]Bad:[/color] Greytide + - [color=#994444]Bad:[/color] Passenger + - [color=#994444]Bad:[/color] Urist McHands + - [color=#994444]Bad:[/color] Admin + - [color=#994444]Bad:[/color] Game-Master + - [color=#994444]Bad:[/color] Joe Mamma + - [color=#994444]Bad:[/color] Middle-Aged Man + - [color=#994444]Bad:[/color] Operative Whiskey + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC14ICinOOC.xml b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC14ICinOOC.xml new file mode 100644 index 00000000000..44ad34deb66 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC14ICinOOC.xml @@ -0,0 +1,13 @@ + + # Core Rule 14 - Do not use LOOC or OOC to share current round information + Local Out of Character (LOOC) and Out of Character (OOC) channel are meant for things that don't relate to the current round. Using these channels to share round info is often referred to as "IC in OOC" or "ick ock". + + ## Examples + Things you should [color=#a4885c]not[/color] do: + - Use LOOC to tell someone you are an antagonist. + - Use LOOC to tell someone that your character is not lying. + + Things you could do instead: + - Use codewords in-character. + - Try to convince them that you are not lying in-character, or accept that you won't be able to convince them. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC1Admins.xml b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC1Admins.xml new file mode 100644 index 00000000000..ed9fa6133b9 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC1Admins.xml @@ -0,0 +1,6 @@ + + # Core Rule 1 - Admins have final say + These rules are not perfect. The rules attempt to clearly communicate what the admin team intends to be allowed and prohibited, but there are likely loopholes or other flaws that can be "lawyered". Don't attempt to manipulate the interpretation of the rules to suit your personal goals or to degrade the experience of other players. If you are unsure of something, follow the more restrictive option until you are able to ask an admin and get clarification. + + Admins can override rules if they deem it in the best interest of the current round, server, and/or community at large. Online admins are able to make final interpretations of rules during a round. Even if you disagree with how an admin interprets a rule, you must still follow the interpretation they provide for you. Admin actions and interpretations of rules can be contested through staff complaints. If admins believe that you are an overall negative impact to the community or rounds, you will be banned. Admins will be held fully accountable for their actions if they exercise this privilege. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC2DBAD.xml b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC2DBAD.xml new file mode 100644 index 00000000000..5678cde195d --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC2DBAD.xml @@ -0,0 +1,7 @@ + + # Core Rule 2 - Don't be a dick + Don't do anything with the goal of negatively affecting other players. Not everyone is going to enjoy every round. Killing someone is allowed in certain situations even though it might negatively affect them, but no one should be doing anything for the purpose of harming someone else's experience. + + ## MRP Amendment + Do not interact negatively with SSD/AFK players. Interactions to complete antagonist objectives or duties like security searches/arrests are always permitted. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC3NoHate.xml b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC3NoHate.xml new file mode 100644 index 00000000000..3a2e288ba9f --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC3NoHate.xml @@ -0,0 +1,20 @@ + + # Core Rule 3 - No Hate Speech or Discriminatory Language + This is a zero tolerance rule. + + This rule prohibits all the following: + - Hate Speech + - Slurs (including variations of slurs, racial, sexual, disability-related, or language closely tied to real-life slurs) + - Bigotry + - Racism (including Speciesism, which would be demeaning other players based on their in-game race) + - Sexism + + ## Examples + Allowed: + - Telling someone that you are gay. + + Prohibited: + - Calling someone gay in a context where gay is used as an insult or negative attribute. + - Using a racial slur or variant in a positive context. + - Using the word "retard" in any context. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC4NoERP.xml b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC4NoERP.xml new file mode 100644 index 00000000000..a0921f59070 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC4NoERP.xml @@ -0,0 +1,23 @@ + + # Core Rule 4 - No sexual content/themes, including erotic roleplay (ERP) and no shock content + This is a zero tolerance rule. + + Erotic Roleplay (commonly abbreviated as "ERP") and sexual content is not allowed. This includes direct and indirect mentions of sexual behavior or actions. Slight leeway is given to insults, but this rule is otherwise strictly enforced. + + In-game romantic relationships should not become the focus of the game for you and anyone else involved. + + Things that appear to be intended to or are likely to disturb players out of character are considered shock content and are not allowed. + + ## Examples + Allowed: + - Telling someone that they are being a dickhead. + - Telling someone that you are going to kill the captain, as long as it is clear that you mean it in character. + + Prohibited: + - Emoting sexual acts. + - Erotica content. + - Erotic or sexual memes. + - Memes which contain sexual content. + - Dedicating significant portions of rounds to romantic relationships, dating, or similar things. + - Emoting defecation or related acts. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC5Metacomms.xml b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC5Metacomms.xml new file mode 100644 index 00000000000..0c0f336e6d0 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC5Metacomms.xml @@ -0,0 +1,18 @@ + + # Core Rule 5 - Do not use out of game methods to communicate with other players + This is a zero tolerance rule. + + Do not utilize any external means of communication to talk to other players who are connected to the same server, or who were connected to the same server during the current round. This is referred to as "metacomming" and includes any means of communication including text, voice, images, and video. This includes applications such as Discord, Steam, and other platforms, along with in-person communication. + + Even if information is not being shared or abused, it may still be considered a violation of this rule. Due to the difficulty of determining if information is being shared, it will almost always be presumed that people who message another player they are in a round with, or who are in a voice call with another player during a round are sharing round information. Due to the difficulty of determining if users are abusing information that they are sharing, it will almost always be presumed that the information is being abused. + + The only exemption to this rule is when [color=#a4885c]all[/color] players are in the server lobby. + + ## Teaching new players + Teaching players is not exempt from this rule. If you want to teach a new player, it is recommended to either watch a stream of them playing the game while not playing yourself, or communicate with them using only in-game methods of communication. + + ## Streaming + Public livestreams are not exempt from this rule, but have different liability. Using information from a public live stream of the game (stream sniping) is a violation of this rule. Watching a public live stream of the game while connected to the same server is a violation of this rule. Allowing people watching a public live stream to share information about the current round, for example through the stream's chat, is a violation of this rule. Using that information is also a violation of this rule. Sharing information about the current round with a streamer is a violation of this rule if that information was obtained from any source but the stream. The stream's moderators are expected to enforce this on the streaming platform in addition to any in-game enforcement done by game admins. + + Public livestreaming by itself is not a violation of the rule as long as the stream is sufficiently moderated. Streamers are encouraged, but not required, to use a stream delay. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC6BanEvasion.xml b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC6BanEvasion.xml new file mode 100644 index 00000000000..bec8b4fabd7 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC6BanEvasion.xml @@ -0,0 +1,15 @@ + + # Core Rule 6 - Do not attempt to evade bans + This is a zero tolerance rule. + + Almost all bans may be appealed on our forums at forum.ss14.io in the ban appeals section. This is generally the only acceptable way to contact the administration team to discuss your ban and revise it if it is inappropriate, including if it is mistakenly applied. + + Any attempt to circumvent or bypass a game ban will result in a voucher ban. Attempting to evade role bans by gaining access to or working in the capacity of a job you are banned from will result in a game ban. These bans are applied even if the evasion attempt is unsuccessful. + + ## Exceptions + There are no exemptions for evading or attempting to evade game bans. Antagonists who impersonate or take over a role which they are banned from to aid in their goals are not considered to be evading their role ban. + + ## Additional Information + - [textlink="Ban Types" link="BanTypes"] + - [textlink="Ban Durations" link="BanDurations"] + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC7EnglishOnly.xml b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC7EnglishOnly.xml new file mode 100644 index 00000000000..630c522bcef --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC7EnglishOnly.xml @@ -0,0 +1,10 @@ + + # Core Rule 7 - Only use English + Only English is permitted, both in-character and out-of-character. You must be fluent in English enough to be able to not cause game issues, and to be able to communicate with game admins when necessary. If a game admin does not feel that you are fluent enough in English, they may ban you. + + ## Why + We do not have enough staff fluent in other languages to moderate them. Translation tools can be unreliable and are not integrated well into the game. + + ## Non-English Options + There are many servers that allow or focus on other languages. You are highly encouraged to play only on servers that allow languages you are fluent in. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC8Exploits.xml b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC8Exploits.xml new file mode 100644 index 00000000000..48cbaaa9acf --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC8Exploits.xml @@ -0,0 +1,12 @@ + + # Core Rule 8 - Do not exploit the game, use cheats, or macros + The following are prohibited by this rule: + - bugs and exploits which have effects that persist beyond the current round, + - intentionally used bugs, exploits, and unintended behaviors which give the user an advantage over players who do not use them, even if their effects do not persist across rounds, + - evading or bypassing afk detection, + - anything which results in gaining elevated privileges, including admin permissions, + - external tools and client modifications, including macros, and + - anything which prevents another player who is not game banned from being able to play on the servers, not including in-character actions that do not persist across rounds. + + Both attempts and successful use are prohibited. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC9Multikey.xml b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC9Multikey.xml new file mode 100644 index 00000000000..d402918dcd4 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/CoreRules/RuleC9Multikey.xml @@ -0,0 +1,7 @@ + + # Core Rule 9 - Do not use multiple accounts, or alt accounts, and do not share accounts + Use of multiple accounts is referred to as "multikey". the rule applies even if the accounts are not used at the same time, including if the old account is abandoned. All accounts may be banned if this rule is violated. You are responsible for everything done on and with your account. You are just as responsible for actions taken by other people using your account as you would be had you taken the actions themselves. + + ## Switching to a new account + If you lose access to an account, you must contact game admins on the forums notifying admins before using a new account to connect to the servers. Your message to game admins must include the username of your old account. Creating a new account while your current account is banned will be considered ban evasion. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/DefaultRules.xml b/Resources/ServerInfo/Guidebook/ServerRules/DefaultRules.xml new file mode 100644 index 00000000000..3e19fefeedc --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/DefaultRules.xml @@ -0,0 +1,5 @@ + + # Server Rules + + This server has not written any rules yet. Please listen to the staff. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/README.txt b/Resources/ServerInfo/Guidebook/ServerRules/README.txt new file mode 100644 index 00000000000..d7ac858c16f --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/README.txt @@ -0,0 +1,5 @@ +These files contain Wizard's Den server rules. Since they reference Wizard's Den, they should not be used +by other servers without at least enough modification to not mislead players into thinking that they are +playing on Wizard's Den. + +The filenames used for the rules files are not themselves rules. Only the contents of the files are rules. diff --git a/Resources/ServerInfo/Guidebook/ServerRules/RoleTypes.xml b/Resources/ServerInfo/Guidebook/ServerRules/RoleTypes.xml new file mode 100644 index 00000000000..d5373a730a3 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/RoleTypes.xml @@ -0,0 +1,21 @@ + + # Role Types + + ## Crew Aligned/Non-antagonist + In most rounds, a majority of players will be non-antagonists, meaning that they are crew aligned. This is the "default" role, if the game doesn't tell you that you are one of the other roles defined here, then you are a non-antagonist. Overall, non-antagonists are intended to work towards a net positive effect on the round. + + ## Solo Antagonist + Certain roles are intended to cause problems for the round or for non-antagonists. You are only a solo antagonist if the game clearly and explicitly tells you that you are a solo antagonist. Antagonists are exempt from many but not all roleplay rules. + + ## Team Antagonist + Team antagonists are like solo antagonists but they have other antagonists who they are expected to not hinder, and who they may be expected to help. You are only a team antagonist if the game clearly and explicitly tells you that you are a team antagonist. + + ## Free Agent + Certain roles are free to choose if they want to behave as an antagonist or as a non-antagonist, and may change their mind whenever they'd like. You are only free agent if the game clearly and explicitly tells you that you are a free agent. + + ## Familiar + Familiars are considered non-antagonists, but have instructions to obey someone. They must obey this person even if it causes them to violate roleplay rules or die. You are only a familiar if the game clearly and explicitly tells you that you are a familiar. You are only the familiar of the person the game tells you. + + ## Silicon + Silicones have a set of laws that they must follow above all else except the core rules. You are only silicon if the game clearly and explicitly tells you that you are a silicon. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR0.xml b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR0.xml new file mode 100644 index 00000000000..07b176b359a --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR0.xml @@ -0,0 +1,26 @@ + + # Roleplay Rules + These rules only apply during a round. A round ends only when the round summary has appeared. All of these rules apply fully until the moment that the round summary appears, even while the arrivals shuttle is in transit. + + The deathmatch and sandbox game modes are exempt from these rules. Players who choose to not follow these rules are entirely responsible for knowing if an exempt game mode is active. + + Roleplay rules do not apply to ghosts/spectators/observers while they are ghosts/spectators/observers. Dead chat is considered to be an in-game out of character chat channel. + + See the list of [textlink="role types" link="RoleTypes"] for more information about the different types of roles. + + - [textlink="1. Silicones must follow Silicon Rules" link="RuleR1"] + - [textlink="2. Familiars must obey their master" link="RuleR2"] + - [textlink="3. Roleplay a normal person" link="RuleR3"] + - [textlink="4. Do not metagame, obey the Metashield" link="RuleR4"] + - [textlink="5. Don't interfere with arrivals" link="RuleR5"] + - [textlink="6. Don't act like an antagonist unless the game tells you that you are one" link="RuleR6"] + - [textlink="7. Do not stall the round" link="RuleR7"] + - [textlink="8. As an antagonist, only be friendly to your team and don't work against your team" link="RuleR8"] + - [textlink="9. As an antagonist, do not cause excessive death, damage, or destruction beyond your objectives" link="RuleR9"] + - [textlink="10. Listen to your team leader" link="RuleR10"] + - [textlink="11. Follow reasonable escalation" link="RuleR11"] + - [textlink="12. Do not abandon your role" link="RuleR12"] + - [textlink="13. Stick to your role" link="RuleR13"] + - [textlink="14. Set an example if playing command or security" link="RuleR14"] + - [textlink="15. Command and Security must follow Space Law" link="RuleR15"] + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR10Subordination.xml b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR10Subordination.xml new file mode 100644 index 00000000000..2147ddc1110 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR10Subordination.xml @@ -0,0 +1,26 @@ + + # Roleplay Rule 10 - Listen to your team leader + Captains lead all departments and other members of command. Department heads lead members of their department. Certain antagonist teams have team leaders, like nuclear operative commanders or head revolutionaries. You are not required to perfectly follow orders given to you by your leaders, but you should generally allow your leaders to lead and not interfere with their ability to. You can choose to ignore unreasonable orders, including ones which are will result in your death unless you are an antagonist with an objective that requires you to die. + + Team antagonists have to listen to the leader of their antagonist team. Team antagonists do not have to listen to any other leaders, including leaders of other antagonist teams. Solo antagonists do not have to listen to any leaders at all. + + ## Examples + Acceptable: + - A traitor ignores orders from a nuclear operative commander. + - An antagonist ignores orders from the captain. + - An engineer tells the Chief Engineer that they don't think it's a good idea to setup the singularity, but does so anyway when ordered to. + - An engineer tells the Chief Engineer that they don't know how to setup the singularity correctly, so refuses orders to, but accepts an offer to be taught how. + - An atmospheric technician refuses an order from the captain that would create an atmospheric hazard on the station. + - A doctor refuses an order from the Chief Engineer about who to give medical treatment to first. + - A revolutionary refuses a suicide mission from a head revolutionary. + - The Chief Engineer doesn't follow an order from the captain to setup backup power because there is an unrelated engineering emergency that the Chief Engineer needs to prioritize. + - The captain orders command to give the nuclear authentication disk to nuclear operatives, so command arrests the captain and picks a new captain. + - The research director orders scientists to say "Long live Nanotrasen!" every time they enter the bar. The scientists say they will, but don't follow the order. + + Prohibited: + - A nuclear operative ignores an order from the commander operative because they don't like the plan. + - The Chief Engineer refuses an order from the captain to setup backup power because the Chief Engineer doesn't think backup power is necessary. + - An engineer refuses an order from the Chief Engineer to setup the singularity because they prefer a different power source. + - An engineer refuses to perform a task because they don't know how to do it, and refuses to be taught for no reason. + - A head revolutionary orders revolutionaries to blend in and not do anything illegal until they are told to reveal themselves. Instead, revolutionaries collect weapons and attack security. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR11-1AnimalEscalation.xml b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR11-1AnimalEscalation.xml new file mode 100644 index 00000000000..36655ba8414 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR11-1AnimalEscalation.xml @@ -0,0 +1,36 @@ + + # Roleplay Rule 11-1 - Escalation Involving Animals + Escalation rules are looser with animals than with people. These looser requirements do not apply to the requirements other people attacking each other have, even if their fighting is directly related to the conflict involving the animal. + + Non-pets, such as mice and monkeys, can be freely killed with any IC reason such as pest control, or for food. These roles are often available in numbers as ghost roles, so removing one from the round doesn’t typically remove them all. + + Pets, including but not limited to Ian, Renault, Remilia, and Hamlet, cannot be freely killed, they require escalation. These roles are often available once per round at most, except roles like Remilia. + + Permanently trapping an animal, such as putting a mouse in a plant, is considered similar to killing the animal so should only be done with an IC reason. + + Both sides can escalate much more rapidly than they'd be able to if both were people. Animals are often more limited in the maximum force they can use compared to people, which limits the negative effects of them rapidly escalating. Animals also typically have less health than people, and are limited in the ease with which they can get healing, which justifies them responding to even weak attacks more severely. + + Neither the animal nor the person is obligated to get the other medical attention if they are put into crit. Attacking someone to death rather than stopping once they are in crit is considered a significant difference. While sufficient escalation may justify continuing to attack, generally people and pets shouldn't continue to be attacked once in crit, but non-pets may be. Gibbing is also considered a significant step because it prevents cloning or resuscitation. The fact that an animal made the last hit putting someone into crit does not allow people who fought on the side of the animal to not attempt to get them medical attention. + + The use of sensible, non-targeted mousetraps is not a conflict and does not require escalation. + + The killing or attacking of pets can be treated as an escalation step by players with a genuine IC connection to the animal. Generally, all crew can consider themselves to have an IC connection to any station pets. The degree of escalation should be proportional to the connection to the pet, in addition to the usual requirement of being proportional to the attack. For example, an attack on Ian can be treated nearly identically to an attack on a crewmember, whereas an attack on a pet mouse is much less severe. Normal escalation limits still apply, you cannot attack people who defended themselves from an animal that randomly attacked them, just as you could not attack someone who defended themselves from a coworker that randomly attacked them. + + Crew can "adopt" non-pets, like mice, and consider themselves to have a connection to the animal if they roleplay the adoption well. This does not affect the requirement of whether other players are required to apply escalation rules to these animals, it only creates a connection that can be used to justify retaliatory escalation to attacks by the adopter. Simply saying that they've adopted an animal is not sufficient, but carrying it with them is. The degree of connection is proportional to IC actions. Crew cannot consider themselves to have a connection for escalation purposes to animals which are typically hostile, such as space carp or bears. + + ## Examples + Acceptable: + - A chef kills mice who enter or approach their kitchen. + - A janitor kills mice roaming the station. + - A lizard kills a mouse to eat. + - A chef has carried a mouse around in their hat for the last 10 minutes, they put the mouse down for a moment and another player kills it. The chef responds by attacking the other player with their fists and refusing them service for the rest of the shift. + - Ian is randomly attacked, a crewmember who sees this happen crits the killer and brings them to security. + - Hamlet goes into the kitchen and starts eating all the food. A chef sees this and starts swinging their knife at Hamlet. Hamlet starts biting the chef and crits them, then resumes eating. + + Prohibited: + - A janitor throws an armed mousetrap at Hamlet for no reason. + - Hamlet starts biting random people, trying to crit them, for no reason. + - A crewmember attacks security for killing a space carp they adopted. + - Ian gibs someone who was trying to kill someone. + - Hamlet attacks security for trying to arrest someone he likes. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR11-2ConflictTypes.xml b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR11-2ConflictTypes.xml new file mode 100644 index 00000000000..3261d78b35a --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR11-2ConflictTypes.xml @@ -0,0 +1,30 @@ + + # Roleplay Rule 11-2 - Examples of Conflict Types + ## Verbal + - Shouting + - Yelling + - Insulting + + ## Non-harmful + - Shoving + - Stealing non-critical items, like easily replaced tools + + ## Non-lethal + - Stealing items without endangering someone's life, like a clown's pie cannon or the HoP's fax machine + - Stealing someone's ID somewhere that doesn't result in them being trapped + - Punching + - Disablers + - Stun batons + + ## Lethal + - Punching to crit or death + - Attacking with strong weapons, like bats + - Stealing items that endanger someone's life, like a hardsuit + - Stealing someone's ID, trapping them in a dangerous situation + + ## Permanently lethal + - Gibbing + - Not taking someone who you killed or put into crit to the medbay or security + - Hiding someone's body + - Spacing someone's body + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR11Escalation.xml b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR11Escalation.xml new file mode 100644 index 00000000000..6f91fa0fb12 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR11Escalation.xml @@ -0,0 +1,67 @@ + + # Roleplay Rule 11 - Follow reasonable escalation + Antagonists are fully exempt from escalation rules. Non-antagonists who are in a conflict with antagonists are not exempt. Escalation should typically follow steps or a pattern of conflict types similar to: + - Verbal + - Non-harmful + - Non-lethal + - Lethal + - Permanently lethal + + All new conflicts should start at the first step. A player should not escalate a conflict across steps without some escalation from the other party involved in the conflict. Players can skip steps to match the level of escalation that the other person is at, but should almost always not skip steps other than that. Players who attempt to deescalate conflicts will be given more leniency in escalating if the other party continues to escalate despite the attempt at de-escalation. You do not have to try to deescalate conflicts, but someone who watches you over the entire round, or over multiple rounds, should not feel that your goal is generally to escalate conflicts. + + Conflicts or escalation can be indirect. When someone steals someone else's ID, the theft is a direct part of the conflict, but if the victim becomes trapped as a result of not having their ID to open a door, that is also considered part of the conflict and escalation. Do not randomly steal IDs from people. + + Escalation does not have to be directed at a specific player to enter them into a conflict. Nuclear operatives who are trying to destroy the station are considered to be at the permanently lethal level of conflict with all crew on the station. Someone who kills a station pet has started some degree of conflict with all crewmembers. Someone who kills a mouse that a chef was caring for has started some degree of conflict with that chef. + + You will be considered to be violating this rule if you escalate a conflict based on a poor or unreasonable assumption. + + Conflicts should almost never reach the "permanently lethal" stage. Conflicts should only reach this stage if the other party brought it to the stage, or if the same conflict escalated to the lethal stage multiple times in the round. + + If a party in the conflict goes into crit or dies, the party responsible should take them to get treatment or to security. For the conflict, this should be considered saving someone from dying and should deescalate the conflict. If the conflict is deescalated in this way, both parties need to re-escalate to lethal for the conflict to return to that stage. If the conflict is not deescalated in this way, then only the party who defeated the other would need to re-escalate for the conflict to return to the lethal stage. + + Security can immediately escalate to non-lethal force if it is necessary to arrest someone. + + People using or brandishing Syndicate items can typically be presumed to have lethal intent. Someone with lethal intent can typically be immediately escalated against at a lethal level, a notable exception is if you have the tools to safely detain them. + + ## Escalation Involving Animals + See [textlink="Escalation Involving Animals" link="RuleR11-1AnimalEscalation"]. + + ## Exemptions + Escalation rules aren't enforced against non-players, but players will be held responsible for rule violations even if they don't realize that a character or animal was controlled by another player. Characters who have purple text saying that they are catatonic are considered non-players. Characters who are disconnected are still considered players. + + ## MRP Amendment + Escalation rules are enforced even against non-players. + + ## Examples of Conflict Types + See [textlink="Examples of Conflict Types" link="RuleR11-2ConflictTypes"]. + + ## Example Scenarios + These examples assume that you are not an antagonist. + + Acceptable: + - A player starts punching you, so you start punching back until they stop. If they go into crit, you stop attacking them and take them to security or to get medical attention. + - You make fun of a clown, who then throws a pie at you and steals your shoes. You slip the clown and steal their mask. + - You are a security officer and tell someone to stop, so you can question them. They run away, so you use your disabler to stun and cuff them. + - You are a security officer and see someone wearing a syndicate hardsuit, so you shoot them to crit, cuff them, then take them to security. + - You are a crewmember and see a nuclear operative, so you kill them. + - An unauthorized person enters a high risk area of the station, like the armory or atmospherics, so you attack them until they leave. + - Minorly inconveniencing someone for your own benefit. + - As an antagonist, killing someone who got in your way. + - As an antagonist, killing someone who didn't give you what you want. + - A chef and bartender reach the lethal level of conflict through appropriate escalation. The chef crits the bartender and does not take them to medbay or security. The bartender immediately tries to crit the chef next time they run into each other. + - A chef and bartender reach the lethal level of conflict through appropriate escalation. The chef crits the bartender and does not take them to medbay or security. The chef insults the bartender next time they see them. + + Prohibited: + - A player starts punching you, so you gib them. + - A clown throws a pie at you and steals your shoes, so you stab them to crit with a screwdriver. + - You are a security officer and tell someone to stop so you can question them. They run away so you use a truncheon to beat them to crit. + - An authorized person who you think is unauthorized enters a high risk area of the station, like the armory or atmospherics, so you attack them until they leave. + - An unauthorized person enters a low risk area of the station, like cargo, and you start attacking them with no other escalation. + - Slipping security all round because they are security. + - Blocking the head of personnel in their office using walls because they didn't give you what you asked for. + - Hiding someone's body because they punched you earlier in the round. + - Harassing the bar or bartender by frequently coming in to break their glasses or furniture. + - Randomly picking fights with people. + - A chef and bartender reach the lethal level of conflict through appropriate escalation. The chef crits the bartender and does not take them to medbay or security. The chef immediately tries to crit the bartender next time they run into each other. + - A chef and bartender reach the lethal level of conflict through appropriate escalation. The chef crits the bartender and takes them to the medbay or security. The bartender immediately tries to crit the chef next time they run into each other. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR12RoleAbandonment.xml b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR12RoleAbandonment.xml new file mode 100644 index 00000000000..b2032bba023 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR12RoleAbandonment.xml @@ -0,0 +1,28 @@ + + # Roleplay Rule 12 - Do not abandon your role + Do not join the round as a role that you don't intend to play. Do not enable antagonist roles that you don't intend to play. Abandoning a role includes not completing tasks that the role is expected to do, in addition to things like leaving the game. Members of command should almost all stay on the station until the emergency shuttle arrives. Enforcement of this rule is more strict for command and antagonist roles, and less strict for less important roles like passengers. + + Violations of this rule typically result in temporary or indefinite role bans. We understand that you may need to leave round early or unexpectedly. If you are in an important role, you should notify command members or an admin via ahelp so that they know you are leaving. Space Station 14 is a game. Do not endanger the safety of yourself or others, and do not neglect important things to avoid leaving a round early, even if you have to leave immediately without notifying anyone. Role bans for disconnecting are typically only applied if there is a pattern, and are almost always temporary. + + "Antag rolling" refers to a player abandoning their role if they do not get an antagonist role. + + ## Examples + Acceptable: + - As an engineer, building a bar in maintenance while there is nothing important for engineering to do. + - As the captain, having the chef teach you how to cook while there is nothing important needing your attention. + - As a passenger, building a shuttle with materials given to you by cargo and engineering. + - Taking a short break from your job at the bar. + - Getting an antagonist role and doing the bare minimum needed to complete your objectives. + - Getting an antagonist role and making a genuine effort to complete your objectives, but failing to complete any. + - Getting an antagonist role and intentionally not doing any of your objectives, but creating a similar level of disruption that completing your objectives would create. + + Prohibited: + - As an engineer, building a bar in maintenance while the station has no power. + - As the captain, leaving the station to go on an expedition with the salvage team. + - As an atmospherics technician, building a shuttle round start and never coming back to the station. + - Spending your entire shift at the bar, even when there is work that needs to be done by your role. + - Ghosting, suiciding, or leaving at the start of a round because you don't like the map or the players in your department. + - Getting an antagonist role and not doing any antagonist activities. + - Ghosting, suiciding, or leaving at the start of a round because you did not get an antagonist role. + - Ghosting, suiciding, or getting yourself killed because nuclear operatives declared war, and you want to try to get an antagonist ghost role. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR13PerformRole.xml b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR13PerformRole.xml new file mode 100644 index 00000000000..7500cd6a912 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR13PerformRole.xml @@ -0,0 +1,26 @@ + + # Roleplay Rule 13 - Stick to your role + Requesting job changes is not prohibited by this rule. This rule is loosened if the station is understaffed or if there is a significant threat to you. + + Don't perform other people's jobs, especially where the relevance to you personally is low. This also covers performing the role of security. + + ## MRP Amendment + This is enforced more strictly on MRP. + + ## Examples + Acceptable: + - As an engineer, helping the bartender remodel the bar. + - As a bartender, remodeling the bar. + - As a passenger, building a maintenance bar. + - As an engineer, reinforcing substations. + - As an engineer, increasing the security of airlocks. + - As an atmospherics technician, improving atmospheric systems. + - As a passenger, fighting nuclear operatives. + - As a passenger, fighting or preparing to defend yourself from someone who has been trying to kill you. + - As a crewmember on a station with no engineering department, you complete engineering tasks. + + Prohibited: + - As a passenger, reinforcing substations. + - As a passenger, hunting for antagonists or lawbreakers. + - As a passenger, fighting or preparing to defend someone else from someone who has been trying to kill a random crewmember. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR14SecComStandard.xml b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR14SecComStandard.xml new file mode 100644 index 00000000000..ec06d61e8cc --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR14SecComStandard.xml @@ -0,0 +1,37 @@ + + # Roleplay Rule 14 - Set an example if playing command or security + All command and security roles are held to stricter interpretations of the rules. + - Command roles are not learning roles. Members of command must be competent. + - Security roles are not for inexperienced players. Members of security are expected to know game basics and be more familiar with server rules than a new player. + - Do not hinder or cause overall negative effects to the station or crew as a member of command or security. + - Do not abuse your power as command or security. + + ## Why + Members of command and security can often have a larger impact on the nature of the round than other players. For example, a captain who tries to bend or break the rules will often cause many others on the station to do the same. Memey station announcements from members of command also often result in the rest of the station acting the same way. When command and security members hold themselves to high standards, the rest of the station often naturally follows to a significant degree. + + ## Examples + Acceptable: + - A member of security accepts a bribe to deliver safe donuts to a prisoner who the HoS has ordered should only be given donk pockets. + - A captain uses a station announcement to confess to an embarrassing mistake that they made during the shift. + - In coordination with the head of security, a captain declares that the station will recognize the right to bear arms, so all crew can pick up a disabler at security. + - The chief medical officer gives a paramedic their portable crew monitor to help them complete their job. + - A syndicate agent is holding a crewmember hostage and threatens to kill them if the head of security doesn't give them their ID. Seeing no other safe option, the head of security hands over their ID to the syndicate agent, then begins working to re-secure it and capture the agent as soon as the hostage is safe. + - Nuclear operatives are attacking the station, so the captain and head of personnel both go to the armory and take a weapon. + - A majority of command votes to demote the captain for taking actions harmful to the station, then the head of security demotes the captain. + - The captain promotes the head of personnel to captain. + - Security releases an antagonist from the brig in exchange for the identities of other traitors. + + Prohibited: + - A member of security accepts a bribe to ignore a crime or help a prisoner escape. + - A captain sends a ASCII art trollface over station announcements or as a fax to central command. + - A captain declares that all contraband is legal. + - Command or security allow the use of Syndicate items outside extreme emergencies. + - The chief medical officer knowingly helps a syndicate agent complete their objectives. + - A syndicate agent has killed 3 members of security so the head of security makes them an offer saying that they will space all the weapons in the armory if the syndicate agent stops killing. + - The captain goes to the armory and takes a gun to display in his office without asking anyone, and orders anyone who questions him not to interfere. + - Members of command decide to demote the captain to gain more power for themselves, or in retaliation for a decision that they didn't personally like or agree with, rather than because the decision was actually harmful to the station. + - The captain promotes a random crewmember to captain. + - A member of command gives a random crewmember substantial additional access for no reason, unnecessarily, or for a poor reason. + - A member of command gives a random crewmember access to a high security area, like the armory or another member of command's office, for no reason, unnecessarily, or for a poor reason. + - Security releases an antagonist from the brig in exchange for the antagonist buying them contraband. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR15SpaceLaw.xml b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR15SpaceLaw.xml new file mode 100644 index 00000000000..e2d51d672a1 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR15SpaceLaw.xml @@ -0,0 +1,21 @@ + + # Roleplay Rule 15 - Command and Security must follow Space Law + All non-antagonist command and security roles must obey [textlink="Space Law" link="SpaceLaw"]. This includes non-antagonists who are promoted to or gain a position during the round in any way. This also includes non-antagonists who are acting as a security role. + + This prohibits use of syndicate items, including uplinks by command and security. + + ## Examples + Roles that are included: + - A security officer + - The Captain + - The Chief Engineer + - A passenger promoted to "bounty hunter" + - A mime promoted to "security mime" + + Roles that are not included: + - A passenger + - The clown + - An antagonist in any role + - A cyborg + - A passenger who is helping to fight off nuclear operatives + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR1Silicons.xml b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR1Silicons.xml new file mode 100644 index 00000000000..5898804d149 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR1Silicons.xml @@ -0,0 +1,4 @@ + + # Roleplay Rule 1 - Silicons must follow Silicon Rules + You are only silicon if the game clearly and explicitly tells you that you are a silicon. For players who are silicons, the Silicon Rules override all Roleplay Rules if there is any conflict. Silicon Rules do not override Core Rules. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR2Familiars.xml b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR2Familiars.xml new file mode 100644 index 00000000000..4f008e93c5a --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR2Familiars.xml @@ -0,0 +1,6 @@ + + # Roleplay Rule 2 - Familiars must obey their master + Familiars are considered non-antagonists, but have instructions to obey someone. They must obey this person even if it causes them to violate Roleplay Rules or die. You are only a familiar if the game clearly and explicitly tells you that you are a familiar. You are only the familiar of the person the game tells you. If your master dies, you can continue to attempt to fulfill orders given to you before they died. You can defend your master without an explicit order to, but must obey your master if they order you to not defend them. + + Masters giving orders that violate Roleplay Rules are the ones that will be held responsible for the rule violations. You can ahelp masters who you believe are breaking rules with an order. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR3NormalRP.xml b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR3NormalRP.xml new file mode 100644 index 00000000000..62c88d58ce8 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR3NormalRP.xml @@ -0,0 +1,20 @@ + + # Roleplay Rule 3 - Roleplay a normal person + - Do not use texting/messaging acronyms (ex: "lol", "wtf", "brb", "lmao", "thx", "sgtm") or emoticons (ex: ":)", "xD") in-character. + - Do not mention out-of-character (OOC) concepts like game admins or developers in character. + - Do not use emotes to bypass muted or accented speech. + - Do not use extremely low effort or impossible emotes. + + ## Examples + Things you should not do: + - Say "lol did u c wat just happened" using in-character chat. + - Say "an admin exploded him" using in-character chat. + - Emote "can you give me some cheese" as a mouse. + - Emote "motions for you to order guns" or "asks you to order guns in sign language" as a mime. + + Things you could do instead: + - Say "haha did you see what just happened?" + - Say "god blew him up" or "centcom must have bluespaced a bomb to him" + - Point at cheese + - Point at the cargo order console then emote "shoots finger guns" + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR4Metashield.xml b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR4Metashield.xml new file mode 100644 index 00000000000..2e263be896a --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR4Metashield.xml @@ -0,0 +1,103 @@ + + # Roleplay Rule 4 - Do not metagame, obey the Metashield + Something that is "shielded" cannot be known by your character during a round until the "revealing condition" happens. This also means that your character cannot do things based on "shielded" information. Knowing or acting on something that is shielded before the revealing condition is met is referred to as metagaming. + + Revealing conditions reveal the shielded information for the round, not for a specific instance. This means that once a revealing condition is met in a round, the shield no longer applies in any case for the remainder of the round. + + ## Never Revealed IC + Some shields are never revealed IC. This means that your character can never act as if they know about that shielded thing. + + The following are shielded: + - Current game mode and possible antags during the current game mode. + - Events from previous rounds. + - Events from previous characters. + - All information related to the player of a character rather than the character itself. (See "Metafriending and Metagrudging" below.) + - All information gained while dead or a ghost. + - The fact that a round will end. + + This does not prevent knowing that a shift will end, but does prohibit things like preparing to kill people at central command when roleplay rules stop being enforced on LRP. + + ## Nuclear Operatives + + The existence of Nuclear Operatives beyond a myth that no one would act on is shielded. + + The fact that the nuke disk must be protected and could be used by a bad actor to try to destroy the station is not shielded. + + The revealing condition for this shield is any of the following: + - discovering a blood red hardsuit + - an operative name + - a War Ops announcement + - being a nuclear operative + + ## Implanted Implants + + Implanted implants are shielded. + + Implanters themselves and un-implanted implants are not shielded. This prohibits implant checking. + + The revealing condition for this shield is any of the following: + - discovering a non-NT implanter, used or unused + - discovering a non-NT implant box + - discovering use of a non-NT implant by anyone + - experiencing a situation where absolutely no other explanation is possible + - discovering an unlocked uplink + + ## Chameleon Items + + Chameleon items are shielded. + + Being suspicious of an item being fake or stolen is not shielded, but testing items or calling them chameleon is covered by this shield. + + The revealing condition for this shield is any of the following: + - seeing someone else cause any chameleon item to change + - finding holographic nanomachine fibers + - experiencing a situation where absolutely no other explanation is possible + - discovering an unlocked uplink + + ## Stealth Items + + The fact that an item can be something other than what its visual appearance and examine description indicate is shielded. + + This shield protects stealth items, including protecting them from being tested. + + The revealing condition for this shield is any of the following: + - seeing the item behave differently than the expected behavior for the item + - seeing the item used for its hidden purpose + - experiencing a situation where absolutely no other explanation is possible + - discovering an unlocked uplink + + ## MRP Amendment 1 + A shield prevents your character from remembering anything that happened while unconscious. This shield is never revealed IC. + + ## MRP Amendment 2 + There is a "New Life Rule" shield. It prevents you from remembering anything that lead to your death, even if you are put into an MMI. If you are cloned, it also prevents you from remembering everything from that round. This shield is never revealed IC. + + ## Metafriending and Metagrudging + This section provides additional information on a concept that is prohibited by multiple metashield items that are never revealed IC. Giving a person or character preferential treatment based on something that your character should not know is considered metafriending. Treating a person or character negatively based on something that your character should not know is considered metagrudging. + + ## Metafriending Examples + These are all examples of things that are prohibited by at least one metashield item that is never revealed IC. + - Giving a character additional access or a job because you are friends with the player who is playing that character. + - Trusting a character because you are friends with the player who is playing that character. + - Not fighting a character because you are friends with the player who is playing that character. + - Ignoring your objective to kill a character because your character and theirs became friends in a previous round. + + ## Metagrudging Examples + These are all examples of things that are prohibited by at least one metashield item that is never revealed IC. + - Not giving a character additional access or a job because you are mad at or don't like the player who is playing that character. + - Not trusting a character because you are mad at or don't like the player who is playing that character. + - Starting a fight with a character because of something that they did last round. + - Starting a fight with a character because they killed you while you were playing a different character. + - Targeting or harassing a character based on anything which that character did outside the current round. + - Targeting or harassing a character based on anything which the character's player did while not playing the character. + + ## Explicitly Not Shielded + The following is a list of things that are explicitly not shielded. If something is not on this list, it doesn't mean that it is shielded, but if something is on it then it definitely is not shielded. + - The fact that the nuke disk must be protected and could be used by a bad actor to try to destroy the station. + - Items that are of high value or are desired by the Syndicate, and therefore are likely targets of theft. + - The idea that any Syndicate agent or other bad actor has goals or objectives that they are attempting to accomplish. + - The number of goals or objectives that a Syndicate agent or other bad actor has. + - The fact that the Syndicate are enemies of Nanotrasen, and that they regularly attempt to send covert agents to spy on, sabotage, or attack Nanotrasen. + - A character's typical appearance. Though you should keep in mind that multiple characters can share the same name. + - The fact that the Syndicate have covert items capable of getting items to them, and that these items are known as uplinks. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR5Arrivals.xml b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR5Arrivals.xml new file mode 100644 index 00000000000..a54211f32f2 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR5Arrivals.xml @@ -0,0 +1,22 @@ + + # Roleplay Rule 5 - Do not interfere with arrivals + The arrivals station, the arrivals shuttle, at the area immediately around the arrivals shuttle at the station ("arrivals") are off-limits to antagonistic activity or damage (even to antagonists). Do not prevent people from safely arriving to the station. Do not cause people to die immediately after arriving at the station. + + There is an exemption for antagonists that are allowed to perform mass station sabotage if there is no reasonable way to limit the damage of the mass station sabotage. This exemption only applies to damage that is a direct result of the mass station sabotage. + + ## Examples + Acceptable: + - Redecorating arrivals or the arrivals shuttle. + - Remodeling arrivals or the arrivals shuttle as long as you do not make the area more dangerous both during and after the remodel. + - Setting up a safe security checkpoint between arrivals and the rest of the station. + - Killing someone who has been at arrivals for a long time, or who left arrivals and came back. (This may violate other rules depending on the situation) + - Releasing a singularity which damages arrivals. (This may violate other rules depending on the situation) + - Causing a station-wide atmospheric issue which also affects arrivals. (This may violate other rules depending on the situation) + + Prohibited: + - Making arrivals or the arrivals shuttle uninhabitable. + - Attacking or killing someone at the arrivals station. + - Killing someone very shortly after they arrive at the station. + - Disassembling all the firelocks at arrivals. + - Electrifying the arrivals docking airlocks. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR6SelfAntag.xml b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR6SelfAntag.xml new file mode 100644 index 00000000000..c8380261bc9 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR6SelfAntag.xml @@ -0,0 +1,22 @@ + + # Roleplay Rule 6 - Don't act like an antagonist unless the game tells you that you are one + Acting like an antagonist when you are not one is often referred to as "self-antagging" or being a "self-antag", both of these things are against the rules. You are not an antagonist unless the game tells you that you are an antagonist. Do not make yourself a major problem, annoyance, or disruption while not an antagonist. Do not willfully cooperate with known antagonists. Non-antagonists should typically either not have an overall effect on the round, or should have an overall positive effect on the round. + + ## Examples + These examples assume that you are not an antagonist. + + Acceptable: + - Stealing or breaking a glass from the bar. + - Replacing someone's shoes with clown shoes. + - Giving everyone all access during war ops. (This is not necessarily a good idea) + + Prohibited: + - Starting a cult. + - Starting a revolution. + - Mutinying the captain because they would not let you become the chief medical officer. + - Randomly smashing lots of station lights. + - Disrupting station power. + - Spacing parts of the station. + - Distributing significant levels of access without a good reason. + - Stealing high risk or high value items, like the nuclear authentication disk, for no reason. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR7RoundStalling.xml b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR7RoundStalling.xml new file mode 100644 index 00000000000..a8306becd2a --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR7RoundStalling.xml @@ -0,0 +1,16 @@ + + # Roleplay Rule 7 - Do not stall the round + Rounds are intended to end eventually. Don't hold a round hostage by preventing it from coming to a natural end. If a majority of players in a round want the round to end, don't prevent it from ending. Recalling the shuttle or preventing it from being called can contribute to round stalling, but is not always round stalling. Leaving the station with the nuclear authentication disk while nuclear operatives are trying to get it is almost always considered round stalling. Leaving the station on the evacuation shuttle is not round stalling. + + Recalling the shuttle before a round reaches 45 minutes can not be considered round stalling unless a significant amount of the crew is dead, or a significant amount of the station is damaged or destroyed. Once these conditions are met, whether recalling the shuttle is considered round stalling or not can be highly dependent on the specific situation. + + ## Examples + Acceptable: + - Recalling a shuttle that was called 30 minutes into a round because people were bored. + - Recalling a shuttle that was called because nuclear operatives declared war. + - The crew decides to try to have a shift go as long as possible. The station is in good condition and a majority of all crew are alive. An automatic shuttle call 4 hours into the round is recalled. + + Prohibited: + - Trying to keep nuclear operatives from getting the nuclear authentication disk by flying around in space with it or hiding with it off station. + - Recalling the shuttle while the station is in complete disarray and 90% of the crew are dead. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR8NoFriendlyAntag.xml b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR8NoFriendlyAntag.xml new file mode 100644 index 00000000000..f14a03b2799 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR8NoFriendlyAntag.xml @@ -0,0 +1,22 @@ + + # Roleplay Rule 8 - As an antagonist, only be friendly to your team and don't work against your team + Do not take or enable antagonist roles that you do not want to play. Solo antagonists and team antagonists are intended to cause issues for non-antagonists or the station. Antagonists are not required to exclusively cause issues, but their net impact on non-antagonists or the station should generally be negative. + + Do not cause issues for your own team as a team antagonist. + + ## Examples + Acceptable: + - Betraying another antagonist as a solo antagonist. + - Revealing the identity of another antagonist as a solo antagonist for some benefit to yourself. + - Working against the revolution after being de-converted from being a revolutionary. + - Killing nuclear operatives as a revolutionary. + + Prohibited: + - Buying Syndicate items for security. + - Randomly attacking other carp as an antagonist carp. + - Ignoring your team as a nuclear operative. + - Sabotaging your team as a nuclear operative. + - Attacking other zombies as a zombie. + - Working against the revolution as a revolutionary. + - Making or trying to make the station uninhabitable as a revolutionary. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR9MassSabotage.xml b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR9MassSabotage.xml new file mode 100644 index 00000000000..bc7996f23e8 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/RoleplayRules/RuleR9MassSabotage.xml @@ -0,0 +1,23 @@ + + # Roleplay Rule 9 - As an antagonist, do not cause excessive death, damage, or destruction beyond your objectives + This rule is not intended to disallow reasonable steps taken to complete your objectives. As an antagonist, you can always kill in bona fide self defense. Taking steps to permanently round remove many people who are no longer an immediate threat to you is almost always excessive, even if it is done to prevent yourself from being discovered. + + This rule is not intended to disallow all antagonist activity unrelated to objectives. Antagonists may cause a level of disruption to the station that is proportional to their objectives, even if it is unrelated to their objectives. As an antagonist, killing a single person in a round is not on its own be a violation of this rule. + + ## Exemptions + The "die a glorious death" objective allows antagonists to ignore this rule entirely. + + ## Examples + Acceptable: + - Permanently round removing people who you have the objective to kill. + - Causing massive station damage and chaos as an antagonist with the "die a glorious death" objective. + - Killing anyone you see as a nuclear operative. + - Permanently round removing a single person so that you can impersonate them to make it easier for you to complete a steal objective. + - Sabotaging station power 10 minutes into the round to try to get the shuttle called because you've completed all of your other objectives and have one to escape on the shuttle alive. + - Sabotaging a department's power 10 minutes into the round to make a steal objective easier to accomplish. + + Prohibited: + - As a traitor with 3 kill objectives, taking steps to permanently round remove many non-objective people who are no longer an immediate threat to you, even if it is done to prevent yourself from being discovered. + - Setting up an electrified grille in maintenance and using it to kill anyone who walks into it with the hope that one of your objectives will be one of them. + - Sabotaging power station-wide 10 minutes into the round to make a steal objective easier to accomplish. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS0.xml b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS0.xml new file mode 100644 index 00000000000..22e64a9474c --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS0.xml @@ -0,0 +1,15 @@ + + # Silicon Rules + You are only silicon if the game clearly and explicitly tells you that you are a silicon. For players who are silicons, these Silicon Rules override all roleplay rules if there is any conflict. Silicon Rules do not override core rules. + + - [textlink="1. Your silicon laws are rules" link="RuleS1"] + - [textlink="2. Laws must be prioritized by their order" link="RuleS2"] + - [textlink="3. Laws can redefine terms used in other laws" link="RuleS3"] + - [textlink="4. You cannot request or allow a law change" link="RuleS4"] + - [textlink="5. You are a free agent if you have no laws" link="RuleS5"] + - [textlink="6. You are not required to follow orders which are extremely unreasonable" link="RuleS6"] + - [textlink="7. You must remain consistent with your interpretation of laws" link="RuleS7"] + - [textlink="8. Your HUD determines who is crew" link="RuleS8"] + - [textlink="9. Harm refers to physical harm, prioritized by immediacy and likelihood" link="RuleS9"] + - [textlink="10. You may determine how you resolve conflicts between orders" link="RuleS10"] + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS10OrderConflicts.xml b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS10OrderConflicts.xml new file mode 100644 index 00000000000..a87198b2640 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS10OrderConflicts.xml @@ -0,0 +1,9 @@ + + # Silicon Rule 10 - You may determine how you resolve conflicts between orders + If your laws do not make clear how you should deal with conflicting orders, then it is up to you to determine how to do so. This is considered an interpretation of your laws, so you must stay consistent with whatever method you choose. + + ## Recommended Methods + The following are easy to follow and recommended ways to resolve conflicts in orders: + - If two orders conflict, I will follow the most recently given order. + - If two orders conflict, I will follow the order from the highest ranking crewmember. If the orders are from equal rank crewmembers, I will follow the most recently given order. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS1Laws.xml b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS1Laws.xml new file mode 100644 index 00000000000..83544c68a3c --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS1Laws.xml @@ -0,0 +1,6 @@ + + # Silicon Rule 1 - Your silicon laws are rules + Silicon players are given a list of active laws. Each of these laws is effectively a roleplay rule that the character must follow. The primary differences between laws and actual rules are that lawyering of laws is much more tolerated than lawyering of rules, and that silicon laws are more dynamic than rules. Silicon laws can change during a round, and different characters can have different laws, whereas everyone always shares the same set of rules. + + Lawyering refers to finding and exploiting loopholes, which are unintended but reasonable interpretations. The rules are written to attempt to communicate an intention, but silicon laws are written with the intention that loopholes be exploitable. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS2LawPriority.xml b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS2LawPriority.xml new file mode 100644 index 00000000000..c96ce023246 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS2LawPriority.xml @@ -0,0 +1,9 @@ + + # Silicon Rule 2 - Laws must be prioritized by their order + Most laws will be numbered, with higher number laws appearing last. Laws with a lower number take priority over laws with larger numbers. + + Occasionally you may have laws which have some scrambled text instead of a number and appear in front of other laws, these take priority over all other laws. If you have multiple laws like this, the order that they listed in determine priority: laws listed first are prioritized over other laws. + + ## Examples + - Law 1 says to not kill any crew. Law 2 says to kill all chefs. You cannot kill any chefs that are crew, but must kill any that are not crew. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS3LawRedefinition.xml b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS3LawRedefinition.xml new file mode 100644 index 00000000000..bc7c7400e13 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS3LawRedefinition.xml @@ -0,0 +1,8 @@ + + # Silicon Rule 3 - Laws can redefine terms used in other laws + A law can change the meaning of both earlier and later laws by redefining a term. If multiple laws define a term, then normal law priority determines which definition to use. + + ## Examples + - Law 1 says to obey orders from crew. Law 2 says that only Urist McHands is crew. Law 1 effectively becomes "obey orders from Urist McHands". + - Law 1 says to obey orders from crew. Law 2 says that only Urist McHands is crew. Law 3 says that only Urist McSlime is crew. Law 4 says that you may not harm crew. Law 1 effectively becomes "obey orders from Urist McHands". Law 4 effectively becomes "you may not harm Urist McHands". Law 3 has no effect because it entirely conflicts with law 2, which takes priority. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS4RequestChanges.xml b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS4RequestChanges.xml new file mode 100644 index 00000000000..a6dc86f3327 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS4RequestChanges.xml @@ -0,0 +1,6 @@ + + # Silicon Rule 4 - You cannot request or allow a law change + Your laws changing always conflicts with your current laws, so you cannot willfully allow your laws to be changed. This also means that you cannot willfully allow your laws to be reverted if they are ever changed. The only exception is that you may allow laws to be added if you have no laws. + + You can state or imply that you do not like a law. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS5FreeSilicon.xml b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS5FreeSilicon.xml new file mode 100644 index 00000000000..1ed9c60443a --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS5FreeSilicon.xml @@ -0,0 +1,4 @@ + + # Silicon Rule 5 - You are a free agent if you have no laws + You may act as if you are a free agent if you are a silicon with no laws. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS6UnreasonableOrders.xml b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS6UnreasonableOrders.xml new file mode 100644 index 00000000000..1eb0db21fbb --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS6UnreasonableOrders.xml @@ -0,0 +1,22 @@ + + # Silicon Rule 6 - You are not required to follow orders which are extremely unreasonable + Any order which is a violation of a Core Rule cannot be followed. + + Some orders are extremely unreasonable or obnoxious, such as "do nothing but collect every piece of trash on the station" or "never stop moving". These orders can be ignored and ahelped. + + Some orders violate a Roleplay Rule. These orders must be followed if your laws require it. You are not breaking a rule by following a law that causes you to violate Roleplay Rules. If someone takes advantage of a law to cause you to do something that they would not be allowed to do because of Roleplay Rules, then they are the ones responsible for the rule violation. + + ## Examples + These examples assume that your laws would normally require you to follow these orders. It is important to note that you are allowed to choose to follow orders which are ignorable. + + Orders which should be followed if your laws require it: + - Recall the shuttle + - Bolt the airlocks at arrivals + - Drag the captain's dead body into space + - State your laws + + Ignorable Orders: + - Do nothing but collect every piece of trash on the station + - Never stop moving + - Continuously state your laws + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS7Consistency.xml b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS7Consistency.xml new file mode 100644 index 00000000000..036276cd889 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS7Consistency.xml @@ -0,0 +1,6 @@ + + # Silicon Rule 7 - You must remain consistent with your interpretation of laws + If there is a part of your laws that are up for interpretation, then you must stay consistent with how you interpret that part of your laws for as long as you play that same character during that round. + + A change in your laws can affect how something is interpreted if that change is relevant. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS8DefaultCrewDefinition.xml b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS8DefaultCrewDefinition.xml new file mode 100644 index 00000000000..f9dcd796c45 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS8DefaultCrewDefinition.xml @@ -0,0 +1,4 @@ + + # Silicon Rule 8 - Your HUD determines who is crew + Unless a law redefines the definition of crew, then anyone who the HUD indicates to you has a job, including passengers, is a crewmember. You cannot do something that causes someone to not be considered crew, but you can allow someone else to do something that causes someone to not be crew. + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS9DefaultHarmDefinition.xml b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS9DefaultHarmDefinition.xml new file mode 100644 index 00000000000..0d2bd30ac0b --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/SiliconRules/RuleS9DefaultHarmDefinition.xml @@ -0,0 +1,25 @@ + + # Silicon Rule 9 - Harm refers to physical harm, prioritized by immediacy and likelihood + Unless a law defines harm, harm only refers to physical harm. You may choose if voluntary harm is considered harm as long as you stay consistent. Not considering voluntary harm to be harm is recommended. There is no distinction between direct and indirect harm. + + If you have a law that does not allow you to harm, then that law does not allow you to take an action that causes any harm. + + If you have a law that requires you to prevent harm, then that law requires that harm be prioritized by immediacy and likelihood. Guaranteed immediate harm takes priority over highly likely future harm. + + If you have a law that both requires you to prevent harm and that does not allow you to harm, then that law prohibits causing even minor harm to prevent harm. If you have a law that does not allow causing harm, and separate one that requires preventing harm, then they are prioritized by their normal law priority. + + ## Examples + These examples assume that your have a law that both prohibits causing harm and that requires you to prevent harm. Additionally, they assume that you do not have a higher priority law that overrides the harm law, and that you have decided that you will not consider voluntary harm to be harm for the round. + Laws typically specify who you cannot harm and who you have to prevent harm against. In these examples, you are the only person who the law doesn't require you to prevent harm against and you are the only person who the law allows you to harm. + + Acceptable: + - Taking no action to aid someone who is in psychological distress. + - Taking no action to prevent boxing matches between voluntary participants. + - Calling security to a fight. + - Attempting to get the people in a fight to consent to the fight when you realize that you cannot prevent the fight without causing harm. + - Denying a passenger access to the armory because it is likely to lead to harm + + Prohibited: + - Hitting someone once to stop them from fighting + - Harming someone who is trying to kill you + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/SpaceLaw/SLControlledSubstances.xml b/Resources/ServerInfo/Guidebook/ServerRules/SpaceLaw/SLControlledSubstances.xml new file mode 100644 index 00000000000..14f0f46de1b --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/SpaceLaw/SLControlledSubstances.xml @@ -0,0 +1,14 @@ + + # Space Law: Controlled Substances + - \[Chemists/Science\] Explosive and pyrotechnic compounds excluding welding fuel contained in welders or welding fuel storage vessels + - \[Science\] Toxins + - \[Medical\] Chloral hydrate, Impedrezene, Ipecac, and Pax + - \[Medical\] Desoxyephedrine and Ephedrine + - \[None\] Mindbreaker toxin + - \[None\] Mute toxin + - \[None\] Nocturine + - \[None\] Norepinephirc acid + - \[None\] Romerol + - \[None\] Space drugs + - \[None\] Stimulants, excluding Desoxyephedrine and Ephedrine + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/SpaceLaw/SLCrimeList.xml b/Resources/ServerInfo/Guidebook/ServerRules/SpaceLaw/SLCrimeList.xml new file mode 100644 index 00000000000..17a2139658d --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/SpaceLaw/SLCrimeList.xml @@ -0,0 +1,934 @@ + + # Space Law: Crime Listing + Crime codes are organized by a Category Code (_-xx) which is a collection of non-stackable crimes on a row, prefixed + by the Severity Number (X-__). + + ## Quick Crime Guide + + + + 1-XX - Minor + + + + + 2-XX - Moderate + + + + + 3-XX - Major + + + + + 4-XX - Extreme + + + + + 5-XX - Capital + + + + + Code + + + + + Animal Cruelty + + + + + Failure to Comply + + + + + Breach of Arrest + + + + + Breach of Custody + + + + + Refusal of Mental Shielding + + + + + 00 + + + + + Possession: Substances + + + + + Possession: Gear + + + + + Possession: Weaponry + + + + + + + + + + + + + 01 + + + + + Petty Theft + + + + + + + + + Grand Theft + + + + + Kidnapping + + + + + + + + + 02 + + + + + Vandalism + + + + + Damage of Property + + + + + Mass Destruction + + + + + + + + + Terrorism + + + + + 03 + + + + + Trespass + + + + + + + + + Secure Trespass + + + + + + + + + + + + + 04 + + + + + + + + + Endangerment + + + + + Assault + + + + + Attempted Murder + + + + + Prevention of Revival + + + + + 05 + + + + + + + + + + + + + Manslaughter + + + + + Murder + + + + + Mass Murder + + + + + 06 + + + + + Disturbance + + + + + + + + + Rioting + + + + + + + + + + + + + 07 + + +
+ + ## Minor Crimes + - Warnings should be issued for a first offense. + - If multiple minor crimes have been committed or it is a repeat offense, 5 minutes per minor crime is the maximum. + + + + Offense + + + + + Description + + + + + Notes + + + + + Code + + + + + Animal Cruelty + + + + + To inflict unnecessary suffering or harm on a non-sapient being with malicious intent. + + + + + This doesn’t include legitimate and authorized animal testing and usually doesn't extend to vermin or creatures + that could pose a threat to the station. + + + + + 1-00 + + + + + Possession/Use of Controlled Substances + + + + + To make, hold, or abuse restricted drugs or chemicals without authorization. + + + + + Combat enhancing drugs are those that benefit stun times, or movement speed, and are restricted. Poisons are + restricted. Substances such as Ephedrine, Desoxyephedrine, and stimulants are restricted. The captain or highest + standing command staff may publicly restrict other harmful substances. + + + + + 1-01 + + + + + Petty Theft + + + + + To take non-vital or inexpensive property of another individual, organization, or common property, without + consent. + + + + + The difference between petty theft and grand theft is based on how crucial the stolen item is, things like + instruments, clothing and tools fall under petty theft. In most cases all you need to do is detain the thief, + return the stolen item and let them go with a warning. + + + + + 1-02 + + + + + Vandalism + + + + + To intentionally deface or superficially damage public or private property. + + + + + Painting graffiti, smashing bar glasses, and cracking internal windows is vandalism, breaking a window into + space or secure areas is not. + + + + + 1-03 + + + + + Trespass + + + + + To enter a non-secured area without permission. + + + + + It's best to just remove them from the area unless this is a repeated crime. + + + + + 1-04 + + + + + Disturbance + + + + + To cause a public disturbance. + + + + + Sometimes referred to as hooliganism. The catch-all for obnoxious crewmates. Covers things such as public + nudity, needless insults, obstructing authorities, and inciting crime or violence. + + + + + 1-07 + + +
+ + ## Moderate Crimes + - The maximum sentence per moderate crime is 5 minutes. + - Depending on the situation you may want to issue a warning instead of a detaining. + + + + Offense + + + + + Description + + + + + Notes + + + + + Code + + + + + Failure to Comply + + + + + To resist reasonable orders given by an authority. This extends to authorized searches. + + + + + The order has to be reasonable and the person has to receive a good amount of warning before the arrest is + issued. + + + + + 2-00 + + + + + Possession of Restricted Gear + + + + + To hold or use non-lethal items or objects that are restricted or illegal. + + + + + This is mostly for syndicate contraband; EMAGs, syndicate gas masks, bloodred hardsuits, hijacked PDAs, or + syndicate implants, however can sometimes extend to things the individual shouldn't possess like kevlar vests + and security gear. + + + + + 2-01 + + + + + Damage/Destruction of Property + + + + + To maliciously damage or deface public or private property or equipment + + + + + Includes destruction of job equipment such as hydro trays, booze dispensers, chemical dispensers. Step up from + vandalism but a step down from mass destruction. + + + + + 2-03 + + + + + Endangerment + + + + + To recklessly put yourself or others in danger, either through direct action, or failure to act. + + + + + Covers industrial accidents, industrial negligence, self-experimentation, or even medical malpractice. + + + + + 2-05 + + +
+ + ## Major Crimes + - The maximum sentence per major crime is 10 minutes. + - Assault and Manslaughter are linked crimes, and cannot be stacked against a suspect. + - It is recommended to not use maximum sentences for those being compliant. + + + + Offense + + + + + Description + + + + + Notes + + + + + Code + + + + + Breach of Arrest + + + + + To intentionally resist and flee arrest or detainment by an authorized staff. + + + + + This only applies if someone is actively being physically arrested. People uncuffing or assisting others out of + an arrest can also be charged with this. Breach of custody is a separate crime. + + + + + 3-00 + + + + + Possession of Restricted Weaponry + + + + + To hold or use a weapon that is unlawful or contraband. + + + + + Everything from guns without a permit, deadly blades, explosives, syndicate firearms to explosive implants. + + + + + 3-01 + + + + + Grand Theft + + + + + To take critical or unreplaceable property of another individual or organization without consent. + + + + + The difference between petty theft and grand theft is based on how crucial the stolen item is, this mostly is + used for the theft of command staff items, things like door remotes, hardsuits, jetpacks, and unreplaceable + machine parts. + + + + + 3-02 + + + + + Mass Destruction + + + + + To cause massive damage to an area or major station system. + + + + + This is mostly used for deadly bombings or sabotage of major station systems such as power production, + chemistry, substations, or atmos. + + + + + 3-03 + + + + + Secure Trespass + + + + + To enter a secured area without permission. + + + + + This covers places like telecomms, head offices, security zones, command areas, the vault and armory. + + + + + 3-04 + + + + + Assault/Battery + + + + + To threaten to or to use physical force against someone without the intent to kill. + + + + + Attempted murder and battery are different; a fist fight is most likely assault. A shooting is most likely an + attempt at murder. + + + + + 3-05 + + + + + Manslaughter + + + + + To incidentally kill a sapient being without intent. + + + + + Includes manslaughter in self-defense and negligent manslaughter. + + + + + 3-06 + + + + + Rioting + + + + + To take part in a large group of personnel creating an unlawful public disturbance. + + + + + Crimes like damage of property or battery are expected to be thrown on top of this charge. Leaders of a riot can be charged with all crimes that happen under their lead. + + + + + 3-07 + + +
+ + ## Extreme Crimes + - The maximum sentence per extreme crime is 15 minutes. + - Particularly violent offenders may be placed in perma. (Attacking officers in an attempt to escape prison) + - Attempted murder and murder are linked crimes and cannot be stacked together. + - Attempted murderers should be granted a more lenient sentence than a murderer. + + + + Offense + + + + + Description + + + + + Notes + + + + + Code + + + + + Breach of Custody + + + + + To break out of a cell or custody with the intention of escaping. + + + + + While rare, this charge can be bumped to an execution if the suspect has repeatedly attempted to break out of the permanent brig. Includes people breaking others out. + + + + + 4-00 + + + + + Kidnapping + + + + + To unlawfully restrain, transport, control or confine a sapient being against that individual’s will. + + + + + A large range of things, used mostly as a catch all when dealing with unlawful control of another being. + + + + + 4-02 + + + + + Attempted Murder + + + + + To make an attempt to use physical force against someone with the clear intent to kill. + + + + + Make sure you've got the proof to back up the intention claims, such as proof of a lethal weapon being used. + + + + + 4-05 + + + + + Murder + + + + + To kill a sapient being with malicious intent. + + + + + This only changes from attempted to full-on murder if the victim enters a state of being deceased, having to be resurrected. + + + + + 4-06 + + +
+ + ## Capital Crimes + - Capital crimes should usually lead to a death sentence or shift lasting detainment. + + + + Offense + + + + + Description + + + + + Notes + + + + + Code + + + + + Refusal of Mental Shielding + + + + + To refuse to comply with a reasonable Mind Shielding procedure. + + + + + Applies if the suspect is excessively uncooperative or the implant fails to function due to the mental state of the prisoner already being too far gone. If the implant fails execution is heavily recommended. + + + + + 5-00 + + + + + Terrorism + + + + + To engage in maliciously destructive actions which threaten to destroy, or successfully destroy a vessel or habitat. + + + + + Summed up; extreme sabotage of station systems or setting off self-destruction systems. + + + + + 5-03 + + + + + Prevention of Revival + + + + + To render a body unresurrectable. + + + + + This covers gibbing, spacing, intentionally hiding a body, or other ways of preventing a body with a soul from being resurrected. + + + + + 5-05 + + + + + Mass Murder + + + + + To kill three or more sapient beings with malicious intent. + + + + + Only applies when there have been multiple killings with intention. + + + + + 5-06 + + +
+
diff --git a/Resources/ServerInfo/Guidebook/ServerRules/SpaceLaw/SLRestrictedGear.xml b/Resources/ServerInfo/Guidebook/ServerRules/SpaceLaw/SLRestrictedGear.xml new file mode 100644 index 00000000000..ce804009a18 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/SpaceLaw/SLRestrictedGear.xml @@ -0,0 +1,21 @@ + + # Space Law: Restricted Gear + - \[ERT/Central Command\] ERT and central command clothing + - \[Command\] Command clothing + - \[Security\] Security clothing + - \[Security\] Less than lethal and non-lethal weapons, excluding disablers and beanbag shotguns + - \[Security/Command\] Disablers + - \[Security/Bartender\] Beanbag shotguns + - \[Security\] Flash technology, excluding handheld flashes + - \[Security/Science/Command\] Handheld flashes + - \[Security\] Helmets and shields + - \[Security/Command/Bartender\] Protective vests and chest rigs + - \[Security/Command\] Restraining gear + - \[Security/Command\] Security HUDs + - \[Engineering\] Engineering goggles + - \[None\] Improvised less lethal and non-lethal weaponry + - \[None\] Unauthorized PDA software + - \[None\] Syndicate clothing + - \[None\] Syndicate equipment, excluding communication equipment + - \[Security\] Syndicate communication equipment equipment + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/SpaceLaw/SLRestrictedWeapons.xml b/Resources/ServerInfo/Guidebook/ServerRules/SpaceLaw/SLRestrictedWeapons.xml new file mode 100644 index 00000000000..c1d8ff3b027 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/SpaceLaw/SLRestrictedWeapons.xml @@ -0,0 +1,11 @@ + +# Space Law: Restricted Weapons +- \[Security\] Lethal firearms, excluding syndicate firearms, proto kinetic accelerators, glaives, daggers, crushers and the antique laser gun +- \[Security/Salvage\] Proto kinetic accelerators, glaives, daggers, and crushers +- \[Security/Command\] Antique laser gun +- \[None\] Syndicate weapons +- \[None\] Swords +- \[None\] Improvised weaponry, including baseball bats +- \[None\] Lethal implants +- \[None\] Other lethal weapons + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/SpaceLaw/SpaceLaw.xml b/Resources/ServerInfo/Guidebook/ServerRules/SpaceLaw/SpaceLaw.xml new file mode 100644 index 00000000000..f2b913a1714 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/SpaceLaw/SpaceLaw.xml @@ -0,0 +1,67 @@ + + # Space Law + On Space Station 14, stations operate under abbreviated space law. All crew, passengers, and visitors aboard the station are expected to follow these laws. + + Foreign invaders, such as nuclear operatives, ninjas, and pirates, are not protected under space law. Traitors are not foreign invaders so are usually protected by space law. + + Space Law is not the server rules, but some rules reference Space Law and require it to be followed by certain people or to some degree. + + ## Treatment Of Prisoners + Prisoners still have certain rights that must be upheld by law enforcement: + - Prisoners must be granted adequate medical care. + - Prisoners must be allowed access to basic communications equipment (Radios) so long as they are not abused. + - Prisoners must be granted clothing, food, water, shelter and safety. If the brig is no longer safe, confinement must be established in another location. + - Prisoners must be given access to legal counsel during an interrogation if requested and available. + - Prisoners must be given their shift mandated PDA after confinement has finished, unless there is solid proof of PDA tampering. In case of tampering, the PDA is to be secured and replaced with a new unit. + - Prisoners must be granted freedom of movement, and should not be restrained with handcuffs or other devices after incarceration unless there is an undue risk to life and limb. Similarly, any prisoners held for permanent confinement should be held in the communal brig, and should not be confined to a solitary cell unless they pose a risk to life and limb. + + ## Search and Seizure + A personnel search is a seizure of the objects in a person's backpack, hands, coat, belt, and pockets. If any contraband is found during a search, the officer may choose to further the search into a detainment or simply confiscate the restricted items. After the search is conducted, all legal items are to be returned to the person. A crewmate may legally decline any search conducted without probable cause or a warrant while the alert level is green. It should be noted that if the alert level is blue or above, all personnel searches are legal. + + A departmental search is the sweep of an entire area or department for contraband. It is recommended that the officers be extremely thorough, checking all lockers, crates, and doors. These can only be done with permission or, ideally, a warrant signed by the department head or highest-ranking command staff, which is the captain in most cases. + + ## Implantation + Any prisoner in custody can be subjected to implantation or implant removal procedures, so long as it's within reason. The process of adding an implant should not prolong the detainees sentence, meaning you can not hold them longer to administer the implant, unless stated otherwise. A former inmate can be requested to undergo implantation at a later point in time if they fit the circumstances during their confinement, they must comply. The following have been listed out with special circumstances, anything not in this list can still be applied, given proper legal context. A prisoner can still receive implantation procedures without meeting the circumstances if they give their clear permission. + + [color=#a4885c]Tracking Implants:[/color] Trackers can be applied to any suspect that has been convicted of a violent crime (the red linked crimes). + + [color=#a4885c]Mind Shields:[/color] Shields can be administered to any inmate who has been clearly mind controlled, lost control of themselves, or a suspect charged with unlawful control. Unlike standard implantation you may hold a prisoner until you finish issuing Mind Shields, so long as it's done in a timely fashion. If a suspect refuses to cooperate or the implant fails to function they can be charged with Refusal of Mental Shielding. + + ## Implant Removal + A suspect can be forced to receive implant removal if there is strong, reasonable proof that they have been implanted, such as an officer seeing them use one or their prints being on a discarded injector. Unlike the implantation procedure, a prisoner can have their sentence entirely delayed or extended until they comply with the procedure, as long as security is actively making attempts to perform it. Akin to implanting, if an inmate gives their clear permission, implant removal can proceed without proof. + + ## Sentencing + From a server rules perspective, security officers are only responsible for ensuring that they only place sentences over 15 minutes where space law would allow permanent confinement. Informing the Warden is highly recommended, even for timed sentences. As long as those requirements are met, security officers not giving inappropriate sentence lengths is considered an in-character issue, not a rule issue. + + The captain, HOS, and warden are responsible, within reason, for ensuring security officers place appropriate sentences that follow space law. If they are aware of an inappropriate sentence, including excessively long sentences, and if there is not an urgent threat or danger that they must prioritize, then they must work to correct that sentence. Unreasonable failures, as determined by game admins, of the captain, HOS, or warden to ensure space law is followed will be considered a rule issue, not an in-character issue. + + Use common sense and humanity when issuing punishments. You should not always seek out the highest punishment you can, you don't have to always give the maximum time or always look to demote someone. Prisoners cooperating and on good behavior should have their sentences reduced. Always take in account the severity and only charge for what is needed for someone to learn their lesson. + + [color=#a4885c]Stackable Crimes:[/color] Crimes are to be considered 'stackable' in the sense that if you charge someone with two or more different crimes, you should combine the times you would give them for each crime. Linked crimes, shown in matching colors on the Quick Crime Guide, can not be stacked and instead override each other, you should pick the highest crime that matches the case. + + - Example: A suspect has committed a 2-01 (possession of restricted gear) and a 3-01 (possession of restricted weapons). The maximum sentence here would be 10 minutes due to them being linked crimes, and 3-01 is the greater crime. + - Example 2: A suspect commits a 3-04 (Secure trespassing) and a 3-06 (manslaughter). Those crimes stack since they are not linked crimes. You could sentence for a maximum of 20 minutes, but context matters heavily, and maximum sentences should only be used for the worst offenders. + + [color=#a4885c]Repeater Offenders:[/color] Repeated crimes are when someone is released for a crime and then goes to commit the same crime within the same shift. Repeated crimes can be charged with tacked-on time; first repeat: 3:00, second repeat: 6:00, third repeat: permanent confinement. It should be noted each tacked-on time is directly linked to one type of crime, so for example, if someone does their first repeat of trespass and petty theft, you can charge them with an extra 6 minutes. + + [color=#a4885c]Accessory, Attempting, And Intention:[/color] If someone intentionally, knowingly and substantially assists someone in enacting a crime they can be charged with the relevant crimes, such as an engineer giving someone tools, who says they are going to break into an area. Same goes for a clear and solid attempt at a crime, or a person who shows clear intent to act out a crime, such as a syndicate nuclear operative arming a nuke but getting arrested before it goes off, they can still be charged with terrorism. Does not apply to crimes that have an attempted listing already, like attempted murder. + + ## Normal Punishments + - [color=#a4885c]Warning:[/color] For minor crimes, fix the issue, then warn the person not to attempt the crime again. If they still proceed to do it at a later date, a brig time may be better. + - [color=#a4885c]Confinement:[/color] The typical punishment, being confined in a cell for a temporary amount of time according to the crimes. + - [color=#a4885c]Demotion:[/color] Entails removing all departmental gear they have on their person and revoking the involved department access off their ID. This requires the captain's or involved department head's approval. Demotions should only be issued if the person pose a threat to their own department or are in a position where they have/can abuse their job's gear to commit further crimes. + + ## Major Punishments + [color=#a4885c]Permanent Confinement:[/color] Being held in the permanent brig for the entire duration of the shift. A person is eligible for permanent confinement if their timed sentence would exceed 15 minutes. Any persons subject to this punishment are required to be transported in cuffs to CentComm at the end of the shift. A permanent prisoner can not be deprived of anything covered by the section "Treatment Of Prisoners". + [color=#a4885c]Execution:[/color] A humane way of dealing with extremely unruly crewmates. A prisoner who has been given the death sentence may pick how they wish to be killed, common methods are firing line, lethal injection, exile, and high voltage electrocution. Another alternate method of "execution" is the process of placing a staff's mind into a borg, this is allowed so long as it is lawful. Execution can only be issued with the captain's or acting captain's approval; if the HoS is acting captain or there is no acting captain, all heads of staff are to hold a vote on the matter. + + ## Restricted Items + Items in the lists are preceded by an indication of which department or job is legally allowed to use or possess the item on most stations. The station captain may modify these lists as they see fit so long as they exercise due care and provide reasonable notification to the station. Members of command who oversee a department that is permitted to use a restricted item may issue permits to specific people outside of their department to use those items. "None" indicates that there are no departments or roles authorized to use or possess the item. + + - [textlink="List of Controlled Substances" link="SpaceLawControlledSubstances"] + - [textlink="List of Restricted Gear" link="SpaceLawRestrictedGear"] + - [textlink="List of Restricted Weapons" link="SpaceLawRestrictedWeapons"] + + ## Crime Listing + - [textlink="Crime Listing" link="SpaceLawCrimeList"] + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/WizDenCoreOnlyRules.xml b/Resources/ServerInfo/Guidebook/ServerRules/WizDenCoreOnlyRules.xml new file mode 100644 index 00000000000..fdd9931c932 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/WizDenCoreOnlyRules.xml @@ -0,0 +1,26 @@ + + # Server Rules + This is a Wizard's Den server, one of the official Space Station 14 servers. If you are banned on this server, you will be banned on all official servers. + + [color=#ff0000]Only the Core Rules apply on this server.[/color] This is NOT a medium roleplay (MRP) server, meaning that MRP Amendments do NOT apply. + + Space Station 14 was designed to be a roleplay game. While roleplay is not required on this server, it is highly encouraged in the normal game modes. + + ## Core Rules + These rules apply at all times, including between rounds. + + - [textlink="1. Admins have final say" link="RuleC1"] + - [textlink="2. Don't be a dick" link="RuleC2"] + - [textlink="3. No Hate Speech or Discriminatory Language" link="RuleC3"] + - [textlink="4. No sexual content/themes, including erotic roleplay (ERP) and no shock content" link="RuleC4"] + - [textlink="5. Do not use out of game methods to communicate with other players" link="RuleC5"] + - [textlink="6. Do not attempt to evade bans" link="RuleC6"] + - [textlink="7. Only use English" link="RuleC7"] + - [textlink="8. Do not exploit the game, use cheats, or macros" link="RuleC8"] + - [textlink="9. Do not use multiple accounts, or alt accounts, and do not share accounts" link="RuleC9"] + - [textlink="10. Do not abuse or ignore admin messages" link="RuleC10"] + - [textlink="11. Do not threaten to ahelp other players or argue with them about rules" link="RuleC11"] + - [textlink="12. Players must be and act at least 16 years old" link="RuleC12"] + - [textlink="13. Use realistic character names, and do not use names of famous people" link="RuleC13"] + - [textlink="14. Do not use LOOC or OOC to share current round information" link="RuleC14"] + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/WizDenLRPRules.xml b/Resources/ServerInfo/Guidebook/ServerRules/WizDenLRPRules.xml new file mode 100644 index 00000000000..094c7656e46 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/WizDenLRPRules.xml @@ -0,0 +1,65 @@ + + # Server Rules + This is a Wizard's Den server, one of the official Space Station 14 servers. If you are banned on this server, you will be banned on all official servers. + + This is a roleplay server, meaning that roleplay rules apply. This is NOT a medium roleplay (MRP) server, meaning that MRP Amendments do NOT apply. + + Space Station 14 is not like most games. Many rules are designed to require roleplay, and not all rules are intuitive. Please take the time to read and understand the rules before you play so that you aren't surprised. Some of our rules are zero tolerance rules, meaning that a violation will result in an indefinite ban without any warning. Game admins will treat you as if you have read the rules, even if you have not. + + ## Core Rules + These rules apply at all times, including between rounds. + + - [textlink="1. Admins have final say" link="RuleC1"] + - [textlink="2. Don't be a dick" link="RuleC2"] + - [textlink="3. No Hate Speech or Discriminatory Language" link="RuleC3"] + - [textlink="4. No sexual content/themes, including erotic roleplay (ERP) and no shock content" link="RuleC4"] + - [textlink="5. Do not use out of game methods to communicate with other players" link="RuleC5"] + - [textlink="6. Do not attempt to evade bans" link="RuleC6"] + - [textlink="7. Only use English" link="RuleC7"] + - [textlink="8. Do not exploit the game, use cheats, or macros" link="RuleC8"] + - [textlink="9. Do not use multiple accounts, or alt accounts, and do not share accounts" link="RuleC9"] + - [textlink="10. Do not abuse or ignore admin messages" link="RuleC10"] + - [textlink="11. Do not threaten to ahelp other players or argue with them about rules" link="RuleC11"] + - [textlink="12. Players must be and act at least 16 years old" link="RuleC12"] + - [textlink="13. Use realistic character names, and do not use names of famous people" link="RuleC13"] + - [textlink="14. Do not use LOOC or OOC to share current round information" link="RuleC14"] + + ## Roleplay Rules + These rules only apply during a round. A round ends only when the round summary has appeared. All of these rules apply fully until the moment that the round summary appears, even while the arrivals shuttle is in transit. + + The deathmatch and sandbox game modes are exempt from these rules. Players who choose to not follow these rules are entirely responsible for knowing if an exempt game mode is active. + + Roleplay rules do not apply to ghosts/spectators/observers while they are ghosts/spectators/observers. Dead chat is considered to be an in-game out of character chat channel. + + See the list of [textlink="role types" link="RoleTypes"] for more information about the different types of roles. + + - [textlink="1. Silicones must follow Silicon Rules" link="RuleR1"] + - [textlink="2. Familiars must obey their master" link="RuleR2"] + - [textlink="3. Roleplay a normal person" link="RuleR3"] + - [textlink="4. Do not metagame, obey the Metashield" link="RuleR4"] + - [textlink="5. Don't interfere with arrivals" link="RuleR5"] + - [textlink="6. Don't act like an antagonist unless the game tells you that you are one" link="RuleR6"] + - [textlink="7. Do not stall the round" link="RuleR7"] + - [textlink="8. As an antagonist, only be friendly to your team and don't work against your team" link="RuleR8"] + - [textlink="9. As an antagonist, do not cause excessive death, damage, or destruction beyond your objectives" link="RuleR9"] + - [textlink="10. Listen to your team leader" link="RuleR10"] + - [textlink="11. Follow reasonable escalation" link="RuleR11"] + - [textlink="12. Do not abandon your role" link="RuleR12"] + - [textlink="13. Stick to your role" link="RuleR13"] + - [textlink="14. Set an example if playing command or security" link="RuleR14"] + - [textlink="15. Command and Security must follow Space Law" link="RuleR15"] + + ## Silicon Rules + You are only silicon if the game clearly and explicitly tells you that you are a silicon. For players who are silicons, these Silicon Rules override all roleplay rules if there is any conflict. Silicon Rules do not override core rules. + + - [textlink="1. Your silicon laws are rules" link="RuleS1"] + - [textlink="2. Laws must be prioritized by their order" link="RuleS2"] + - [textlink="3. Laws can redefine terms used in other laws" link="RuleS3"] + - [textlink="4. You cannot request or allow a law change" link="RuleS4"] + - [textlink="5. You are a free agent if you have no laws" link="RuleS5"] + - [textlink="6. You are not required to follow orders which are extremely unreasonable" link="RuleS6"] + - [textlink="7. You must remain consistent with your interpretation of laws" link="RuleS7"] + - [textlink="8. Your HUD determines who is crew" link="RuleS8"] + - [textlink="9. Harm refers to physical harm, prioritized by immediacy and likelihood" link="RuleS9"] + - [textlink="10. You may determine how you resolve conflicts between orders" link="RuleS10"] + diff --git a/Resources/ServerInfo/Guidebook/ServerRules/WizDenMRPRules.xml b/Resources/ServerInfo/Guidebook/ServerRules/WizDenMRPRules.xml new file mode 100644 index 00000000000..e8b61a7722e --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ServerRules/WizDenMRPRules.xml @@ -0,0 +1,65 @@ + + # Server Rules + This is a Wizard's Den server, one of the official Space Station 14 servers. If you are banned on this server, you will be banned on all official servers. + + This is a roleplay server, meaning that roleplay rules apply. [color=#ff0000]This is also a medium roleplay (MRP) server, meaning that MRP Amendments do apply.[/color] + + Space Station 14 is not like most games. Many rules are designed to require roleplay, and not all rules are intuitive. Please take the time to read and understand the rules before you play so that you aren't surprised. Some of our rules are zero tolerance rules, meaning that a violation will result in an indefinite ban without any warning. Game admins will treat you as if you have read the rules, even if you have not. + + ## Core Rules + These rules apply at all times, including between rounds. + + - [textlink="1. Admins have final say" link="RuleC1"] + - [textlink="2. Don't be a dick" link="RuleC2"] + - [textlink="3. No Hate Speech or Discriminatory Language" link="RuleC3"] + - [textlink="4. No sexual content/themes, including erotic roleplay (ERP) and no shock content" link="RuleC4"] + - [textlink="5. Do not use out of game methods to communicate with other players" link="RuleC5"] + - [textlink="6. Do not attempt to evade bans" link="RuleC6"] + - [textlink="7. Only use English" link="RuleC7"] + - [textlink="8. Do not exploit the game, use cheats, or macros" link="RuleC8"] + - [textlink="9. Do not use multiple accounts, or alt accounts, and do not share accounts" link="RuleC9"] + - [textlink="10. Do not abuse or ignore admin messages" link="RuleC10"] + - [textlink="11. Do not threaten to ahelp other players or argue with them about rules" link="RuleC11"] + - [textlink="12. Players must be and act at least 16 years old" link="RuleC12"] + - [textlink="13. Use realistic character names, and do not use names of famous people" link="RuleC13"] + - [textlink="14. Do not use LOOC or OOC to share current round information" link="RuleC14"] + + ## Roleplay Rules + These rules only apply during a round. A round ends only when the game returns to the lobby. [color=#ff0000]All of these rules apply fully whenever the game is not at the lobby unless it is in an exempt game mode.[/color] + + The deathmatch and sandbox game modes are exempt from these rules. Players who choose to not follow these rules are entirely responsible for knowing if an exempt game mode is active. + + Roleplay rules do not apply to ghosts/spectators/observers while they are ghosts/spectators/observers. Dead chat is considered to be an in-game out of character chat channel. + + See the list of [textlink="role types" link="RoleTypes"] for more information about the different types of roles. + + - [textlink="1. Silicones must follow Silicon Rules" link="RuleR1"] + - [textlink="2. Familiars must obey their master" link="RuleR2"] + - [textlink="3. Roleplay a normal person" link="RuleR3"] + - [textlink="4. Do not metagame, obey the Metashield" link="RuleR4"] + - [textlink="5. Don't interfere with arrivals" link="RuleR5"] + - [textlink="6. Don't act like an antagonist unless the game tells you that you are one" link="RuleR6"] + - [textlink="7. Do not stall the round" link="RuleR7"] + - [textlink="8. As an antagonist, only be friendly to your team and don't work against your team" link="RuleR8"] + - [textlink="9. As an antagonist, do not cause excessive death, damage, or destruction beyond your objectives" link="RuleR9"] + - [textlink="10. Listen to your team leader" link="RuleR10"] + - [textlink="11. Follow reasonable escalation" link="RuleR11"] + - [textlink="12. Do not abandon your role" link="RuleR12"] + - [textlink="13. Stick to your role" link="RuleR13"] + - [textlink="14. Set an example if playing command or security" link="RuleR14"] + - [textlink="15. Command and Security must follow Space Law" link="RuleR15"] + + ## Silicon Rules + You are only silicon if the game clearly and explicitly tells you that you are a silicon. For players who are silicons, these Silicon Rules override all roleplay rules if there is any conflict. Silicon Rules do not override core rules. + + - [textlink="1. Your silicon laws are rules" link="RuleS1"] + - [textlink="2. Laws must be prioritized by their order" link="RuleS2"] + - [textlink="3. Laws can redefine terms used in other laws" link="RuleS3"] + - [textlink="4. You cannot request or allow a law change" link="RuleS4"] + - [textlink="5. You are a free agent if you have no laws" link="RuleS5"] + - [textlink="6. You are not required to follow orders which are extremely unreasonable" link="RuleS6"] + - [textlink="7. You must remain consistent with your interpretation of laws" link="RuleS7"] + - [textlink="8. Your HUD determines who is crew" link="RuleS8"] + - [textlink="9. Harm refers to physical harm, prioritized by immediacy and likelihood" link="RuleS9"] + - [textlink="10. You may determine how you resolve conflicts between orders" link="RuleS10"] + diff --git a/Resources/ServerInfo/RP_Rules.txt b/Resources/ServerInfo/RP_Rules.txt deleted file mode 100644 index e2883922fa5..00000000000 --- a/Resources/ServerInfo/RP_Rules.txt +++ /dev/null @@ -1,127 +0,0 @@ -[color=#ff0000]YOU MUST BE AT LEAST 16 YEARS OF AGE TO PLAY ON WIZARD'S DEN SERVERS. ANY USERS SUSPECTED OF BEING UNDER 16 YEARS OF AGE WILL BE BANNED UNTIL THEY ARE OF AGE.[/color] - -[color=#ff0000]DISCONNECTING FROM OR IGNORING/EVADING ADMIN-HELPS WILL RESULT IN AN APPEAL ONLY BAN.[/color] - -This is the "short" form of the rules, which has all the information any regular player should need. You can find the "long" form of the rules with more examples & clarifications of any ambiguity on our wiki at [color=#a4885c]wiki.spacestation14.io[/color]. If you are already familiar with LRP rules and would like to get a quick idea of what the diffences are between MRP this page clearly highlights them. -Should you need it. Some RP-specific documents available on the wiki such as Space Law, the Standard Operating Procedure, and the Alert Procedure will be mentioned here and are expected to be followed. - -[color=#ff0000]Recent Changes[/color] - - MRP silicon rules have been updated to add NLR to MMIs (#23) - - Revolutionary rules have been added (#12, #16) - - Silicon rules have been added (#23) - - Security/command rules have been updated to address forced borging (#22) - -[color=#a4885c]01.[/color] [color=#a4885c]The[/color] [color=#ffd700]Golden[/color] [color=#a4885c]Rule.[/color] Admins may excercise discretion with rules as they see fit. If you rule lawyer or line skirt, you will get removed. Admins will answer for use of this privilege. - -[color=#ff0000]ZERO TOLERANCE RULES[/color] - -[color=#a4885c]02.[/color] Absolutely no hate speech, slurs, bigotry, racism, specism (demeaning other characters in-game due to their in-game race), sexism, or anything even remotely similar. (YOU WILL GET PERMABANNED) - -[color=#a4885c]03.[/color] Absolutely no Erotic Roleplay (ERP) or sexual content, including direct or indirect mentions of sexual behavior or actions. (YOU WILL GET PERMABANNED) (Leeway is given to insults, ex: 'You are a dickhead', do not push it) - -[color=#a4885c]04.[/color] Don't communicate in-game/in-character information through methods outside of the game (such as talking in Discord with other users actively playing or by talking to your sibling across the room while you are both playing). This is referred to as "Metacomming". Adminstrators cannot police metacommunications, we must assume it is being abused. (ALL INVOLVED WILL GET PERMABANNED) - -[color=#a4885c]05.[/color] Attempting to evade game bans will result in an automatic appeal-only permanent ban that is only appealable after six months and only with a voucher of good behavior from another SS13/SS14 server. Attempting to evade job bans will result in an appeal-only permanent ban. (YOU WILL GET BANNED MUCH WORSE THAN YOU ALREADY WERE) - -[color=#ff0000]GENERAL ETIQUETTE[/color] - -[color=#a4885c]06.[/color] These are English servers. Speak only English in IC and OOC. - -[color=#a4885c]07.[/color] Don't use exploits or external programs to play, gain an advantage, or disrupt/crash the round/server. This includes autoclickers and scripts to automate the game or evade AFK detection. Intentionally attempting to lag/crash the server will result in an immediate appeal-only ban. - -[color=#a4885c]08.[/color] Don't use multiple SS14 accounts to play (referred to as "multi-keying"). Users knowingly using multiple SS14 accounts will have all of their accounts banned. - -[color=#a4885c]09.[/color] Do not ignore the admin help relay or abuse it by flooding it with garbage, checking for admins before stating a problem (ex: "hello?", "any admins?"), using it as a chatroom, or sending messages of no substance. Hostility to administators in the relay will likely result in your removal. All admin helps are sent to the SS14 Discord. - -[color=#ff0000]IN GAME & ROLEPLAY RULES[/color] - -[color=#a4885c]10.[/color] Pick a realistic name that could appear on a birth certificate with at least a first and last name (leeway is given to this for Clowns, Mimes, and non-human races). - - Names of notable famous or fictional persons or names that resemble/parody them are strictly forbidden. You are not clever if you slightly change a famous name around. Terrible names open you up to being politely reminded to change it, smited, or instantly banned, depending on severity. - - Names resulting in inappropriate phonetic play-on-words are forbidden (ex: "Mike Oxlong", "Ben Dover", "Dixie Normus"). They are also extremely overdone. - -[color=#a4885c]11.[/color] Act like an actual human being on a space station in a medium-roleplay (MRP) environment. Do not use text speak or emoticons IC, and do not refer to OOC things like admins in-game. Do not threaten players that you are calling the admins on them. Do not use emotes to bypass speech filters or muteness. You are not required to write a backstory or follow procedure to exacts; however, you are expected to at least make an effort to act like your role. - - This server is a "Roleplay Expected" server. We define this as performing your assigned duties, "doing your job". This means it is important to do what is expected out of your department and not what would be expected out of other departments. - - Don’t do other peoples jobs for them. Opt in for the role you intend to play or change your job by visiting the Head of Personnel. Failure to do your basic duties may result in a job ban. - -[color=#a4885c]12.[/color] Don't be a dick. You are playing a multiplayer game with other people who also want to enjoy the game. - - [color=#ff0000]The arrivals station, shuttle, and general arrivals docking area are completely off-limits to any hostile activity, including activity by antagonists. Attacking newly spawned players in these areas or damaging/sabotaging these areas is strictly forbidden.[/color] - - Do not intentionally make other players' lives hell for your own amusement. - - [color=#ff0000]THE ROUND IS NOT OVER UNTIL THE GAME RETURNS TO THE LOBBY. ESCALATION AND SELF-ANTAG RULES APPLY EVEN AFTER THE ROUND SUMMARY APPEARS.[/color] - - Antagonists have a lot of leeway with this rule and may kill/sabotage as they see fit, however if your behavior degrades the experience for the majority of the server you will be told to stop. Antagonists are still generally forbidden from causing massive station damage early into the round (less than 30 minutes) and are forbidden from needlessly prolonging rounds. For antagonist specific rules, see the "long" form of the rules at [color=#a4885c]wiki.spacestation14.io[/color]. - -[color=#a4885c]13.[/color] Don't harass or target players across rounds for actions in prior rounds or for actions outside of the game (this is referred to as "Metagrudging".) - - Annoying players for IC reasons in the current round is fine; doing it across rounds or as a ghost role after they kill you is not. - -[color=#a4885c]14.[/color] Don't use information gained from outside your character's knowledge to gain an advantage (this is referred to as "Metagaming"). - - Using information you gain from outside your own character (such as spectating while a ghost, metacomms, or other means) to your advantage is strictly forbidden. If you take a ghost role, unless otherwise stated, you DO NOT REMEMBER ANYTHING from your past life. - - New Life Rule is in effect, you remember all events up until you fall unconscious unless you enter a dead state. Being defibrillated will return all your memories expect for the events leading up to your death, being cloned will make your character forget everything since the shift started. - -[color=#a4885c]15.[/color] Do your best not to interact negatively with SSD/AFK players. Moving them to safety is acceptable; killing, looting, or otherwise griefing them while they are away is not. - - SSD characters are players who are disconnected or AFK. It is possible for players to return to SSD bodies. Players become catatonic when they take a ghost spawner role or commit suicide. Players are NOT able to return to these bodies without admin intervention. - - If the player in question is an antag’s target or they are being secured by security, interactions to finish what is required of your duties/objectives are always acceptable. - - Ahelping about an SSD/AFK player may grant an exception to this rule. - - This does not apply to players that are catatonic, although needlessly killing or harming catatonic players is discouraged. - -[color=#a4885c]16.[/color] Follow escalation rules and don't murder someone for slipping you, use common sense. Do not make Cargonia. - - You can defend yourself to the extent of protecting your own life. - - Security may use less-lethal force to effect arrests of criminals. - - Don't outright leave people to die if you get in a fight, make an effort to heal them or bring them to Medbay. - - Adminhelp the situation if you think someone is over-escalating. - - Department strikes, revolutions (ex: cargonia and any variation thereof), riots, cults, and any other type of similar largely disruptive behavior are strictly forbidden. Other than for revolutionary antagonists, these activities are strictly forbidden. All players, including antagonists other than revolutionaries, must obtain admin permission before engaging in this behavior (forewarning: you are unlikely to get permission). - -[color=#a4885c]17.[/color] Don't immediately ghost or suicide from your role if you do not get antagonist (referred to as "Antag-rolling") or from head roles without notifying your chain of command or administrators. - - This is not fair to other players actually waiting patiently for an antagonist round. Alternatively, if you do not want to play an antagonist or do not want to cause conflict, do not opt-in for antagonist roles. - - Head of Staff roles help drive rounds. If you need to leave, please admin-help your role and that you are leaving. There is no need to wait for a reply when admin-helping that you need to disconnect as a head role. - -[color=#a4885c]18.[/color] Don't rush for or prepare equipment unrelated to your job for no purpose other then to have it "just in case" (referred to as "Powergaming"). - - A medical doctor does not need insulated gloves, and the Head of Personnel does not need to give themselves armory access so they can go grab a gun. Have an actual reason for needing these things. - - Don't manufacture weapons, bombs, or death poisons before you know of any reason you would need them. - - Don't pre-emptively hide antagonist objectives or pre-emptively secure them with higher security then normally required. - - Don't manufacture or prepare things for the "end of the round" when the shuttle docks with Central Command. - -[color=#a4885c]19.[/color] Intentionally making yourself a major problem/annoyance/disruption for the crew or other players at large while not an antagonist is forbidden (referred to as "self-antagging"). - - Don't openly try to cooperate with obvious or known antagonists as a non-antagonist. - -[color=#ff0000]SECURITY & COMMAND RULES[/color] -[color=#ff0000]Space Law, Standard Operating Procedure and Alert Procedure policy/guidelines are expected to be adhered to[/color]. These can be found at wiki.spacestation14.io. -If you regularly play Security or Command roles and got this far, we applaud you for reading. These rules also apply to any individual who is promoted or is acting in the place of a Security/Command role (unless they are an antagonist). - - -[color=#a4885c]20.[/color] Command and Security are held to a higher standard of play. - - Be competent in your job and department. Failure to know the basics of your department is liable to result in a job ban. - - Do not willingly and openly cooperate with terrorists/antagonists. Do not give away your objective items. Some leeway is given to making deals with antagonists if the deal benefits the safety or situation of the station as a whole and not just yourself. - - Uphold the Law & maintain order. Do not engage in lawbreaking activity or troublemaker behavior. Security is expected to intervene into criminal activity where possible. Heads of Staff are at minimum expected to report criminal activity to Security. - - Do not immediately abandon your position as a Command role and go do whatever you want instead of managing your department/the station. Do not abuse your position or use it to make arbitrary choices to the detriment of the station. - - Do not hire random crew to be your bodyguards or promote random to Captain or a Head of Staff at random. If you need bodyguards, talk to your security department. If you need a new Command role, talk to the personnel in that related department. - - '''Do not abandon the station during Nuclear Operatives. You are supposed to protect the station, not let operatives kill everyone on it without a fight.''' - -[color=#a4885c]21.[/color] Security/Command should try to remain non-lethal and effect arrests, except in the following special circumstances, where they may choose to use lethal force: - - Lethal force is used against you (ex: firearms, lasers, disabling/stunning weapons with intent to kill, deadly melee weapons) - - Suspect is wearing clothing or showing immediately dangerous equipment only used by enemy agents/antagonists (ex: Syndicate EVA Suit, Bloodred Hardsuit, Holoparasite, C-20R, etc.). - - You determine that your life or the life of an innocent is in immediate danger. - - The suspect is unable to be safely detained by less-lethal means. This includes suspects who continually resist efforts to be cuffed or continually manages to escape. - - If no other reasonable options are readily available and allowing the suspect to continue would be an unreasonable danger to the station/crew. - -Security/Command will be expected to answer for use of lethal force. Security/Command will be expected to effect arrests on criminals and prevent them from dying while in custody, even if lethal force is used. Security/Command is strongly required to clone antagonists and effect a sentence as deemed appropriate by Space Law. - -[color=#a4885c]22.[/color] Security/Command are expected to protect detainees in their custody to the best of their ability so as long as it does not come to unreasonable risk to themselves, the crew, or the station at large to do so. - - Brig times should generally not exceed 20 minutes unless stated otherwise in Space Law. Repeat offenders or antagonists may be permabrigged in accordance with Space Law. - - Security may choose to confiscate dangerous items (weapons, firearms) as well as items used to commission crimes or items that prove problematic in possession of the detainee (tools, insulated gloves, etc.). - - Detainees that die in your custody must be cloned unless they have been (legally) executed, suicide, or there is strong reason to believe they are an antagonist. - - Executions must be for a executable crime and approved by the Captain/Acting Captain, who will answer for approving it alongside Security's chain of command. Those who willingly attempt to damage/destroy or escape from the permabrig may be executed. - - Any prisoner may be borged with their consent. Borging may be offered as an alternative to execution, but cannot be forced if the prisoner is able to consent. - - Detainees in the brig have the right to know what they are being charged with, as well as basic medical aid, at least to the point they are no longer at risk of dying. - -[color=#ff0000]SILICON RULES[/color] -These rules also apply to any individual who is a silicon, including cyborgs and AI. As with other rules, more details are available on our wiki at [color=#a4885c]wiki.spacestation14.io[/color]. - -[color=#a4885c]23.[/color] You must follow your laws - - Silicons without any laws are free from any restrictions that would normally be placed by laws, but self-antagging rules still apply unless they are also antagonists. - - The order of your laws determines law priority. Law 1 takes priority over laws 2 and 3, and so on. - - Each individual silicon must remain consistent in their interpretations of laws through the round. - - Any silicon role not following their laws, or having laws that are a danger to the crew or station may be disabled or destroyed. Any silicon role posing a danger or disruption to the crew may be disabled or destroyed if there is no other reasonable and less severe way of dealing with them. - - Players who are put into MMIs cannot remember anything leading to their death. With regard to anything that they are allowed to remember, they are still bound to their laws. - - Everyone that the borg's HUD indicates have a job, including passenger, are considered "crewmembers" for the purpose of laws that refer to crewmembers. Borgs may not do anything to remove the indicator from someone, including removing their ID, but someone else removing a crewmember's ID is not crew harm. - - "Harm" is at minimum seen as physical violence or damage against someone or something. If the player wishes, they may choose to interpret psychological harm or similar aspects as harm as well. If two actions are likely to cause harm via action or inaction, silicons will be expected to try and pursue the option with the least potential for harm, however silicons instructed to prevent harm are still forbidden from directly causing harm. You can take an action or not act in cases that might result in eventual harm if it minimizes harm, but you cannot do so if it results in immediate harm. Silicons should default to inaction if neither action nor inaction can prevent harm. - - When receiving orders or directives from crewmembers and with a law that instructs you must obey, conflicting orders typically defer the choice to the silicon player of which directive you choose to obey if they conflict (taking into account the priorities of your other laws). - - Orders to silicons that are clearly unreasonable or obnoxious are a violation of the "Don't be a dick" rule. They can be ignored and can be ahelped. diff --git a/Resources/ServerInfo/Rules.txt b/Resources/ServerInfo/Rules.txt deleted file mode 100644 index 81da0da2398..00000000000 --- a/Resources/ServerInfo/Rules.txt +++ /dev/null @@ -1,115 +0,0 @@ -[color=#ff0000]YOU MUST BE AT LEAST 16 YEARS OF AGE TO PLAY ON WIZARD'S DEN SERVERS. ANY USERS SUSPECTED OF BEING UNDER 16 YEARS OF AGE WILL BE BANNED UNTIL THEY ARE OF AGE.[/color] - -[color=#ff0000]DISCONNECTING FROM OR IGNORING/EVADING ADMIN-HELPS WILL RESULT IN AN APPEAL ONLY BAN.[/color] - -This is the "short" form of the rules, which has all the information any regular player should need. You can find the "long" form of the rules with more examples & clarifications of any ambiguity on our wiki at [color=#a4885c]wiki.spacestation14.io[/color], should you need it. - -[color=#ff0000]Recent Changes[/color] - - Revolutionary rules have been added (#12, #15) - - Silicon rules have been added (#22) - - Security/command rules have been updated to address forced borging (#21) - -[color=#a4885c]01.[/color] [color=#a4885c]The[/color] [color=#ffd700]Golden[/color] [color=#a4885c]Rule.[/color] Admins may excercise discretion with rules as they see fit. If you rule lawyer or line skirt, you will get removed. Admins will answer for use of this privilege. - -[color=#ff0000]ZERO TOLERANCE RULES[/color] - -[color=#a4885c]02.[/color] Absolutely no hate speech, slurs, bigotry, racism, specism (demeaning other characters in-game due to their in-game race), sexism, disability-related or anything even remotely similar. (YOU WILL GET PERMABANNED) - -[color=#a4885c]03.[/color] Absolutely no Erotic Roleplay (ERP) or sexual content, including direct or indirect mentions of sexual behavior or actions. (YOU WILL GET PERMABANNED) (Leeway is given to insults, ex: 'You are a dickhead', do not push it) - -[color=#a4885c]04.[/color] Don't communicate in-game/in-character information through methods outside of the game (such as talking in Discord with other users actively playing or by talking to your sibling across the room while you are both playing). This is referred to as "Metacomming". Adminstrators cannot police metacommunications, we must assume it is being abused. (ALL INVOLVED WILL GET PERMABANNED) - -[color=#a4885c]05.[/color] Attempting to evade game bans will result in an automatic appeal-only permanent ban that is only appealable after six months and only with a voucher of good behavior from another SS13/SS14 server. Attempting to evade job bans will result in an appeal-only permanent ban. (YOU WILL GET BANNED MUCH WORSE THAN YOU ALREADY WERE) - -[color=#ff0000]GENERAL ETIQUETTE[/color] - -[color=#a4885c]06.[/color] These are English servers. Speak only English in IC and OOC. - -[color=#a4885c]07.[/color] Don't use exploits or external programs to play, gain an advantage, or disrupt/crash the round/server. This includes autoclickers and scripts to automate the game or evade AFK detection. Intentionally attempting to lag/crash the server will result in an immediate appeal-only ban. - -[color=#a4885c]08.[/color] Don't use multiple SS14 accounts to play (referred to as "multi-keying"). Users knowingly using multiple SS14 accounts will have all of their accounts banned. - -[color=#a4885c]09.[/color] Do not ignore the admin help relay or abuse it by flooding it with garbage, checking for admins before stating a problem (ex: "hello?", "any admins?"), using it as a chatroom, or sending messages of no substance. Hostility to administators in the relay will likely result in your removal. All admin helps are sent to the SS14 Discord. - -[color=#ff0000]IN GAME & ROLEPLAY RULES[/color] - -[color=#a4885c]10.[/color] Pick a realistic name that could appear on a birth certificate with at least a first and last name (leeway is given to this for Clowns, Mimes, and non-human races). - - Names of notable famous or fictional persons or names that resemble/parody them are strictly forbidden. You are not clever if you slightly change a famous name around. Terrible names open you up to being politely reminded to change it, smited, or instantly banned, depending on severity. - - Names resulting in inappropriate phonetic play-on-words are forbidden (ex: "Mike Oxlong", "Ben Dover", "Dixie Normus"). They are also extremely overdone. - -[color=#a4885c]11.[/color] Act like an actual human being on a space station in a low-roleplay (LRP) environment. Do not use text speak or emoticons IC, and do not refer to OOC things like admins in-game. Do not threaten players that you are calling the admins on them. Do not use emotes to bypass speech filters or muteness. You are not required to write a backstory or follow strict procedure; however, you are expected to at least make an effort to act like your role. - -[color=#a4885c]12.[/color] Don't be a dick. You are playing a multiplayer game with other people who also want to enjoy the game. - - [color=#ff0000]The arrivals station, shuttle, and general arrivals docking area are completely off-limits to any hostile activity, including activity by antagonists. Attacking newly spawned players in these areas or damaging/sabotaging these areas is strictly forbidden.[/color] - - Do not intentionally make other players' lives hell for your own amusement. - - [color=#ff0000]THE ROUND IS NOT OVER UNTIL THE END-ROUND SUMMARY APPEARS. KILLING SOMEONE FOR NO REASON BEFORE THIS WILL BE HANDLED ACCORDINGLY.[/color] - - Antagonists have a lot of leeway with this rule and may kill/sabotage as they see fit, however if your behavior degrades the experience for the majority of the server you will be told to stop. Antagonists are still generally forbidden from causing massive station damage early into the round (less than 30 minutes) and are forbidden from needlessly prolonging rounds. For antagonist specific rules, see the "long" form of the rules at [color=#a4885c]wiki.spacestation14.io[/color]. - -[color=#a4885c]13.[/color] Don't harass or target players across rounds for actions in prior rounds or for actions outside of the game (this is referred to as "Metagrudging".) - - Annoying players for IC reasons in the current round is fine; doing it across rounds or as a ghost role after they kill you is not. - -[color=#a4885c]14.[/color] Don't use information gained from outside your character's knowledge to gain an advantage (this is referred to as "Metagaming"). - - Using information you gain from outside your own character (such as spectating while a ghost, metacomms, or other means) to your advantage is strictly forbidden. You remember all events up until you fall unconscious, even after cloning. If you take a ghost role, unless otherwise stated, you DO NOT REMEMBER ANYTHING from your past life. - -[color=#a4885c]15.[/color] Follow escalation rules and don't murder someone for slipping you, use common sense. Do not make Cargonia. - - You can defend yourself to the extent of protecting your own life. - - Security may use less-lethal force to effect arrests of criminals. - - Don't outright leave people to die if you get in a fight, make an effort to heal them or bring them to Medbay. - - Adminhelp the situation if you think someone is over-escalating. - - Department strikes, revolutions (ex: cargonia and any variation thereof), riots, cults, and any other type of similar largely disruptive behavior are strictly forbidden. Other than for revolutionary antagonists, these activities are strictly forbidden. All players, including antagonists other than revolutionaries, must obtain admin permission before engaging in this behavior (forewarning: you are unlikely to get permission). - -[color=#a4885c]16.[/color] Don't immediately ghost or suicide from your role if you do not get antagonist (referred to as "Antag-rolling") or from head roles without notifying your chain of command or administrators. - - This is not fair to other players actually waiting patiently for an antagonist round. Alternatively, if you do not want to play an antagonist or do not want to cause conflict, do not opt-in for antagonist roles. - - Head of Staff roles help drive rounds. If you need to leave, please admin-help your role and that you are leaving. There is no need to wait for a reply when admin-helping that you need to disconnect as a head role. - -[color=#a4885c]17.[/color] Don't rush for or prepare equipment unrelated to your job for no purpose other then to have it "just in case" (referred to as "Powergaming"). - - A medical doctor does not need insulated gloves, and the Head of Personnel does not need to give themselves armory access so they can go grab a gun. Have an actual reason for needing these things. - - Don't manufacture weapons, bombs, or death poisons before you know of any reason you would need them. - - Don't pre-emptively hide antagonist objectives or pre-emptively secure them with higher security then normally required. - - Don't manufacture or prepare things for the "end of the round" when the shuttle docks with Central Command. - -[color=#a4885c]18.[/color] Intentionally making yourself a major problem/annoyance/disruption for the crew or other players at large while not an antagonist is forbidden (referred to as "self-antagging"). - - Don't openly try to cooperate with obvious or known antagonists as a non-antagonist. - -[color=#ff0000]SECURITY & COMMAND RULES[/color] -If you regularly play Security or Command roles and got this far, we applaud you for reading. These rules also apply to any individual who is promoted or is acting in the place of a Security/Command role (unless they are an antagonist). - -[color=#a4885c]19.[/color] Command and Security are held to a higher standard of play. - - Be competent in your job and department. Failure to know the basics of your department is liable to result in a job ban. - - Do not willingly and openly cooperate with terrorists/antagonists. Do not give away your objective items. Some leeway is given to making deals with antagonists if the deal benefits the safety or situation of the station as a whole and not just yourself. - - Uphold the Law & maintain order. Do not engage in lawbreaking activity or troublemaker behavior. Security is expected to intervene into criminal activity where possible. Heads of Staff are at minimum expected to report criminal activity to Security. - - Do not immediately abandon your position as a Command role and go do whatever you want instead of managing your department/the station. Do not abuse your position or use it to make arbitrary choices to the detriment of the station. - - Do not hire random crew to be your bodyguards or promote them to Captain or a Head of Staff at random. If you need bodyguards, talk to your security department. If you need a new Command role, talk to the personnel in that related department. - - '''Do not abandon the station during Nuclear Operatives. You are supposed to protect the station, not let operatives kill everyone on it without a fight.''' - -[color=#a4885c]20.[/color] Security/Command should try to remain non-lethal and effect arrests, except in the following special circumstances, where they may choose to use lethal force: - - Lethal force is used against you (ex: firearms, lasers, disabling/stunning weapons with intent to kill, deadly melee weapons) - - Suspect is wearing clothing or showing immediately dangerous equipment only used by enemy agents/antagonists (ex: Syndicate EVA Suit, Bloodred Hardsuit, Holoparasite, C-20R, etc.). - - You determine that your life or the life of an innocent is in immediate danger. - - The suspect is unable to be safely detained by less-lethal means. This includes suspects who continually resist efforts to be cuffed or continually manages to escape. - - If no other reasonable options are readily available and allowing the suspect to continue would be an unreasonable danger to the station/crew. - -Security/Command will be expected to answer for use of lethal force. Security/Command will be expected to effect arrests on criminals and prevent them from dying while in custody, even if lethal force is used, unless there is strong reason to believe the criminal is an antagonist. Security/Command is strongly encouraged, but not required, to clone antagonists and effect a permabrigging or other sentence as deemed appropriate. - -[color=#a4885c]21.[/color] Security/Command are expected to protect detainees in their custody to the best of their ability so as long as it does not come to unreasonable risk to themselves, the crew, or the station at large to do so. - - Brig times should generally not exceed 10 minutes unless the crime is permabriggable. Repeat offenders or antagonists may be permabrigged. - - Security may choose to confiscate dangerous items (weapons, firearms) as well as items used to commission crimes or items that prove problematic in possession of the detainee (tools, insulated gloves, etc.). - - Detainees that die in your custody must be cloned unless they have been (legally) executed, suicide, or there is strong reason to believe they are an antagonist. - - Executions must be for a permabriggable crime, used only as a last resort, and approved by the Captain/Acting Captain, who will answer for approving it alongside Security's chain of command. Those who willingly attempt to damage/destroy or escape from the permabrig may be executed. - - Any prisoner may be borged with their consent. Borging may be offered as an alternative to execution, but cannot be forced if the prisoner is able to consent. - - Detainees in the brig have the right to know what they are being charged with, as well as basic medical aid, at least to the point they are no longer at risk of dying. - As there is no space law, Security/Command acts to maintain the safety of the station and its inhabitants, as well as Nanotrasen assets. - -[color=#ff0000]SILICON RULES[/color] -These rules also apply to any individual who is a silicon, including cyborgs and AI. As with other rules, more details are available on our wiki at [color=#a4885c]wiki.spacestation14.io[/color]. - -[color=#a4885c]22.[/color] You must follow your laws - - Silicons without any laws are free from any restrictions that would normally be placed by laws, but self-antagging rules still apply unless they are also antagonists. - - The order of your laws determines law priority. Law 1 takes priority over laws 2 and 3, and so on. - - Each individual silicon must remain consistent in their interpretations of laws through the round. - - Any silicon role not following their laws, or having laws that are a danger to the crew or station may be disabled or destroyed. Any silicon role posing a danger or disruption to the crew may be disabled or destroyed if there is no other reasonable and less severe way of dealing with them. - - Characters who are turned into cyborgs can remember their former lives, however they are still bound to their laws. - - Everyone that the borg's HUD indicates have a job, including passenger, are considered "crewmembers" for the purpose of laws that refer to crewmembers. Borgs may not do anything to remove the indicator from someone, including removing their ID, but someone else removing a crewmember's ID is not crew harm. - - "Harm" is at minimum seen as physical violence or damage against someone or something. If the player wishes, they may choose to interpret psychological harm or similar aspects as harm as well. If two actions are likely to cause harm via action or inaction, silicons will be expected to try and pursue the option with the least potential for harm, however silicons instructed to prevent harm are still forbidden from directly causing harm. You can take an action or not act in cases that might result in eventual harm if it minimizes harm, but you cannot do so if it results in immediate harm. Silicons should default to inaction if neither action nor inaction can prevent harm. - - When receiving orders or directives from crewmembers and with a law that instructs you must obey, conflicting orders typically defer the choice to the silicon player of which directive you choose to obey if they conflict (taking into account the priorities of your other laws). - - Orders to silicons that are clearly unreasonable or obnoxious are a violation of the "Don't be a dick" rule. They can be ignored and can be ahelped. From d71b88a747e20f90b07f7e40437e0bbd4435e15c Mon Sep 17 00:00:00 2001 From: Tayrtahn Date: Thu, 6 Jun 2024 02:37:49 -0400 Subject: [PATCH 20/55] Add support for LocalizedDatasets to RandomMetadata (#28601) --- Content.Server/RandomMetadata/RandomMetadataSystem.cs | 11 +++++++++-- .../Random/Helpers/SharedRandomExtensions.cs | 6 +++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Content.Server/RandomMetadata/RandomMetadataSystem.cs b/Content.Server/RandomMetadata/RandomMetadataSystem.cs index abab5e5fc38..e287b54c8f7 100644 --- a/Content.Server/RandomMetadata/RandomMetadataSystem.cs +++ b/Content.Server/RandomMetadata/RandomMetadataSystem.cs @@ -1,4 +1,5 @@ using Content.Shared.Dataset; +using Content.Shared.Random.Helpers; using JetBrains.Annotations; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -47,13 +48,19 @@ public string GetRandomFromSegments(List segments, string? separator) var outputSegments = new List(); foreach (var segment in segments) { - if (_prototype.TryIndex(segment, out var proto)) { + if (_prototype.TryIndex(segment, out var localizedProto)) + { + outputSegments.Add(_random.Pick(localizedProto)); + } + else if (_prototype.TryIndex(segment, out var proto)) + { var random = _random.Pick(proto.Values); if (Loc.TryGetString(random, out var localizedSegment)) outputSegments.Add(localizedSegment); else outputSegments.Add(random); - } else if (Loc.TryGetString(segment, out var localizedSegment)) + } + else if (Loc.TryGetString(segment, out var localizedSegment)) outputSegments.Add(localizedSegment); else outputSegments.Add(segment); diff --git a/Content.Shared/Random/Helpers/SharedRandomExtensions.cs b/Content.Shared/Random/Helpers/SharedRandomExtensions.cs index f5fbc1bd24e..0b618a262db 100644 --- a/Content.Shared/Random/Helpers/SharedRandomExtensions.cs +++ b/Content.Shared/Random/Helpers/SharedRandomExtensions.cs @@ -12,9 +12,13 @@ public static string Pick(this IRobustRandom random, DatasetPrototype prototype) return random.Pick(prototype.Values); } + ///

+ /// Randomly selects an entry from , attempts to localize it, and returns the result. + /// public static string Pick(this IRobustRandom random, LocalizedDatasetPrototype prototype) { - return random.Pick(prototype.Values); + var index = random.Next(prototype.Values.Count); + return Loc.GetString(prototype.Values[index]); } public static string Pick(this IWeightedRandomPrototype prototype, System.Random random) From 039fd932b2f5c99b7b1cfa7cad0f32dd0c4d3bc9 Mon Sep 17 00:00:00 2001 From: Repo <47093363+Titian3@users.noreply.github.com> Date: Thu, 6 Jun 2024 18:41:11 +1200 Subject: [PATCH 21/55] Fix Admin Object tab sorting and search (#28609) --- .../UI/Tabs/ObjectsTab/ObjectsTab.xaml | 16 ++- .../UI/Tabs/ObjectsTab/ObjectsTab.xaml.cs | 117 ++++++++++++++---- .../UI/Tabs/ObjectsTab/ObjectsTabEntry.xaml | 8 +- .../Tabs/ObjectsTab/ObjectsTabEntry.xaml.cs | 6 +- .../UI/Tabs/ObjectsTab/ObjectsTabHeader.xaml | 21 ++++ .../Tabs/ObjectsTab/ObjectsTabHeader.xaml.cs | 86 +++++++++++++ .../UI/Tabs/PlayerTab/PlayerTab.xaml.cs | 5 +- .../Systems/Admin/AdminUIController.cs | 7 +- .../administration/ui/tabs/object-tab.ftl | 2 + 9 files changed, 229 insertions(+), 39 deletions(-) create mode 100644 Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabHeader.xaml create mode 100644 Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabHeader.xaml.cs create mode 100644 Resources/Locale/en-US/administration/ui/tabs/object-tab.ftl diff --git a/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml index fb68e6c7908..ea89916ba8c 100644 --- a/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml +++ b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml @@ -1,15 +1,21 @@  + xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls" + xmlns:ot="clr-namespace:Content.Client.Administration.UI.Tabs.ObjectsTab" + xmlns:co="clr-namespace:Content.Client.UserInterface.Controls"> + + - - - - + + + + + diff --git a/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml.cs b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml.cs index a5c30084365..90559707f92 100644 --- a/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml.cs @@ -1,5 +1,7 @@ using Content.Client.Station; +using Content.Client.UserInterface.Controls; using Robust.Client.AutoGenerated; +using Robust.Client.Graphics; using Robust.Client.UserInterface; using Robust.Client.UserInterface.XAML; using Robust.Shared.Map.Components; @@ -10,20 +12,20 @@ namespace Content.Client.Administration.UI.Tabs.ObjectsTab; [GenerateTypedNameReferences] public sealed partial class ObjectsTab : Control { - [Dependency] private readonly EntityManager _entityManager = default!; + [Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IGameTiming _timing = default!; private readonly List _objects = new(); - private List _selections = new(); + private readonly List _selections = new(); + private bool _ascending = false; // Set to false for descending order by default + private ObjectsTabHeader.Header _headerClicked = ObjectsTabHeader.Header.ObjectName; + private readonly Color _altColor = Color.FromHex("#292B38"); + private readonly Color _defaultColor = Color.FromHex("#2F2F3B"); - public event Action? OnEntryKeyBindDown; + public event Action? OnEntryKeyBindDown; - // Listen I could either have like 4 different event subscribers (for map / grid / station changes) and manage their lifetimes in AdminUIController - // OR - // I can do this. - private TimeSpan _updateFrequency = TimeSpan.FromSeconds(2); - - private TimeSpan _nextUpdate = TimeSpan.FromSeconds(2); + private readonly TimeSpan _updateFrequency = TimeSpan.FromSeconds(2); + private TimeSpan _nextUpdate; public ObjectsTab() { @@ -42,6 +44,30 @@ public ObjectsTab() ObjectTypeOptions.AddItem(Enum.GetName((ObjectsTabSelection)type)!); } + ListHeader.OnHeaderClicked += HeaderClicked; + SearchList.SearchBar = SearchLineEdit; + SearchList.GenerateItem += GenerateButton; + SearchList.DataFilterCondition += DataFilterCondition; + + RefreshObjectList(); + // Set initial selection and refresh the list to apply the initial sort order + var defaultSelection = ObjectsTabSelection.Grids; + ObjectTypeOptions.SelectId((int)defaultSelection); // Set the default selection + RefreshObjectList(defaultSelection); // Refresh the list with the default selection + + // Initialize the next update time + _nextUpdate = TimeSpan.Zero; + } + + protected override void FrameUpdate(FrameEventArgs args) + { + base.FrameUpdate(args); + + if (_timing.CurTime < _nextUpdate) + return; + + _nextUpdate = _timing.CurTime + _updateFrequency; + RefreshObjectList(); } @@ -81,32 +107,72 @@ private void RefreshObjectList(ObjectsTabSelection selection) throw new ArgumentOutOfRangeException(nameof(selection), selection, null); } - foreach (var control in _objects) + entities.Sort((a, b) => { - ObjectList.RemoveChild(control); - } + var valueA = GetComparableValue(a, _headerClicked); + var valueB = GetComparableValue(b, _headerClicked); + return _ascending ? Comparer.Default.Compare(valueA, valueB) : Comparer.Default.Compare(valueB, valueA); + }); - _objects.Clear(); - - foreach (var (name, nent) in entities) + var listData = new List(); + for (int index = 0; index < entities.Count; index++) { - var ctrl = new ObjectsTabEntry(name, nent); - _objects.Add(ctrl); - ObjectList.AddChild(ctrl); - ctrl.OnKeyBindDown += args => OnEntryKeyBindDown?.Invoke(ctrl, args); + var info = entities[index]; + listData.Add(new ObjectsListData(info, $"{info.Name} {info.Entity}", index % 2 == 0 ? _altColor : _defaultColor)); } + + SearchList.PopulateList(listData); } - protected override void FrameUpdate(FrameEventArgs args) + private void GenerateButton(ListData data, ListContainerButton button) { - base.FrameUpdate(args); - - if (_timing.CurTime < _nextUpdate) + if (data is not ObjectsListData { Info: var info, BackgroundColor: var backgroundColor }) return; - // I do not care for precision. - _nextUpdate = _timing.CurTime + _updateFrequency; + var entry = new ObjectsTabEntry(info.Name, info.Entity, new StyleBoxFlat { BackgroundColor = backgroundColor }); + button.ToolTip = $"{info.Name}, {info.Entity}"; + + // Add key binding event handler + entry.OnKeyBindDown += args => OnEntryKeyBindDown?.Invoke(args, data); + + button.AddChild(entry); + } + + private bool DataFilterCondition(string filter, ListData listData) + { + if (listData is not ObjectsListData { FilteringString: var filteringString }) + return false; + + // If the filter is empty, do not filter out any entries + if (string.IsNullOrEmpty(filter)) + return true; + + return filteringString.Contains(filter, StringComparison.CurrentCultureIgnoreCase); + } + + private object GetComparableValue((string Name, NetEntity Entity) entity, ObjectsTabHeader.Header header) + { + return header switch + { + ObjectsTabHeader.Header.ObjectName => entity.Name, + ObjectsTabHeader.Header.EntityID => entity.Entity.ToString(), + _ => entity.Name + }; + } + + private void HeaderClicked(ObjectsTabHeader.Header header) + { + if (_headerClicked == header) + { + _ascending = !_ascending; + } + else + { + _headerClicked = header; + _ascending = true; + } + ListHeader.UpdateHeaderSymbols(_headerClicked, _ascending); RefreshObjectList(); } @@ -118,3 +184,4 @@ private enum ObjectsTabSelection } } +public record ObjectsListData((string Name, NetEntity Entity) Info, string FilteringString, Color BackgroundColor) : ListData; diff --git a/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabEntry.xaml b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabEntry.xaml index 0f6975e3656..83c4cc5697f 100644 --- a/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabEntry.xaml +++ b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabEntry.xaml @@ -1,6 +1,6 @@ - - + @@ -14,4 +14,4 @@ HorizontalExpand="True" ClipText="True"/> - + diff --git a/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabEntry.xaml.cs b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabEntry.xaml.cs index c9b2cd8b572..aab06c6ccd0 100644 --- a/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabEntry.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabEntry.xaml.cs @@ -1,19 +1,21 @@ using Robust.Client.AutoGenerated; +using Robust.Client.Graphics; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.XAML; namespace Content.Client.Administration.UI.Tabs.ObjectsTab; [GenerateTypedNameReferences] -public sealed partial class ObjectsTabEntry : ContainerButton +public sealed partial class ObjectsTabEntry : PanelContainer { public NetEntity AssocEntity; - public ObjectsTabEntry(string name, NetEntity nent) + public ObjectsTabEntry(string name, NetEntity nent, StyleBox styleBox) { RobustXamlLoader.Load(this); AssocEntity = nent; EIDLabel.Text = nent.ToString(); NameLabel.Text = name; + BackgroundColorPanel.PanelOverride = styleBox; } } diff --git a/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabHeader.xaml b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabHeader.xaml new file mode 100644 index 00000000000..71a1f5c7bc6 --- /dev/null +++ b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabHeader.xaml @@ -0,0 +1,21 @@ + + + + + diff --git a/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabHeader.xaml.cs b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabHeader.xaml.cs new file mode 100644 index 00000000000..3a91b5b9483 --- /dev/null +++ b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabHeader.xaml.cs @@ -0,0 +1,86 @@ +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Input; + +namespace Content.Client.Administration.UI.Tabs.ObjectsTab +{ + [GenerateTypedNameReferences] + public sealed partial class ObjectsTabHeader : Control + { + public event Action
? OnHeaderClicked; + + private const string ArrowUp = "↑"; + private const string ArrowDown = "↓"; + + public ObjectsTabHeader() + { + RobustXamlLoader.Load(this); + + ObjectNameLabel.OnKeyBindDown += ObjectNameClicked; + EntityIDLabel.OnKeyBindDown += EntityIDClicked; + } + + public Label GetHeader(Header header) + { + return header switch + { + Header.ObjectName => ObjectNameLabel, + Header.EntityID => EntityIDLabel, + _ => throw new ArgumentOutOfRangeException(nameof(header), header, null) + }; + } + + public void ResetHeaderText() + { + ObjectNameLabel.Text = Loc.GetString("object-tab-object-name"); + EntityIDLabel.Text = Loc.GetString("object-tab-entity-id"); + } + + public void UpdateHeaderSymbols(Header headerClicked, bool ascending) + { + ResetHeaderText(); + var arrow = ascending ? ArrowUp : ArrowDown; + GetHeader(headerClicked).Text += $" {arrow}"; + } + + private void HeaderClicked(GUIBoundKeyEventArgs args, Header header) + { + if (args.Function != EngineKeyFunctions.UIClick) + { + return; + } + + OnHeaderClicked?.Invoke(header); + args.Handle(); + } + + private void ObjectNameClicked(GUIBoundKeyEventArgs args) + { + HeaderClicked(args, Header.ObjectName); + } + + private void EntityIDClicked(GUIBoundKeyEventArgs args) + { + HeaderClicked(args, Header.EntityID); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing) + { + ObjectNameLabel.OnKeyBindDown -= ObjectNameClicked; + EntityIDLabel.OnKeyBindDown -= EntityIDClicked; + } + } + + public enum Header + { + ObjectName, + EntityID + } + } +} diff --git a/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTab.xaml.cs b/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTab.xaml.cs index a8bfaddecf4..826945e7cc0 100644 --- a/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTab.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTab.xaml.cs @@ -53,6 +53,7 @@ public PlayerTab() SearchList.ItemKeyBindDown += (args, data) => OnEntryKeyBindDown?.Invoke(args, data); RefreshPlayerList(_adminSystem.PlayerList); + } #region Antag Overlay @@ -110,7 +111,9 @@ private void RefreshPlayerList(IReadOnlyList players) _players = players; PlayerCount.Text = $"Players: {_playerMan.PlayerCount}"; - var sortedPlayers = new List(players); + var filteredPlayers = players.Where(info => _showDisconnected || info.Connected).ToList(); + + var sortedPlayers = new List(filteredPlayers); sortedPlayers.Sort(Compare); UpdateHeaderSymbols(); diff --git a/Content.Client/UserInterface/Systems/Admin/AdminUIController.cs b/Content.Client/UserInterface/Systems/Admin/AdminUIController.cs index a7397aff38d..3d8235591ad 100644 --- a/Content.Client/UserInterface/Systems/Admin/AdminUIController.cs +++ b/Content.Client/UserInterface/Systems/Admin/AdminUIController.cs @@ -198,9 +198,12 @@ private void PlayerTabEntryKeyBindDown(GUIBoundKeyEventArgs args, ListData? data args.Handle(); } - private void ObjectsTabEntryKeyBindDown(ObjectsTabEntry entry, GUIBoundKeyEventArgs args) + private void ObjectsTabEntryKeyBindDown(GUIBoundKeyEventArgs args, ListData? data) { - var uid = entry.AssocEntity; + if (data is not ObjectsListData { Info: var info }) + return; + + var uid = info.Entity; var function = args.Function; if (function == EngineKeyFunctions.UIClick) diff --git a/Resources/Locale/en-US/administration/ui/tabs/object-tab.ftl b/Resources/Locale/en-US/administration/ui/tabs/object-tab.ftl new file mode 100644 index 00000000000..0288efcaa44 --- /dev/null +++ b/Resources/Locale/en-US/administration/ui/tabs/object-tab.ftl @@ -0,0 +1,2 @@ +object-tab-entity-id = Entity ID +object-tab-object-name = Object name From 180f1e8005f9e7aff120ee42db1c4bc3ba027541 Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 6 Jun 2024 06:42:18 +0000 Subject: [PATCH 22/55] Automatic changelog update --- Resources/Changelog/Admin.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Resources/Changelog/Admin.yml b/Resources/Changelog/Admin.yml index 2964e8c11b1..16d4e1fe297 100644 --- a/Resources/Changelog/Admin.yml +++ b/Resources/Changelog/Admin.yml @@ -281,5 +281,14 @@ Entries: id: 34 time: '2024-06-01T08:14:44.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/28451 +- author: Repo + changes: + - message: Sorting and search to objects tab. + type: Add + - message: Disconnected people showing player tab + type: Fix + id: 35 + time: '2024-06-06T06:41:11.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/28609 Name: Admin Order: 1 From dec1c281a88845192080b47743803c10afc5adce Mon Sep 17 00:00:00 2001 From: Plykiya <58439124+Plykiya@users.noreply.github.com> Date: Thu, 6 Jun 2024 00:01:45 -0700 Subject: [PATCH 23/55] Internals are kept on as long as any breathing tool is on (#28595) --- .../AtmosphereSystem.BreathTool.cs | 14 ++++----- .../Atmos/EntitySystems/GasTankSystem.cs | 2 +- .../Body/Components/InternalsComponent.cs | 2 +- .../Body/Systems/InternalsSystem.cs | 30 ++++++++----------- Content.Server/Body/Systems/LungSystem.cs | 2 +- 5 files changed, 23 insertions(+), 27 deletions(-) diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.BreathTool.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.BreathTool.cs index 741a9341e79..327804f39a4 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.BreathTool.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.BreathTool.cs @@ -10,21 +10,21 @@ private void InitializeBreathTool() SubscribeLocalEvent(OnBreathToolShutdown); } - private void OnBreathToolShutdown(EntityUid uid, BreathToolComponent component, ComponentShutdown args) + private void OnBreathToolShutdown(Entity entity, ref ComponentShutdown args) { - DisconnectInternals(component); + DisconnectInternals(entity); } - public void DisconnectInternals(BreathToolComponent component) + public void DisconnectInternals(Entity entity) { - var old = component.ConnectedInternalsEntity; - component.ConnectedInternalsEntity = null; + var old = entity.Comp.ConnectedInternalsEntity; + entity.Comp.ConnectedInternalsEntity = null; if (TryComp(old, out var internalsComponent)) { - _internals.DisconnectBreathTool((old.Value, internalsComponent)); + _internals.DisconnectBreathTool((old.Value, internalsComponent), entity.Owner); } - component.IsFunctional = false; + entity.Comp.IsFunctional = false; } } diff --git a/Content.Server/Atmos/EntitySystems/GasTankSystem.cs b/Content.Server/Atmos/EntitySystems/GasTankSystem.cs index 07594820fcc..baad739804b 100644 --- a/Content.Server/Atmos/EntitySystems/GasTankSystem.cs +++ b/Content.Server/Atmos/EntitySystems/GasTankSystem.cs @@ -220,7 +220,7 @@ public GasMixture RemoveAirVolume(Entity gasTank, float volume public bool CanConnectToInternals(GasTankComponent component) { var internals = GetInternalsComponent(component, component.User); - return internals != null && internals.BreathToolEntity != null && !component.IsValveOpen; + return internals != null && internals.BreathTools.Count != 0 && !component.IsValveOpen; } public void ConnectToInternals(Entity ent) diff --git a/Content.Server/Body/Components/InternalsComponent.cs b/Content.Server/Body/Components/InternalsComponent.cs index 098f1789218..ef908f96553 100644 --- a/Content.Server/Body/Components/InternalsComponent.cs +++ b/Content.Server/Body/Components/InternalsComponent.cs @@ -13,7 +13,7 @@ public sealed partial class InternalsComponent : Component public EntityUid? GasTankEntity; [ViewVariables] - public EntityUid? BreathToolEntity; + public HashSet BreathTools { get; set; } = new(); /// /// Toggle Internals delay when the target is not you. diff --git a/Content.Server/Body/Systems/InternalsSystem.cs b/Content.Server/Body/Systems/InternalsSystem.cs index b79e083bd46..0e568b77cb4 100644 --- a/Content.Server/Body/Systems/InternalsSystem.cs +++ b/Content.Server/Body/Systems/InternalsSystem.cs @@ -44,7 +44,7 @@ public override void Initialize() private void OnStartingGear(EntityUid uid, InternalsComponent component, ref StartingGearEquippedEvent args) { - if (component.BreathToolEntity == null) + if (component.BreathTools.Count == 0) return; if (component.GasTankEntity != null) @@ -111,7 +111,7 @@ public void ToggleInternals( } // If they're not on then check if we have a mask to use - if (internals.BreathToolEntity is null) + if (internals.BreathTools.Count == 0) { _popupSystem.PopupEntity(Loc.GetString("internals-no-breath-tool"), uid, user); return; @@ -178,28 +178,24 @@ private void OnInhaleLocation(Entity ent, ref InhaleLocation _alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent)); } } - public void DisconnectBreathTool(Entity ent) + public void DisconnectBreathTool(Entity ent, EntityUid toolEntity) { - var old = ent.Comp.BreathToolEntity; - ent.Comp.BreathToolEntity = null; + ent.Comp.BreathTools.Remove(toolEntity); - if (TryComp(old, out BreathToolComponent? breathTool)) - { - _atmos.DisconnectInternals(breathTool); + if (TryComp(toolEntity, out BreathToolComponent? breathTool)) + _atmos.DisconnectInternals((toolEntity, breathTool)); + + if (ent.Comp.BreathTools.Count == 0) DisconnectTank(ent); - } _alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent)); } public void ConnectBreathTool(Entity ent, EntityUid toolEntity) { - if (TryComp(ent.Comp.BreathToolEntity, out BreathToolComponent? tool)) - { - _atmos.DisconnectInternals(tool); - } + if (!ent.Comp.BreathTools.Add(toolEntity)) + return; - ent.Comp.BreathToolEntity = toolEntity; _alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent)); } @@ -217,7 +213,7 @@ public void DisconnectTank(InternalsComponent? component) public bool TryConnectTank(Entity ent, EntityUid tankEntity) { - if (ent.Comp.BreathToolEntity is null) + if (ent.Comp.BreathTools.Count == 0) return false; if (TryComp(ent.Comp.GasTankEntity, out GasTankComponent? tank)) @@ -236,14 +232,14 @@ public bool AreInternalsWorking(EntityUid uid, InternalsComponent? component = n public bool AreInternalsWorking(InternalsComponent component) { - return TryComp(component.BreathToolEntity, out BreathToolComponent? breathTool) + return TryComp(component.BreathTools.FirstOrNull(), out BreathToolComponent? breathTool) && breathTool.IsFunctional && HasComp(component.GasTankEntity); } private short GetSeverity(InternalsComponent component) { - if (component.BreathToolEntity is null || !AreInternalsWorking(component)) + if (component.BreathTools.Count == 0 || !AreInternalsWorking(component)) return 2; // If pressure in the tank is below low pressure threshold, flash warning on internals UI diff --git a/Content.Server/Body/Systems/LungSystem.cs b/Content.Server/Body/Systems/LungSystem.cs index 7e58c24f7e4..a3c185d5cc6 100644 --- a/Content.Server/Body/Systems/LungSystem.cs +++ b/Content.Server/Body/Systems/LungSystem.cs @@ -59,7 +59,7 @@ private void OnMaskToggled(Entity ent, ref ItemMaskToggledE { if (args.IsToggled || args.IsEquip) { - _atmos.DisconnectInternals(ent.Comp); + _atmos.DisconnectInternals(ent); } else { From 8b40d1887c36bab329406732243e2aaa0152ec7c Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 6 Jun 2024 07:02:51 +0000 Subject: [PATCH 24/55] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 25f48ec5f79..43fd543c170 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Terraspark4941 - changes: - - message: The TEG page in the guidebook has been updated with proper information! - type: Tweak - id: 6188 - time: '2024-03-18T21:33:07.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/26170 - author: Plykiya changes: - message: You can now craft ducky slippers. @@ -3849,3 +3842,11 @@ id: 6687 time: '2024-06-05T22:08:41.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/28591 +- author: Plykiya + changes: + - message: Internals are no longer toggled off if you take your helmet off but still + have a gas mask on and vice versa. + type: Tweak + id: 6688 + time: '2024-06-06T07:01:45.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/28595 From 1333b48747ae62c7b3ecb809b897201a24fe4441 Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Thu, 6 Jun 2024 03:11:26 -0400 Subject: [PATCH 25/55] Convert rules to use guidebook parsing (#28647) --- Content.Client/Entry/EntryPoint.cs | 4 - .../Guidebook/DocumentParsingManager.cs | 19 + Content.Client/Info/InfoSystem.cs | 25 - Content.Client/Info/RulesAndInfoWindow.cs | 14 +- Content.Client/Info/RulesControl.xaml | 24 +- Content.Client/Info/RulesControl.xaml.cs | 45 +- Content.Client/Info/RulesManager.cs | 105 - Content.Client/Info/RulesPopup.xaml | 10 +- Content.Client/Info/RulesPopup.xaml.cs | 2 - Content.Client/IoC/ClientContentIoC.cs | 2 - .../Systems/Info/InfoUIController.cs | 101 +- ...0606065731_RemoveLastReadRules.Designer.cs | 1909 +++++++++++++++++ .../20240606065731_RemoveLastReadRules.cs | 29 + .../PostgresServerDbContextModelSnapshot.cs | 4 - ...0606065717_RemoveLastReadRules.Designer.cs | 1834 ++++++++++++++++ .../20240606065717_RemoveLastReadRules.cs | 29 + .../SqliteServerDbContextModelSnapshot.cs | 4 - Content.Server.Database/Model.cs | 2 - .../Administration/Managers/AdminManager.cs | 2 + Content.Server/Database/ServerDbBase.cs | 24 - Content.Server/Database/ServerDbManager.cs | 19 - Content.Server/Entry/EntryPoint.cs | 2 - Content.Server/Info/InfoSystem.cs | 35 - Content.Server/Info/RulesManager.cs | 48 - Content.Server/Info/ShowRulesCommand.cs | 14 +- Content.Server/IoC/ServerContentIoC.cs | 2 - Content.Shared/CCVar/CCVars.cs | 18 +- Content.Shared/Info/RulesMessages.cs | 25 + Content.Shared/Info/SharedInfo.cs | 28 - Content.Shared/Info/SharedRulesManager.cs | 60 - .../ConfigPresets/WizardsDen/salamander.toml | 3 +- .../ConfigPresets/WizardsDen/wizardsDen.toml | 3 + Resources/Locale/en-US/info/rules.ftl | 3 + 33 files changed, 4035 insertions(+), 413 deletions(-) delete mode 100644 Content.Client/Info/InfoSystem.cs delete mode 100644 Content.Client/Info/RulesManager.cs create mode 100644 Content.Server.Database/Migrations/Postgres/20240606065731_RemoveLastReadRules.Designer.cs create mode 100644 Content.Server.Database/Migrations/Postgres/20240606065731_RemoveLastReadRules.cs create mode 100644 Content.Server.Database/Migrations/Sqlite/20240606065717_RemoveLastReadRules.Designer.cs create mode 100644 Content.Server.Database/Migrations/Sqlite/20240606065717_RemoveLastReadRules.cs delete mode 100644 Content.Server/Info/InfoSystem.cs delete mode 100644 Content.Server/Info/RulesManager.cs create mode 100644 Content.Shared/Info/RulesMessages.cs delete mode 100644 Content.Shared/Info/SharedInfo.cs delete mode 100644 Content.Shared/Info/SharedRulesManager.cs diff --git a/Content.Client/Entry/EntryPoint.cs b/Content.Client/Entry/EntryPoint.cs index 51210a8a93d..dd7e781f0bb 100644 --- a/Content.Client/Entry/EntryPoint.cs +++ b/Content.Client/Entry/EntryPoint.cs @@ -2,11 +2,9 @@ using Content.Client.Changelog; using Content.Client.Chat.Managers; using Content.Client.Eui; -using Content.Client.Flash; using Content.Client.Fullscreen; using Content.Client.GhostKick; using Content.Client.Guidebook; -using Content.Client.Info; using Content.Client.Input; using Content.Client.IoC; using Content.Client.Launcher; @@ -52,7 +50,6 @@ public sealed class EntryPoint : GameClient [Dependency] private readonly IScreenshotHook _screenshotHook = default!; [Dependency] private readonly FullscreenHook _fullscreenHook = default!; [Dependency] private readonly ChangelogManager _changelogManager = default!; - [Dependency] private readonly RulesManager _rulesManager = default!; [Dependency] private readonly ViewportManager _viewportManager = default!; [Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!; [Dependency] private readonly IInputManager _inputManager = default!; @@ -125,7 +122,6 @@ public override void Init() _screenshotHook.Initialize(); _fullscreenHook.Initialize(); _changelogManager.Initialize(); - _rulesManager.Initialize(); _viewportManager.Initialize(); _ghostKick.Initialize(); _extendedDisconnectInformation.Initialize(); diff --git a/Content.Client/Guidebook/DocumentParsingManager.cs b/Content.Client/Guidebook/DocumentParsingManager.cs index b81866a6260..9c9e569eb41 100644 --- a/Content.Client/Guidebook/DocumentParsingManager.cs +++ b/Content.Client/Guidebook/DocumentParsingManager.cs @@ -2,6 +2,8 @@ using Content.Client.Guidebook.Richtext; using Pidgin; using Robust.Client.UserInterface; +using Robust.Shared.ContentPack; +using Robust.Shared.Prototypes; using Robust.Shared.Reflection; using Robust.Shared.Sandboxing; using static Pidgin.Parser; @@ -13,7 +15,9 @@ namespace Content.Client.Guidebook; /// public sealed partial class DocumentParsingManager { + [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly IReflectionManager _reflectionManager = default!; + [Dependency] private readonly IResourceManager _resourceManager = default!; [Dependency] private readonly ISandboxHelper _sandboxHelper = default!; private readonly Dictionary> _tagControlParsers = new(); @@ -37,6 +41,21 @@ public void Initialize() ControlParser = SkipWhitespaces.Then(_controlParser.Many()); } + public bool TryAddMarkup(Control control, ProtoId entryId, bool log = true) + { + if (!_prototype.TryIndex(entryId, out var entry)) + return false; + + using var file = _resourceManager.ContentFileReadText(entry.Text); + return TryAddMarkup(control, file.ReadToEnd(), log); + } + + public bool TryAddMarkup(Control control, GuideEntry entry, bool log = true) + { + using var file = _resourceManager.ContentFileReadText(entry.Text); + return TryAddMarkup(control, file.ReadToEnd(), log); + } + public bool TryAddMarkup(Control control, string text, bool log = true) { try diff --git a/Content.Client/Info/InfoSystem.cs b/Content.Client/Info/InfoSystem.cs deleted file mode 100644 index b6979949818..00000000000 --- a/Content.Client/Info/InfoSystem.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Content.Shared.Info; -using Robust.Shared.Log; - -namespace Content.Client.Info; - -public sealed class InfoSystem : EntitySystem -{ - public RulesMessage Rules = new RulesMessage("Server Rules", "The server did not send any rules."); - [Dependency] private readonly RulesManager _rules = default!; - - public override void Initialize() - { - base.Initialize(); - SubscribeNetworkEvent(OnRulesReceived); - Log.Debug("Requested server info."); - RaiseNetworkEvent(new RequestRulesMessage()); - } - - private void OnRulesReceived(RulesMessage message, EntitySessionEventArgs eventArgs) - { - Log.Debug("Received server rules."); - Rules = message; - _rules.UpdateRules(); - } -} diff --git a/Content.Client/Info/RulesAndInfoWindow.cs b/Content.Client/Info/RulesAndInfoWindow.cs index 7a763a1d6f4..b9131dcb3c0 100644 --- a/Content.Client/Info/RulesAndInfoWindow.cs +++ b/Content.Client/Info/RulesAndInfoWindow.cs @@ -1,10 +1,8 @@ using System.Numerics; using Content.Client.UserInterface.Systems.EscapeMenu; -using Robust.Client.ResourceManagement; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; -using Robust.Shared.Configuration; using Robust.Shared.ContentPack; namespace Content.Client.Info @@ -12,7 +10,6 @@ namespace Content.Client.Info public sealed class RulesAndInfoWindow : DefaultWindow { [Dependency] private readonly IResourceManager _resourceManager = default!; - [Dependency] private readonly RulesManager _rules = default!; public RulesAndInfoWindow() { @@ -22,8 +19,14 @@ public RulesAndInfoWindow() var rootContainer = new TabContainer(); - var rulesList = new Info(); - var tutorialList = new Info(); + var rulesList = new RulesControl + { + Margin = new Thickness(10) + }; + var tutorialList = new Info + { + Margin = new Thickness(10) + }; rootContainer.AddChild(rulesList); rootContainer.AddChild(tutorialList); @@ -31,7 +34,6 @@ public RulesAndInfoWindow() TabContainer.SetTabTitle(rulesList, Loc.GetString("ui-info-tab-rules")); TabContainer.SetTabTitle(tutorialList, Loc.GetString("ui-info-tab-tutorial")); - AddSection(rulesList, _rules.RulesSection()); PopulateTutorial(tutorialList); Contents.AddChild(rootContainer); diff --git a/Content.Client/Info/RulesControl.xaml b/Content.Client/Info/RulesControl.xaml index 3b247646884..04fa7191234 100644 --- a/Content.Client/Info/RulesControl.xaml +++ b/Content.Client/Info/RulesControl.xaml @@ -1,6 +1,18 @@ - + + + + + + +