From 190b1f61f22b54a10bab5a0aa7922c40445446eb Mon Sep 17 00:00:00 2001 From: TsjipTsjip <19798667+TsjipTsjip@users.noreply.github.com> Date: Sun, 22 Oct 2023 20:00:36 +0200 Subject: [PATCH 001/102] Kettle updates (#21164) --- Resources/Maps/kettle.yml | 10474 ++++++++++++++++++------------------ 1 file changed, 5267 insertions(+), 5207 deletions(-) diff --git a/Resources/Maps/kettle.yml b/Resources/Maps/kettle.yml index c8194474d0..92356aef08 100644 --- a/Resources/Maps/kettle.yml +++ b/Resources/Maps/kettle.yml @@ -539,439 +539,1353 @@ entities: color: '#EFB34196' id: Arrows decals: - 1233: -56,47 - 1234: -56,38 + 1223: -56,47 + 1224: -56,38 - node: angle: 1.5707963267948966 rad color: '#52B4E996' id: ArrowsGreyscale decals: - 4928: -41,-43 + 4915: -41,-43 - node: angle: 4.71238898038469 rad color: '#52B4E996' id: ArrowsGreyscale decals: - 4927: -42,-41 + 4914: -42,-41 - node: color: '#52B4E996' id: Bot decals: - 3903: 26,61 + 3890: 26,61 - node: color: '#EFB34196' id: Bot decals: - 465: 35,0 - 466: 36,0 - 467: 37,0 - 468: 35,-1 - 469: 36,-1 - 470: 37,-1 - 1080: 35,11 - 1081: 35,10 - 1082: 36,11 - 1083: 36,10 - 1084: 37,11 - 1085: 37,10 - 1086: 38,11 - 1087: 38,10 - 1088: 39,11 - 1089: 39,10 - 3902: 28,61 + 455: 35,0 + 456: 36,0 + 457: 37,0 + 458: 35,-1 + 459: 36,-1 + 460: 37,-1 + 1070: 35,11 + 1071: 35,10 + 1072: 36,11 + 1073: 36,10 + 1074: 37,11 + 1075: 37,10 + 1076: 38,11 + 1077: 38,10 + 1078: 39,11 + 1079: 39,10 + 3889: 28,61 - node: color: '#FFA500FF' id: Bot decals: - 4842: 52,-19 - 4843: 52,-20 - 4844: 52,-21 - 4845: 48,-21 - 4846: 48,-20 - 4847: 48,-19 + 4829: 52,-19 + 4830: 52,-20 + 4831: 52,-21 + 4832: 48,-21 + 4833: 48,-20 + 4834: 48,-19 - node: color: '#FFFFFFFF' id: Bot decals: - 4654: 20,76 - 4655: 21,76 - 4656: 21,75 - 4657: 20,75 - 4658: 20,73 - 4659: 21,73 - 4660: 21,72 - 4661: 20,72 + 4641: 20,76 + 4642: 21,76 + 4643: 21,75 + 4644: 20,75 + 4645: 20,73 + 4646: 21,73 + 4647: 21,72 + 4648: 20,72 - node: color: '#52B4E996' id: BotGreyscale decals: - 1669: -15,39 - 1675: 29,10 - 1682: 42,-6 - 4746: -27,18 - 4747: -27,17 - 4748: -25,18 - 4749: -25,17 + 1658: -15,39 + 1664: 29,10 + 1671: 42,-6 + 4733: -27,18 + 4734: -27,17 + 4735: -25,18 + 4736: -25,17 - node: color: '#EFB34196' id: BotGreyscale decals: - 1634: -55,-33 - 1635: -49,-29 - 1636: -44,-25 - 1637: -24,-33 - 1638: -3,-23 - 1639: 6,-27 - 1640: 17,-23 - 1641: 19,-58 - 1642: 32,-32 - 1643: 17,-6 - 1644: 40,5 - 1645: 43,-12 - 1646: 62,-3 - 1647: 22,7 - 1648: 35,30 - 1649: 43,12 - 1650: 25,25 - 1651: 30,40 - 1652: 14,48 - 1653: 26,68 - 1654: 3,38 - 1655: -20,24 - 1656: -20,21 - 1657: -27,-17 - 1658: -31,1 - 1659: 5,-2 - 1660: -3,-6 - 1661: -26,-2 - 1662: -43,-3 - 1663: -32,-23 - 1667: -23,52 - 1668: -15,41 - 1670: -61,43 - 1671: -39,31 - 1672: -18,-44 - 1673: -4,-63 - 1674: 26,-10 + 1623: -55,-33 + 1624: -49,-29 + 1625: -44,-25 + 1626: -24,-33 + 1627: -3,-23 + 1628: 6,-27 + 1629: 17,-23 + 1630: 19,-58 + 1631: 32,-32 + 1632: 17,-6 + 1633: 40,5 + 1634: 43,-12 + 1635: 62,-3 + 1636: 22,7 + 1637: 35,30 + 1638: 43,12 + 1639: 25,25 + 1640: 30,40 + 1641: 14,48 + 1642: 26,68 + 1643: 3,38 + 1644: -20,24 + 1645: -20,21 + 1646: -27,-17 + 1647: -31,1 + 1648: 5,-2 + 1649: -3,-6 + 1650: -26,-2 + 1651: -43,-3 + 1652: -32,-23 + 1656: -23,52 + 1657: -15,41 + 1659: -61,43 + 1660: -39,31 + 1661: -18,-44 + 1662: -4,-63 + 1663: 26,-10 - node: color: '#EFB34196' id: BotLeft decals: - 1044: 37,27 - 1045: 37,28 + 1034: 37,27 + 1035: 37,28 - node: angle: 3.141592653589793 rad color: '#334E6DC8' id: BotLeftGreyscale decals: - 500: -9,-1 - 501: -8,-1 - 502: -7,-1 + 490: -9,-1 + 491: -8,-1 + 492: -7,-1 - node: zIndex: 1 color: '#FFFFFFFF' id: BotLeftGreyscale decals: - 4904: -44,-44 - 4905: -40,-44 - 4906: -42,-40 + 4891: -44,-44 + 4892: -40,-44 + 4893: -42,-40 - node: color: '#EFB34196' id: BotRight decals: - 701: 24,17 - 702: 24,16 - 703: 24,15 - 704: 25,17 - 705: 25,16 - 706: 25,15 - 707: 26,17 - 708: 26,16 - 709: 26,15 - 710: 27,17 - 711: 27,16 - 712: 27,15 - 713: 28,17 - 714: 28,16 - 715: 28,15 - 716: 29,17 - 717: 29,16 - 718: 29,15 - 1090: 35,15 - 1091: 35,16 - 1092: 36,15 - 1093: 37,15 - 1094: 37,16 - 1095: 38,15 - 1096: 38,16 - 1097: 39,15 - 1098: 39,16 - 1550: 36,16 + 691: 24,17 + 692: 24,16 + 693: 24,15 + 694: 25,17 + 695: 25,16 + 696: 25,15 + 697: 26,17 + 698: 26,16 + 699: 26,15 + 700: 27,17 + 701: 27,16 + 702: 27,15 + 703: 28,17 + 704: 28,16 + 705: 28,15 + 706: 29,17 + 707: 29,16 + 708: 29,15 + 1080: 35,15 + 1081: 35,16 + 1082: 36,15 + 1083: 37,15 + 1084: 37,16 + 1085: 38,15 + 1086: 38,16 + 1087: 39,15 + 1088: 39,16 + 1540: 36,16 - node: color: '#EFB34196' id: Box decals: - 1042: 37,26 + 1032: 37,26 - node: angle: 3.141592653589793 rad color: '#EFB34196' id: Box decals: - 493: 23,1 - 494: 23,0 - 495: 22,1 - 496: 22,0 + 483: 23,1 + 484: 23,0 + 485: 22,1 + 486: 22,0 - node: color: '#EFB34196' id: BoxGreyscale decals: - 1114: 42,23 - 1115: 43,23 - 1116: 42,21 - 1117: 43,21 - 1120: 42,19 - 1121: 43,19 + 1104: 42,23 + 1105: 43,23 + 1106: 42,21 + 1107: 43,21 + 1110: 42,19 + 1111: 43,19 - node: color: '#FFFFFFFF' id: BrickTileDarkCornerNe decals: - 3537: 14,-10 - 3679: 29,-15 - 3823: 2,61 - 3916: 46,36 - 3946: 38,21 - 3960: 37,20 - 4239: -59,54 - 4279: -5,-61 - 4386: 29,56 - 4614: 16,75 - 4615: 19,74 - 4696: -31,18 + 3524: 14,-10 + 3666: 29,-15 + 3810: 2,61 + 3903: 46,36 + 3933: 38,21 + 3947: 37,20 + 4226: -59,54 + 4266: -5,-61 + 4373: 29,56 + 4601: 16,75 + 4602: 19,74 + 4683: -31,18 - node: color: '#FFFFFFFF' id: BrickTileDarkCornerNw decals: - 3523: 0,-10 - 3680: 28,-15 - 3821: -2,61 - 3918: 43,36 - 3943: 35,21 - 3963: 36,20 - 4241: -61,54 - 4281: -7,-61 - 4319: 23,79 - 4383: 26,56 - 4612: 11,74 - 4613: 14,75 - 4693: -33,18 + 3510: 0,-10 + 3667: 28,-15 + 3808: -2,61 + 3905: 43,36 + 3930: 35,21 + 3950: 36,20 + 4228: -61,54 + 4268: -7,-61 + 4306: 23,79 + 4370: 26,56 + 4599: 11,74 + 4600: 14,75 + 4680: -33,18 - node: color: '#FFFFFFFF' id: BrickTileDarkCornerSe decals: - 3539: 14,-12 - 3557: 9,-14 - 3670: 29,-24 - 3789: -17,25 - 3822: 2,57 - 3917: 46,33 - 3949: 38,18 - 3961: 37,19 - 4280: -5,-62 - 4329: 31,73 - 4529: -30,-29 - 4616: 19,72 - 4694: -31,17 + 3526: 14,-12 + 3544: 9,-14 + 3657: 29,-24 + 3776: -17,25 + 3809: 2,57 + 3904: 46,33 + 3936: 38,18 + 3948: 37,19 + 4267: -5,-62 + 4316: 31,73 + 4516: -30,-29 + 4603: 19,72 + 4681: -31,17 - node: color: '#FFFFFFFF' id: BrickTileDarkCornerSw decals: - 3521: 0,-12 - 3553: 5,-14 - 3573: 22,-30 - 3669: 28,-24 - 3820: -2,57 - 3919: 43,33 - 3940: 35,18 - 3962: 36,19 - 4282: -7,-62 - 4313: 23,73 - 4617: 11,72 - 4695: -33,17 + 3508: 0,-12 + 3540: 5,-14 + 3560: 22,-30 + 3656: 28,-24 + 3807: -2,57 + 3906: 43,33 + 3927: 35,18 + 3949: 36,19 + 4269: -7,-62 + 4300: 23,73 + 4604: 11,72 + 4682: -33,17 - node: color: '#FFFFFFFF' id: BrickTileDarkInnerNe decals: - 3697: 28,-24 - 4631: 16,74 + 3684: 28,-24 + 4618: 16,74 - node: color: '#FFFFFFFF' id: BrickTileDarkInnerNw decals: - 3696: 29,-24 - 4632: 14,74 - 4753: -24,16 + 3683: 29,-24 + 4619: 14,74 + 4740: -24,16 - node: color: '#FFFFFFFF' id: BrickTileDarkInnerSe decals: - 3550: 9,-12 - 3715: 28,-15 - 3795: -17,26 + 3537: 9,-12 + 3702: 28,-15 + 3782: -17,26 - node: color: '#FFFFFFFF' id: BrickTileDarkInnerSw decals: - 3549: 5,-12 - 3714: 29,-15 - 4752: -24,19 + 3536: 5,-12 + 3701: 29,-15 + 4739: -24,19 - node: color: '#FFFFFFFF' id: BrickTileDarkLineE decals: - 3538: 14,-11 - 3551: 9,-13 - 3671: 29,-23 - 3672: 29,-22 - 3673: 29,-21 - 3674: 29,-20 - 3675: 29,-19 - 3676: 29,-18 - 3677: 29,-17 - 3678: 29,-16 - 3698: 28,-23 - 3699: 28,-22 - 3700: 28,-21 - 3701: 28,-20 - 3702: 28,-19 - 3703: 28,-18 - 3704: 28,-17 - 3705: 28,-16 - 3827: 2,58 - 3828: 2,59 - 3829: 2,60 - 3910: 46,34 - 3911: 46,35 - 3947: 38,20 - 3948: 38,19 - 3956: 35,19 - 3957: 35,20 - 4195: 41,0 - 4196: 41,-1 - 4238: -59,53 - 4330: 31,74 - 4331: 31,75 - 4387: 29,55 - 4388: 29,54 - 4389: 29,53 - 4390: 29,52 - 4530: -30,-28 - 4531: -30,-27 - 4532: -30,-26 - 4533: -30,-25 - 4618: 19,73 - 4703: -32,15 - 4704: -32,16 - 4705: -32,19 - 4706: -32,20 - 4716: -34,17 - 4717: -34,18 - 4718: -34,19 - 4719: -34,16 - 4728: -28,18 - 4729: -28,17 - 4736: -29,17 - 4737: -29,18 + 3525: 14,-11 + 3538: 9,-13 + 3658: 29,-23 + 3659: 29,-22 + 3660: 29,-21 + 3661: 29,-20 + 3662: 29,-19 + 3663: 29,-18 + 3664: 29,-17 + 3665: 29,-16 + 3685: 28,-23 + 3686: 28,-22 + 3687: 28,-21 + 3688: 28,-20 + 3689: 28,-19 + 3690: 28,-18 + 3691: 28,-17 + 3692: 28,-16 + 3814: 2,58 + 3815: 2,59 + 3816: 2,60 + 3897: 46,34 + 3898: 46,35 + 3934: 38,20 + 3935: 38,19 + 3943: 35,19 + 3944: 35,20 + 4182: 41,0 + 4183: 41,-1 + 4225: -59,53 + 4317: 31,74 + 4318: 31,75 + 4374: 29,55 + 4375: 29,54 + 4376: 29,53 + 4377: 29,52 + 4517: -30,-28 + 4518: -30,-27 + 4519: -30,-26 + 4520: -30,-25 + 4605: 19,73 + 4690: -32,15 + 4691: -32,16 + 4692: -32,19 + 4693: -32,20 + 4703: -34,17 + 4704: -34,18 + 4705: -34,19 + 4706: -34,16 + 4715: -28,18 + 4716: -28,17 + 4723: -29,17 + 4724: -29,18 - node: color: '#FFFFFFFF' id: BrickTileDarkLineN decals: - 3524: 1,-10 - 3525: 2,-10 - 3526: 3,-10 - 3527: 4,-10 - 3528: 5,-10 - 3529: 6,-10 - 3530: 7,-10 - 3531: 8,-10 - 3532: 9,-10 - 3533: 10,-10 - 3534: 11,-10 - 3535: 12,-10 - 3536: 13,-10 - 3830: 1,61 - 3831: 0,61 - 3832: -1,61 - 3914: 44,36 - 3915: 45,36 - 3944: 36,21 - 3945: 37,21 - 3958: 36,18 - 3959: 37,18 - 4240: -60,54 - 4278: -6,-61 - 4320: 24,79 - 4360: 26,79 - 4361: 27,79 - 4384: 27,56 - 4385: 28,56 - 4627: 12,74 - 4628: 13,74 - 4629: 15,75 - 4630: 17,74 - 4662: 18,74 - 4698: -32,18 + 3511: 1,-10 + 3512: 2,-10 + 3513: 3,-10 + 3514: 4,-10 + 3515: 5,-10 + 3516: 6,-10 + 3517: 7,-10 + 3518: 8,-10 + 3519: 9,-10 + 3520: 10,-10 + 3521: 11,-10 + 3522: 12,-10 + 3523: 13,-10 + 3817: 1,61 + 3818: 0,61 + 3819: -1,61 + 3901: 44,36 + 3902: 45,36 + 3931: 36,21 + 3932: 37,21 + 3945: 36,18 + 3946: 37,18 + 4227: -60,54 + 4265: -6,-61 + 4307: 24,79 + 4347: 26,79 + 4348: 27,79 + 4371: 27,56 + 4372: 28,56 + 4614: 12,74 + 4615: 13,74 + 4616: 15,75 + 4617: 17,74 + 4649: 18,74 + 4685: -32,18 - node: color: '#FFFFFFFF' id: BrickTileDarkLineS decals: - 3541: 13,-12 - 3542: 12,-12 - 3543: 11,-12 - 3544: 10,-12 - 3545: 1,-12 - 3546: 2,-12 - 3547: 3,-12 - 3548: 4,-12 - 3554: 6,-14 - 3555: 7,-14 - 3556: 8,-14 - 3576: 23,-30 - 3790: -18,25 - 3791: -19,25 - 3792: -20,25 - 3793: -21,25 - 3796: -16,26 - 3797: -15,26 - 3798: -14,26 - 3799: -13,26 - 3824: -1,57 - 3825: 0,57 - 3826: 1,57 - 3912: 44,33 - 3913: 45,33 - 3950: 37,18 - 3951: 36,18 - 3952: 36,21 - 3953: 37,21 - 4277: -6,-62 - 4321: 24,73 - 4322: 25,73 - 4323: 26,73 - 4324: 27,73 - 4325: 28,73 - 4326: 29,73 - 4327: 30,73 - 4328: 31,73 - 4358: 26,78 - 4359: 27,78 - 4521: -38,-29 - 4522: -37,-29 - 4523: -36,-29 - 4524: -35,-29 - 4525: -34,-29 - 4526: -33,-29 - 4527: -32,-29 - 4528: -31,-29 + 3528: 13,-12 + 3529: 12,-12 + 3530: 11,-12 + 3531: 10,-12 + 3532: 1,-12 + 3533: 2,-12 + 3534: 3,-12 + 3535: 4,-12 + 3541: 6,-14 + 3542: 7,-14 + 3543: 8,-14 + 3563: 23,-30 + 3777: -18,25 + 3778: -19,25 + 3779: -20,25 + 3780: -21,25 + 3783: -16,26 + 3784: -15,26 + 3785: -14,26 + 3786: -13,26 + 3811: -1,57 + 3812: 0,57 + 3813: 1,57 + 3899: 44,33 + 3900: 45,33 + 3937: 37,18 + 3938: 36,18 + 3939: 36,21 + 3940: 37,21 + 4264: -6,-62 + 4308: 24,73 + 4309: 25,73 + 4310: 26,73 + 4311: 27,73 + 4312: 28,73 + 4313: 29,73 + 4314: 30,73 + 4315: 31,73 + 4345: 26,78 + 4346: 27,78 + 4508: -38,-29 + 4509: -37,-29 + 4510: -36,-29 + 4511: -35,-29 + 4512: -34,-29 + 4513: -33,-29 + 4514: -32,-29 + 4515: -31,-29 + 4607: 12,72 + 4608: 13,72 + 4609: 14,72 + 4610: 15,72 + 4611: 16,72 + 4612: 17,72 + 4613: 18,72 + 4684: -32,17 + - node: + color: '#FFFFFFFF' + id: BrickTileDarkLineW + decals: + 3509: 0,-11 + 3539: 5,-13 + 3561: 22,-29 + 3562: 22,-28 + 3648: 28,-23 + 3649: 28,-22 + 3650: 28,-21 + 3651: 28,-20 + 3652: 28,-19 + 3653: 28,-18 + 3654: 28,-17 + 3655: 28,-16 + 3693: 29,-16 + 3694: 29,-17 + 3695: 29,-18 + 3696: 29,-19 + 3697: 29,-20 + 3698: 29,-21 + 3699: 29,-22 + 3700: 29,-23 + 3820: -2,60 + 3821: -2,59 + 3822: -2,58 + 3895: 43,34 + 3896: 43,35 + 3928: 35,19 + 3929: 35,20 + 3941: 38,20 + 3942: 38,19 + 4184: 39,0 + 4185: 39,-1 + 4229: -61,53 + 4301: 23,74 + 4302: 23,75 + 4303: 23,76 + 4304: 23,77 + 4305: 23,78 + 4368: 26,52 + 4369: 26,53 + 4398: 26,54 + 4399: 26,55 + 4606: 11,73 + 4686: -32,20 + 4687: -32,19 + 4688: -32,16 + 4689: -32,15 + 4719: -28,18 + 4720: -28,17 + 4737: -24,17 + 4738: -24,18 + - node: + color: '#FFFFFFFF' + id: BrickTileSteelBox + decals: + 3977: -56,-32 + - node: + color: '#FFFFFFFF' + id: BrickTileSteelCornerNe + decals: + 3570: 31,-31 + 3756: 28,-8 + 3790: -24,38 + 3891: 28,70 + 3915: 40,30 + 4081: 62,-5 + 4097: 58,-14 + 4195: -58,44 + 4271: -27,4 + 4290: 81,9 + - node: + color: '#FFFFFFFF' + id: BrickTileSteelCornerNw + decals: + 3564: 25,-31 + 3757: 23,-8 + 3788: -27,38 + 3894: 27,70 + 3916: 39,30 + 4066: 49,-5 + 4194: -62,44 + 4270: -30,4 + 4295: 77,9 + - node: + color: '#FFFFFFFF' + id: BrickTileSteelCornerSe + decals: + 3575: 31,-36 + 3759: 28,-9 + 3789: -24,37 + 3892: 28,69 + 3914: 40,26 + 4082: 62,-6 + 4103: 58,-20 + 4196: -58,37 + 4272: -27,1 + 4289: 81,7 + - node: + color: '#FFFFFFFF' + id: BrickTileSteelCornerSw + decals: + 3581: 25,-36 + 3758: 23,-9 + 3787: -27,37 + 3893: 27,69 + 3913: 39,26 + 4067: 49,-6 + 4107: 54,-20 + 4193: -62,37 + 4273: -30,1 + 4296: 77,7 + - node: + color: '#FFFFFFFF' + id: BrickTileSteelEndN + decals: + 3978: -56,-26 + - node: + color: '#FFFFFFFF' + id: BrickTileSteelEndS + decals: + 3979: -56,-28 + - node: + color: '#FFFFFFFF' + id: BrickTileSteelInnerNe + decals: + 3604: 25,-36 + 4095: 56,-14 + 4215: -59,51 + 4221: -63,46 + - node: + color: '#FFFFFFFF' + id: BrickTileSteelInnerNw + decals: + 3605: 31,-36 + 4214: -57,51 + 4220: -61,46 + - node: + color: '#FFFFFFFF' + id: BrickTileSteelInnerSe + decals: + 3607: 25,-31 + 4088: 56,-6 + 4385: 26,56 + - node: + color: '#FFFFFFFF' + id: BrickTileSteelInnerSw + decals: + 3606: 31,-31 + 4118: 54,-6 + 4119: 54,-6 + 4382: 29,56 + - node: + color: '#FFFFFFFF' + id: BrickTileSteelLineE + decals: + 3571: 31,-32 + 3572: 31,-33 + 3573: 31,-34 + 3574: 31,-35 + 3586: 25,-34 + 3587: 25,-33 + 3588: 25,-32 + 3589: 25,-35 + 3910: 40,29 + 3911: 40,28 + 3912: 40,27 + 3980: -56,-27 + 4087: 56,-7 + 4089: 56,-9 + 4090: 56,-8 + 4091: 56,-10 + 4092: 56,-11 + 4093: 56,-12 + 4094: 56,-13 + 4098: 58,-15 + 4099: 58,-16 + 4100: 58,-17 + 4101: 58,-18 + 4102: 58,-19 + 4197: -58,38 + 4198: -58,39 + 4199: -58,40 + 4200: -58,41 + 4201: -58,39 + 4202: -58,42 + 4203: -58,43 + 4276: -27,2 + 4277: -27,3 + 4291: 81,8 + 4386: 26,53 + 4387: 26,52 + 4400: 26,55 + 4401: 26,54 + - node: + color: '#FFFFFFFF' + id: BrickTileSteelLineN + decals: + 3565: 26,-31 + 3566: 27,-31 + 3567: 28,-31 + 3568: 29,-31 + 3569: 30,-31 + 3599: 30,-36 + 3600: 29,-36 + 3601: 28,-36 + 3602: 27,-36 + 3603: 26,-36 + 3738: 16,-3 + 3739: 15,-3 + 3740: 14,-3 + 3741: 13,-3 + 3742: 12,-3 + 3743: 11,-3 + 3744: 10,-3 + 3745: 9,-3 + 3746: 8,-3 + 3747: 7,-3 + 3748: 6,-3 + 3749: 5,-3 + 3750: 4,-3 + 3751: 3,-3 + 3752: 2,-3 + 3753: 1,-3 + 3754: 0,-3 + 3755: -1,-3 + 3764: 24,-8 + 3765: 25,-8 + 3766: 26,-8 + 3767: 27,-8 + 3768: -20,28 + 3769: -19,28 + 3770: -18,28 + 3771: -15,28 + 3772: -14,28 + 3773: -13,28 + 3791: -26,38 + 3792: -25,38 + 4068: 50,-5 + 4069: 51,-5 + 4070: 52,-5 + 4071: 53,-5 + 4072: 54,-5 + 4073: 55,-5 + 4074: 56,-5 + 4075: 57,-5 + 4076: 58,-5 + 4077: 58,-5 + 4078: 59,-5 + 4079: 60,-5 + 4080: 61,-5 + 4096: 57,-14 + 4204: -61,44 + 4205: -60,44 + 4206: -59,44 + 4213: -58,51 + 4219: -62,46 + 4247: 15,-24 + 4248: 14,-24 + 4249: 13,-24 + 4250: 12,-24 + 4251: 11,-24 + 4252: 10,-24 + 4253: 9,-24 + 4254: 8,-24 + 4255: 7,-24 + 4256: 6,-24 + 4257: 5,-24 + 4258: 4,-24 + 4259: 3,-24 + 4260: 2,-24 + 4261: 1,-24 + 4262: 0,-24 + 4263: -1,-24 + 4280: -29,4 + 4281: -28,4 + 4292: 80,9 + 4293: 79,9 + 4294: 78,9 + - node: + color: '#FFFFFFFF' + id: BrickTileSteelLineS + decals: + 3576: 30,-36 + 3577: 29,-36 + 3578: 28,-36 + 3579: 27,-36 + 3580: 26,-36 + 3594: 30,-31 + 3595: 29,-31 + 3596: 28,-31 + 3597: 27,-31 + 3598: 26,-31 + 3720: -1,-5 + 3721: 0,-5 + 3722: 1,-5 + 3723: 16,-5 + 3724: 14,-5 + 3725: 15,-5 + 3726: 13,-5 + 3727: 12,-5 + 3728: 11,-5 + 3729: 10,-5 + 3730: 9,-5 + 3731: 8,-5 + 3732: 7,-5 + 3733: 6,-5 + 3734: 5,-5 + 3735: 4,-5 + 3736: 3,-5 + 3737: 2,-5 + 3760: 24,-9 + 3761: 25,-9 + 3762: 26,-9 + 3763: 27,-9 + 3793: -26,37 + 3794: -25,37 + 4083: 61,-6 + 4084: 60,-6 + 4085: 58,-6 + 4086: 57,-6 + 4104: 57,-20 + 4105: 56,-20 + 4106: 55,-20 + 4120: 53,-6 + 4121: 52,-6 + 4122: 50,-6 + 4123: 51,-6 + 4145: 59,-6 + 4190: -61,37 + 4191: -60,37 + 4192: -59,37 + 4230: -1,-26 + 4231: 0,-26 + 4232: 1,-26 + 4233: 2,-26 + 4234: 3,-26 + 4235: 4,-26 + 4236: 5,-26 + 4237: 6,-26 + 4238: 7,-26 + 4239: 8,-26 + 4240: 9,-26 + 4241: 10,-26 + 4242: 11,-26 + 4243: 12,-26 + 4244: 13,-26 + 4245: 14,-26 + 4246: 15,-26 + 4278: -29,1 + 4279: -28,1 + 4286: 78,7 + 4287: 79,7 + 4288: 80,7 + 4383: 28,56 + 4384: 27,56 + - node: + color: '#FFFFFFFF' + id: BrickTileSteelLineW + decals: + 3582: 25,-35 + 3583: 25,-34 + 3584: 25,-33 + 3585: 25,-32 + 3590: 31,-35 + 3591: 31,-34 + 3592: 31,-33 + 3593: 31,-32 + 3774: -21,27 + 3775: -21,26 + 3781: -21,25 + 3907: 39,27 + 3908: 39,28 + 3909: 39,29 + 3981: -56,-27 + 4108: 54,-19 + 4109: 54,-18 + 4110: 54,-14 + 4111: 54,-13 + 4112: 54,-12 + 4113: 54,-11 + 4114: 54,-10 + 4115: 54,-9 + 4116: 54,-8 + 4117: 54,-7 + 4207: -62,43 + 4208: -62,42 + 4209: -62,41 + 4210: -62,40 + 4211: -62,39 + 4212: -62,38 + 4274: -30,2 + 4275: -30,3 + 4297: 77,8 + 4378: 29,52 + 4379: 29,53 + 4380: 29,54 + 4381: 29,55 + - node: + color: '#334E6DC8' + id: BrickTileWhiteCornerNe + decals: + 3473: 5,-12 + - node: + color: '#52B4E996' + id: BrickTileWhiteCornerNe + decals: + 4916: -30,-35 + - node: + color: '#A4610696' + id: BrickTileWhiteCornerNe + decals: + 3926: 40,30 + 3960: 38,21 + - node: + color: '#D381C996' + id: BrickTileWhiteCornerNe + decals: + 4393: 29,56 + 4636: 16,75 + 4637: 19,74 + - node: + color: '#DE3A3A96' + id: BrickTileWhiteCornerNe + decals: + 4142: 62,-5 + 4160: 58,-14 + - node: + color: '#FFFFFFFF' + id: BrickTileWhiteCornerNe + decals: + 3860: 29,61 + 4045: -17,-29 + 4431: -29,-12 + - node: + color: '#334E6DC8' + id: BrickTileWhiteCornerNw + decals: + 3500: 9,-12 + - node: + color: '#52B4E996' + id: BrickTileWhiteCornerNw + decals: + 4917: -40,-35 + - node: + color: '#A4610696' + id: BrickTileWhiteCornerNw + decals: + 3921: 39,30 + 3957: 35,21 + - node: + color: '#D381C996' + id: BrickTileWhiteCornerNw + decals: + 4321: 23,79 + 4390: 26,56 + 4634: 14,75 + 4635: 11,74 + - node: + color: '#DE3A3A96' + id: BrickTileWhiteCornerNw + decals: + 4129: 49,-5 + - node: + color: '#FFFFFFFF' + id: BrickTileWhiteCornerNw + decals: + 3858: 22,61 + 4043: -20,-29 + 4439: -37,-12 + - node: + color: '#52B4E996' + id: BrickTileWhiteCornerSe + decals: + 4918: -30,-40 + 4919: -37,-41 + - node: + color: '#A4610696' + id: BrickTileWhiteCornerSe + decals: + 3922: 40,26 + 3951: 38,18 + - node: + color: '#D381C996' + id: BrickTileWhiteCornerSe + decals: + 4319: 31,73 + 4633: 19,72 + - node: + color: '#DE3A3A96' + id: BrickTileWhiteCornerSe + decals: + 4143: 62,-6 + 4166: 58,-20 + - node: + color: '#F9801DFF' + id: BrickTileWhiteCornerSe + decals: + 4529: -30,-29 + - node: + color: '#FFFFFFFF' + id: BrickTileWhiteCornerSe + decals: + 3857: 29,58 + 4044: -17,-31 + 4429: -29,-14 + - node: + color: '#52B4E996' + id: BrickTileWhiteCornerSw + decals: + 4920: -40,-41 + - node: + color: '#A4610696' + id: BrickTileWhiteCornerSw + decals: + 3920: 39,26 + 3954: 35,18 + - node: + color: '#D381C996' + id: BrickTileWhiteCornerSw + decals: + 4320: 23,73 + 4638: 11,72 + - node: + color: '#DE3A3A96' + id: BrickTileWhiteCornerSw + decals: + 4128: 49,-6 + 4170: 54,-20 + - node: + color: '#FFFFFFFF' + id: BrickTileWhiteCornerSw + decals: + 3859: 22,58 + 4042: -20,-31 + 4440: -37,-13 + - node: + color: '#FFFFFFFF' + id: BrickTileWhiteEndN + decals: + 4053: 7,-39 + - node: + color: '#FFFFFFFF' + id: BrickTileWhiteEndS + decals: + 4052: 7,-42 + - node: + color: '#334E6DC8' + id: BrickTileWhiteInnerNe + decals: + 3478: 0,-12 + 3506: 5,-14 + 3556: -10,-3 + 4217: -59,51 + - node: + color: '#52B4E996' + id: BrickTileWhiteInnerNe + decals: + 4911: -52,-37 + - node: + color: '#D381C996' + id: BrickTileWhiteInnerNe + decals: + 4639: 16,74 + - node: + color: '#DE3A3A96' + id: BrickTileWhiteInnerNe + decals: + 4158: 56,-14 + 4222: -63,46 + - node: + color: '#334E6DC8' + id: BrickTileWhiteInnerNw + decals: + 3502: 9,-14 + 3527: 14,-12 + 3557: -4,-3 + 4218: -57,51 + 4744: -24,16 + - node: + color: '#52B4E996' + id: BrickTileWhiteInnerNw + decals: + 4910: -48,-37 + - node: + color: '#D381C996' + id: BrickTileWhiteInnerNw + decals: + 4640: 14,74 + - node: + color: '#DE3A3A96' + id: BrickTileWhiteInnerNw + decals: + 4223: -61,46 + - node: + color: '#334E6DC8' + id: BrickTileWhiteInnerSe + decals: + 3480: 0,-10 + - node: + color: '#52B4E996' + id: BrickTileWhiteInnerSe + decals: + 4903: -52,-35 + 4921: -37,-40 + - node: + color: '#DE3A3A96' + id: BrickTileWhiteInnerSe + decals: + 4150: 56,-6 + - node: + color: '#334E6DC8' + id: BrickTileWhiteInnerSw + decals: + 3494: 14,-10 + 4743: -24,19 + - node: + color: '#52B4E996' + id: BrickTileWhiteInnerSw + decals: + 4902: -48,-35 + - node: + color: '#DE3A3A96' + id: BrickTileWhiteInnerSw + decals: + 4181: 54,-6 + - node: + color: '#FFFFFFFF' + id: BrickTileWhiteInnerSw + decals: + 4443: -34,-13 + - node: + color: '#334E6DC8' + id: BrickTileWhiteLineE + decals: + 3479: 0,-11 + 3507: 5,-13 + - node: + color: '#52B4E996' + id: BrickTileWhiteLineE + decals: + 4900: -52,-36 + 4939: -30,-36 + 4940: -30,-37 + 4941: -30,-38 + 4942: -30,-39 + - node: + color: '#9FED5896' + id: BrickTileWhiteLineE + decals: + 4696: -32,16 + - node: + color: '#A4610696' + id: BrickTileWhiteLineE + decals: + 3923: 40,27 + 3924: 40,28 + 3925: 40,29 + 3961: 38,20 + 3962: 38,19 + - node: + color: '#D381C996' + id: BrickTileWhiteLineE + decals: + 4335: 31,74 + 4336: 31,75 + 4394: 29,55 + 4395: 29,54 + 4396: 29,53 + 4397: 29,52 + 4631: 19,73 + - node: + color: '#D4D4D405' + id: BrickTileWhiteLineE + decals: + 4725: -29,18 + 4726: -29,17 + - node: + color: '#D4D4D40C' + id: BrickTileWhiteLineE + decals: + 4713: -28,18 + 4714: -28,17 + - node: + color: '#D4D4D426' + id: BrickTileWhiteLineE + decals: + 4717: -28,18 + 4718: -28,17 + - node: + color: '#D4D4D428' + id: BrickTileWhiteLineE + decals: + 4701: -32,19 + - node: + color: '#DE3A3A96' + id: BrickTileWhiteLineE + decals: + 4151: 56,-7 + 4152: 56,-8 + 4153: 56,-9 + 4154: 56,-10 + 4155: 56,-11 + 4156: 56,-12 + 4157: 56,-13 + 4161: 58,-15 + 4162: 58,-16 + 4163: 58,-17 + 4164: 58,-18 + 4165: 58,-19 + 4188: 41,0 + 4189: 41,-1 + 4698: -32,15 + - node: + color: '#EFB34196' + id: BrickTileWhiteLineE + decals: + 4697: -32,20 + - node: + color: '#F9801DFF' + id: BrickTileWhiteLineE + decals: + 4530: -30,-28 + 4531: -30,-27 + 4532: -30,-26 + 4533: -30,-25 + - node: + color: '#FFFFFFFF' + id: BrickTileWhiteLineE + decals: + 3875: 29,59 + 3876: 29,60 + 4051: -17,-30 + 4054: 7,-40 + 4055: 7,-41 + 4430: -29,-13 + 4702: -45,15 + - node: + color: '#334E6DC8' + id: BrickTileWhiteLineN + decals: + 3474: 4,-12 + 3475: 3,-12 + 3476: 2,-12 + 3477: 1,-12 + 3496: 13,-12 + 3497: 12,-12 + 3498: 11,-12 + 3499: 10,-12 + 3503: 8,-14 + 3504: 7,-14 + 3505: 6,-14 + 3553: -8,-3 + 3554: -7,-3 + 3555: -6,-3 + 4216: -58,51 + - node: + color: '#52B4E996' + id: BrickTileWhiteLineN + decals: + 4907: -51,-37 + 4908: -50,-37 + 4909: -49,-37 + 4930: -39,-35 + 4931: -38,-35 + 4932: -37,-35 + 4933: -36,-35 + 4934: -35,-35 + 4935: -34,-35 + 4936: -33,-35 + 4937: -32,-35 + 4938: -31,-35 + - node: + color: '#A4610696' + id: BrickTileWhiteLineN + decals: + 3958: 36,21 + 3959: 37,21 + - node: + color: '#D381C996' + id: BrickTileWhiteLineN + decals: + 4322: 24,79 + 4351: 26,79 + 4352: 27,79 + 4391: 27,56 + 4392: 28,56 + 4627: 12,74 + 4628: 13,74 + 4629: 15,75 + 4630: 17,74 + 4650: 18,74 + - node: + color: '#DE3A3A96' + id: BrickTileWhiteLineN + decals: + 4130: 50,-5 + 4131: 51,-5 + 4132: 52,-5 + 4133: 53,-5 + 4134: 54,-5 + 4135: 55,-5 + 4136: 56,-5 + 4137: 57,-5 + 4138: 58,-5 + 4139: 59,-5 + 4140: 60,-5 + 4141: 61,-5 + 4159: 57,-14 + 4224: -62,46 + - node: + color: '#FFFFFFFF' + id: BrickTileWhiteLineN + decals: + 3861: 28,61 + 3862: 27,61 + 3863: 26,61 + 3864: 25,61 + 3865: 24,61 + 3866: 23,61 + 4006: -53,-31 + 4007: -52,-31 + 4008: -51,-31 + 4009: -50,-31 + 4010: -49,-31 + 4011: -48,-31 + 4012: -47,-31 + 4013: -46,-31 + 4014: -45,-31 + 4015: -44,-31 + 4016: -43,-31 + 4017: -42,-31 + 4018: -41,-31 + 4019: -40,-31 + 4020: -39,-31 + 4021: -38,-31 + 4022: -37,-31 + 4023: -36,-31 + 4024: -35,-31 + 4025: -34,-31 + 4026: -33,-31 + 4027: -32,-31 + 4028: -31,-31 + 4029: -30,-31 + 4046: -19,-29 + 4047: -18,-29 + 4432: -30,-12 + 4433: -31,-12 + 4434: -32,-12 + 4435: -33,-12 + 4436: -34,-12 + 4437: -35,-12 + 4438: -36,-12 + - node: + color: '#334E6DC8' + id: BrickTileWhiteLineS + decals: + 3481: 1,-10 + 3482: 2,-10 + 3483: 3,-10 + 3484: 4,-10 + 3485: 5,-10 + 3486: 6,-10 + 3487: 7,-10 + 3488: 8,-10 + 3489: 9,-10 + 3490: 10,-10 + 3491: 11,-10 + 3492: 12,-10 + 3493: 13,-10 + - node: + color: '#52B4E996' + id: BrickTileWhiteLineS + decals: + 4897: -51,-35 + 4898: -50,-35 + 4899: -49,-35 + 4922: -39,-41 + 4923: -38,-41 + 4924: -36,-40 + 4925: -35,-40 + 4926: -34,-40 + 4927: -33,-40 + 4928: -32,-40 + 4929: -31,-40 + - node: + color: '#A4610696' + id: BrickTileWhiteLineS + decals: + 3952: 37,18 + 3953: 36,18 + - node: + color: '#D381C996' + id: BrickTileWhiteLineS + decals: + 4328: 24,73 + 4329: 25,73 + 4330: 26,73 + 4331: 27,73 + 4332: 28,73 + 4333: 29,73 + 4334: 30,73 + 4349: 26,78 + 4350: 27,78 4620: 12,72 4621: 13,72 4622: 14,72 @@ -979,3359 +1893,2445 @@ entities: 4624: 16,72 4625: 17,72 4626: 18,72 - 4697: -32,17 + - node: + color: '#DE3A3A96' + id: BrickTileWhiteLineS + decals: + 4124: 51,-6 + 4125: 50,-6 + 4126: 52,-6 + 4127: 53,-6 + 4144: 61,-6 + 4146: 60,-6 + 4147: 59,-6 + 4148: 58,-6 + 4149: 57,-6 + 4167: 57,-20 + 4168: 56,-20 + 4169: 55,-20 + - node: + color: '#F9801DFF' + id: BrickTileWhiteLineS + decals: + 4521: -32,-29 + 4522: -33,-29 + 4523: -34,-29 + 4524: -35,-29 + 4525: -36,-29 + 4526: -37,-29 + 4527: -38,-29 + 4528: -31,-29 - node: color: '#FFFFFFFF' - id: BrickTileDarkLineW + id: BrickTileWhiteLineS decals: - 3522: 0,-11 - 3552: 5,-13 - 3574: 22,-29 - 3575: 22,-28 - 3661: 28,-23 - 3662: 28,-22 - 3663: 28,-21 - 3664: 28,-20 - 3665: 28,-19 - 3666: 28,-18 - 3667: 28,-17 - 3668: 28,-16 - 3706: 29,-16 - 3707: 29,-17 - 3708: 29,-18 - 3709: 29,-19 - 3710: 29,-20 - 3711: 29,-21 - 3712: 29,-22 - 3713: 29,-23 - 3833: -2,60 - 3834: -2,59 - 3835: -2,58 - 3908: 43,34 - 3909: 43,35 - 3941: 35,19 - 3942: 35,20 - 3954: 38,20 - 3955: 38,19 - 4197: 39,0 - 4198: 39,-1 - 4242: -61,53 - 4314: 23,74 - 4315: 23,75 - 4316: 23,76 - 4317: 23,77 - 4318: 23,78 - 4381: 26,52 - 4382: 26,53 - 4411: 26,54 - 4412: 26,55 - 4619: 11,73 - 4699: -32,20 + 3867: 23,58 + 3868: 24,58 + 3869: 25,58 + 3870: 26,58 + 3871: 27,58 + 3872: 28,58 + 3982: -30,-33 + 3983: -31,-33 + 3984: -32,-33 + 3985: -33,-33 + 3986: -34,-33 + 3987: -35,-33 + 3988: -36,-33 + 3989: -37,-33 + 3990: -38,-33 + 3991: -39,-33 + 3992: -40,-33 + 3993: -41,-33 + 3994: -42,-33 + 3995: -43,-33 + 3996: -44,-33 + 3997: -45,-33 + 3998: -46,-33 + 3999: -47,-33 + 4000: -48,-33 + 4001: -49,-33 + 4002: -50,-33 + 4003: -51,-33 + 4004: -52,-33 + 4005: -53,-33 + 4048: -19,-31 + 4049: -18,-31 + 4424: -34,-14 + 4425: -33,-14 + 4426: -32,-14 + 4427: -31,-14 + 4428: -30,-14 + 4441: -36,-13 + 4442: -35,-13 + - node: + color: '#334E6DC8' + id: BrickTileWhiteLineW + decals: + 3495: 14,-11 + 3501: 9,-13 + 4694: -32,20 + 4741: -24,17 + 4742: -24,18 + - node: + color: '#52B4E996' + id: BrickTileWhiteLineW + decals: + 4695: -32,15 + 4901: -48,-36 + 4943: -40,-40 + 4944: -40,-39 + 4945: -40,-38 + 4946: -40,-37 + 4947: -40,-36 + - node: + color: '#A4610696' + id: BrickTileWhiteLineW + decals: + 3917: 39,28 + 3918: 39,29 + 3919: 39,27 + 3955: 35,19 + 3956: 35,20 4700: -32,19 - 4701: -32,16 - 4702: -32,15 - 4732: -28,18 - 4733: -28,17 - 4750: -24,17 - 4751: -24,18 - - node: - color: '#FFFFFFFF' - id: BrickTileSteelBox - decals: - 3990: -56,-32 - - node: - color: '#FFFFFFFF' - id: BrickTileSteelCornerNe - decals: - 3583: 31,-31 - 3769: 28,-8 - 3803: -24,38 - 3904: 28,70 - 3928: 40,30 - 4094: 62,-5 - 4110: 58,-14 - 4208: -58,44 - 4284: -27,4 - 4303: 81,9 - - node: - color: '#FFFFFFFF' - id: BrickTileSteelCornerNw - decals: - 3577: 25,-31 - 3770: 23,-8 - 3801: -27,38 - 3907: 27,70 - 3929: 39,30 - 4079: 49,-5 - 4207: -62,44 - 4283: -30,4 - 4308: 77,9 - - node: - color: '#FFFFFFFF' - id: BrickTileSteelCornerSe - decals: - 3588: 31,-36 - 3772: 28,-9 - 3802: -24,37 - 3905: 28,69 - 3927: 40,26 - 4095: 62,-6 - 4116: 58,-20 - 4209: -58,37 - 4285: -27,1 - 4302: 81,7 - - node: - color: '#FFFFFFFF' - id: BrickTileSteelCornerSw - decals: - 3594: 25,-36 - 3771: 23,-9 - 3800: -27,37 - 3906: 27,69 - 3926: 39,26 - 4080: 49,-6 - 4120: 54,-20 - 4206: -62,37 - 4286: -30,1 - 4309: 77,7 - - node: - color: '#FFFFFFFF' - id: BrickTileSteelEndN - decals: - 3991: -56,-26 - - node: - color: '#FFFFFFFF' - id: BrickTileSteelEndS - decals: - 3992: -56,-28 - - node: - color: '#FFFFFFFF' - id: BrickTileSteelInnerNe - decals: - 3617: 25,-36 - 4108: 56,-14 - 4228: -59,51 - 4234: -63,46 - - node: - color: '#FFFFFFFF' - id: BrickTileSteelInnerNw - decals: - 3618: 31,-36 - 4227: -57,51 - 4233: -61,46 - - node: - color: '#FFFFFFFF' - id: BrickTileSteelInnerSe - decals: - 3620: 25,-31 - 4101: 56,-6 - 4398: 26,56 - - node: - color: '#FFFFFFFF' - id: BrickTileSteelInnerSw - decals: - 3619: 31,-31 - 4131: 54,-6 - 4132: 54,-6 - 4395: 29,56 - - node: - color: '#FFFFFFFF' - id: BrickTileSteelLineE - decals: - 3584: 31,-32 - 3585: 31,-33 - 3586: 31,-34 - 3587: 31,-35 - 3599: 25,-34 - 3600: 25,-33 - 3601: 25,-32 - 3602: 25,-35 - 3923: 40,29 - 3924: 40,28 - 3925: 40,27 - 3993: -56,-27 - 4100: 56,-7 - 4102: 56,-9 - 4103: 56,-8 - 4104: 56,-10 - 4105: 56,-11 - 4106: 56,-12 - 4107: 56,-13 - 4111: 58,-15 - 4112: 58,-16 - 4113: 58,-17 - 4114: 58,-18 - 4115: 58,-19 - 4210: -58,38 - 4211: -58,39 - 4212: -58,40 - 4213: -58,41 - 4214: -58,39 - 4215: -58,42 - 4216: -58,43 - 4289: -27,2 - 4290: -27,3 - 4304: 81,8 - 4399: 26,53 - 4400: 26,52 - 4413: 26,55 - 4414: 26,54 - - node: - color: '#FFFFFFFF' - id: BrickTileSteelLineN - decals: - 3578: 26,-31 - 3579: 27,-31 - 3580: 28,-31 - 3581: 29,-31 - 3582: 30,-31 - 3612: 30,-36 - 3613: 29,-36 - 3614: 28,-36 - 3615: 27,-36 - 3616: 26,-36 - 3751: 16,-3 - 3752: 15,-3 - 3753: 14,-3 - 3754: 13,-3 - 3755: 12,-3 - 3756: 11,-3 - 3757: 10,-3 - 3758: 9,-3 - 3759: 8,-3 - 3760: 7,-3 - 3761: 6,-3 - 3762: 5,-3 - 3763: 4,-3 - 3764: 3,-3 - 3765: 2,-3 - 3766: 1,-3 - 3767: 0,-3 - 3768: -1,-3 - 3777: 24,-8 - 3778: 25,-8 - 3779: 26,-8 - 3780: 27,-8 - 3781: -20,28 - 3782: -19,28 - 3783: -18,28 - 3784: -15,28 - 3785: -14,28 - 3786: -13,28 - 3804: -26,38 - 3805: -25,38 - 4081: 50,-5 - 4082: 51,-5 - 4083: 52,-5 - 4084: 53,-5 - 4085: 54,-5 - 4086: 55,-5 - 4087: 56,-5 - 4088: 57,-5 - 4089: 58,-5 - 4090: 58,-5 - 4091: 59,-5 - 4092: 60,-5 - 4093: 61,-5 - 4109: 57,-14 - 4217: -61,44 - 4218: -60,44 - 4219: -59,44 - 4226: -58,51 - 4232: -62,46 - 4260: 15,-24 - 4261: 14,-24 - 4262: 13,-24 - 4263: 12,-24 - 4264: 11,-24 - 4265: 10,-24 - 4266: 9,-24 - 4267: 8,-24 - 4268: 7,-24 - 4269: 6,-24 - 4270: 5,-24 - 4271: 4,-24 - 4272: 3,-24 - 4273: 2,-24 - 4274: 1,-24 - 4275: 0,-24 - 4276: -1,-24 - 4293: -29,4 - 4294: -28,4 - 4305: 80,9 - 4306: 79,9 - 4307: 78,9 - - node: - color: '#FFFFFFFF' - id: BrickTileSteelLineS - decals: - 3589: 30,-36 - 3590: 29,-36 - 3591: 28,-36 - 3592: 27,-36 - 3593: 26,-36 - 3607: 30,-31 - 3608: 29,-31 - 3609: 28,-31 - 3610: 27,-31 - 3611: 26,-31 - 3733: -1,-5 - 3734: 0,-5 - 3735: 1,-5 - 3736: 16,-5 - 3737: 14,-5 - 3738: 15,-5 - 3739: 13,-5 - 3740: 12,-5 - 3741: 11,-5 - 3742: 10,-5 - 3743: 9,-5 - 3744: 8,-5 - 3745: 7,-5 - 3746: 6,-5 - 3747: 5,-5 - 3748: 4,-5 - 3749: 3,-5 - 3750: 2,-5 - 3773: 24,-9 - 3774: 25,-9 - 3775: 26,-9 - 3776: 27,-9 - 3806: -26,37 - 3807: -25,37 - 4096: 61,-6 - 4097: 60,-6 - 4098: 58,-6 - 4099: 57,-6 - 4117: 57,-20 - 4118: 56,-20 - 4119: 55,-20 - 4133: 53,-6 - 4134: 52,-6 - 4135: 50,-6 - 4136: 51,-6 - 4158: 59,-6 - 4203: -61,37 - 4204: -60,37 - 4205: -59,37 - 4243: -1,-26 - 4244: 0,-26 - 4245: 1,-26 - 4246: 2,-26 - 4247: 3,-26 - 4248: 4,-26 - 4249: 5,-26 - 4250: 6,-26 - 4251: 7,-26 - 4252: 8,-26 - 4253: 9,-26 - 4254: 10,-26 - 4255: 11,-26 - 4256: 12,-26 - 4257: 13,-26 - 4258: 14,-26 - 4259: 15,-26 - 4291: -29,1 - 4292: -28,1 - 4299: 78,7 - 4300: 79,7 - 4301: 80,7 - 4396: 28,56 - 4397: 27,56 - - node: - color: '#FFFFFFFF' - id: BrickTileSteelLineW - decals: - 3595: 25,-35 - 3596: 25,-34 - 3597: 25,-33 - 3598: 25,-32 - 3603: 31,-35 - 3604: 31,-34 - 3605: 31,-33 - 3606: 31,-32 - 3787: -21,27 - 3788: -21,26 - 3794: -21,25 - 3920: 39,27 - 3921: 39,28 - 3922: 39,29 - 3994: -56,-27 - 4121: 54,-19 - 4122: 54,-18 - 4123: 54,-14 - 4124: 54,-13 - 4125: 54,-12 - 4126: 54,-11 - 4127: 54,-10 - 4128: 54,-9 - 4129: 54,-8 - 4130: 54,-7 - 4220: -62,43 - 4221: -62,42 - 4222: -62,41 - 4223: -62,40 - 4224: -62,39 - 4225: -62,38 - 4287: -30,2 - 4288: -30,3 - 4310: 77,8 - 4391: 29,52 - 4392: 29,53 - 4393: 29,54 - 4394: 29,55 - - node: - color: '#334E6DC8' - id: BrickTileWhiteCornerNe - decals: - 3486: 5,-12 - - node: - color: '#52B4E996' - id: BrickTileWhiteCornerNe - decals: - 4929: -30,-35 - - node: - color: '#A4610696' - id: BrickTileWhiteCornerNe - decals: - 3939: 40,30 - 3973: 38,21 - - node: - color: '#D381C996' - id: BrickTileWhiteCornerNe - decals: - 4406: 29,56 - 4649: 16,75 - 4650: 19,74 - - node: - color: '#DE3A3A96' - id: BrickTileWhiteCornerNe - decals: - 4155: 62,-5 - 4173: 58,-14 - - node: - color: '#FFFFFFFF' - id: BrickTileWhiteCornerNe - decals: - 3873: 29,61 - 4058: -17,-29 - 4444: -29,-12 - - node: - color: '#334E6DC8' - id: BrickTileWhiteCornerNw - decals: - 3513: 9,-12 - - node: - color: '#52B4E996' - id: BrickTileWhiteCornerNw - decals: - 4930: -40,-35 - - node: - color: '#A4610696' - id: BrickTileWhiteCornerNw - decals: - 3934: 39,30 - 3970: 35,21 - - node: - color: '#D381C996' - id: BrickTileWhiteCornerNw - decals: - 4334: 23,79 - 4403: 26,56 - 4647: 14,75 - 4648: 11,74 - - node: - color: '#DE3A3A96' - id: BrickTileWhiteCornerNw - decals: - 4142: 49,-5 - - node: - color: '#FFFFFFFF' - id: BrickTileWhiteCornerNw - decals: - 3871: 22,61 - 4056: -20,-29 - 4452: -37,-12 - - node: - color: '#52B4E996' - id: BrickTileWhiteCornerSe - decals: - 4931: -30,-40 - 4932: -37,-41 - - node: - color: '#A4610696' - id: BrickTileWhiteCornerSe - decals: - 3935: 40,26 - 3964: 38,18 - - node: - color: '#D381C996' - id: BrickTileWhiteCornerSe - decals: - 4332: 31,73 - 4646: 19,72 - - node: - color: '#DE3A3A96' - id: BrickTileWhiteCornerSe - decals: - 4156: 62,-6 - 4179: 58,-20 - - node: - color: '#F9801DFF' - id: BrickTileWhiteCornerSe - decals: - 4542: -30,-29 - - node: - color: '#FFFFFFFF' - id: BrickTileWhiteCornerSe - decals: - 3870: 29,58 - 4057: -17,-31 - 4442: -29,-14 - - node: - color: '#52B4E996' - id: BrickTileWhiteCornerSw - decals: - 4933: -40,-41 - - node: - color: '#A4610696' - id: BrickTileWhiteCornerSw - decals: - 3933: 39,26 - 3967: 35,18 - - node: - color: '#D381C996' - id: BrickTileWhiteCornerSw - decals: - 4333: 23,73 - 4651: 11,72 - - node: - color: '#DE3A3A96' - id: BrickTileWhiteCornerSw - decals: - 4141: 49,-6 - 4183: 54,-20 - - node: - color: '#FFFFFFFF' - id: BrickTileWhiteCornerSw - decals: - 3872: 22,58 - 4055: -20,-31 - 4453: -37,-13 - - node: - color: '#FFFFFFFF' - id: BrickTileWhiteEndN - decals: - 4066: 7,-39 - - node: - color: '#FFFFFFFF' - id: BrickTileWhiteEndS - decals: - 4065: 7,-42 - - node: - color: '#334E6DC8' - id: BrickTileWhiteInnerNe - decals: - 3491: 0,-12 - 3519: 5,-14 - 3569: -10,-3 - 4230: -59,51 - - node: - color: '#52B4E996' - id: BrickTileWhiteInnerNe - decals: - 4924: -52,-37 - - node: - color: '#D381C996' - id: BrickTileWhiteInnerNe - decals: - 4652: 16,74 - - node: - color: '#DE3A3A96' - id: BrickTileWhiteInnerNe - decals: - 4171: 56,-14 - 4235: -63,46 - - node: - color: '#334E6DC8' - id: BrickTileWhiteInnerNw - decals: - 3515: 9,-14 - 3540: 14,-12 - 3570: -4,-3 - 4231: -57,51 - 4757: -24,16 - - node: - color: '#52B4E996' - id: BrickTileWhiteInnerNw - decals: - 4923: -48,-37 - - node: - color: '#D381C996' - id: BrickTileWhiteInnerNw - decals: - 4653: 14,74 - - node: - color: '#DE3A3A96' - id: BrickTileWhiteInnerNw - decals: - 4236: -61,46 - - node: - color: '#334E6DC8' - id: BrickTileWhiteInnerSe - decals: - 3493: 0,-10 - - node: - color: '#52B4E996' - id: BrickTileWhiteInnerSe - decals: - 4916: -52,-35 - 4934: -37,-40 - - node: - color: '#DE3A3A96' - id: BrickTileWhiteInnerSe - decals: - 4163: 56,-6 - - node: - color: '#334E6DC8' - id: BrickTileWhiteInnerSw - decals: - 3507: 14,-10 - 4756: -24,19 - - node: - color: '#52B4E996' - id: BrickTileWhiteInnerSw - decals: - 4915: -48,-35 - - node: - color: '#DE3A3A96' - id: BrickTileWhiteInnerSw - decals: - 4194: 54,-6 - - node: - color: '#FFFFFFFF' - id: BrickTileWhiteInnerSw - decals: - 4456: -34,-13 - - node: - color: '#334E6DC8' - id: BrickTileWhiteLineE - decals: - 3492: 0,-11 - 3520: 5,-13 - - node: - color: '#52B4E996' - id: BrickTileWhiteLineE - decals: - 4913: -52,-36 - 4952: -30,-36 - 4953: -30,-37 - 4954: -30,-38 - 4955: -30,-39 - - node: - color: '#9FED5896' - id: BrickTileWhiteLineE - decals: - 4709: -32,16 - - node: - color: '#A4610696' - id: BrickTileWhiteLineE - decals: - 3936: 40,27 - 3937: 40,28 - 3938: 40,29 - 3974: 38,20 - 3975: 38,19 - - node: - color: '#D381C996' - id: BrickTileWhiteLineE - decals: - 4348: 31,74 - 4349: 31,75 - 4407: 29,55 - 4408: 29,54 - 4409: 29,53 - 4410: 29,52 - 4644: 19,73 - - node: - color: '#D4D4D405' - id: BrickTileWhiteLineE - decals: - 4738: -29,18 - 4739: -29,17 - - node: - color: '#D4D4D40C' - id: BrickTileWhiteLineE - decals: - 4726: -28,18 - 4727: -28,17 - - node: - color: '#D4D4D426' - id: BrickTileWhiteLineE - decals: - 4730: -28,18 - 4731: -28,17 - - node: - color: '#D4D4D428' - id: BrickTileWhiteLineE - decals: - 4714: -32,19 - - node: - color: '#DE3A3A96' - id: BrickTileWhiteLineE - decals: - 4164: 56,-7 - 4165: 56,-8 - 4166: 56,-9 - 4167: 56,-10 - 4168: 56,-11 - 4169: 56,-12 - 4170: 56,-13 - 4174: 58,-15 - 4175: 58,-16 - 4176: 58,-17 - 4177: 58,-18 - 4178: 58,-19 - 4201: 41,0 - 4202: 41,-1 - 4711: -32,15 - - node: - color: '#EFB34196' - id: BrickTileWhiteLineE - decals: - 4710: -32,20 - - node: - color: '#F9801DFF' - id: BrickTileWhiteLineE - decals: - 4543: -30,-28 - 4544: -30,-27 - 4545: -30,-26 - 4546: -30,-25 - - node: - color: '#FFFFFFFF' - id: BrickTileWhiteLineE - decals: - 3888: 29,59 - 3889: 29,60 - 4064: -17,-30 - 4067: 7,-40 - 4068: 7,-41 - 4443: -29,-13 - 4715: -45,15 - - node: - color: '#334E6DC8' - id: BrickTileWhiteLineN - decals: - 3487: 4,-12 - 3488: 3,-12 - 3489: 2,-12 - 3490: 1,-12 - 3509: 13,-12 - 3510: 12,-12 - 3511: 11,-12 - 3512: 10,-12 - 3516: 8,-14 - 3517: 7,-14 - 3518: 6,-14 - 3566: -8,-3 - 3567: -7,-3 - 3568: -6,-3 - 4229: -58,51 - - node: - color: '#52B4E996' - id: BrickTileWhiteLineN - decals: - 4920: -51,-37 - 4921: -50,-37 - 4922: -49,-37 - 4943: -39,-35 - 4944: -38,-35 - 4945: -37,-35 - 4946: -36,-35 - 4947: -35,-35 - 4948: -34,-35 - 4949: -33,-35 - 4950: -32,-35 - 4951: -31,-35 - - node: - color: '#A4610696' - id: BrickTileWhiteLineN - decals: - 3971: 36,21 - 3972: 37,21 - - node: - color: '#D381C996' - id: BrickTileWhiteLineN - decals: - 4335: 24,79 - 4364: 26,79 - 4365: 27,79 - 4404: 27,56 - 4405: 28,56 - 4640: 12,74 - 4641: 13,74 - 4642: 15,75 - 4643: 17,74 - 4663: 18,74 - - node: - color: '#DE3A3A96' - id: BrickTileWhiteLineN - decals: - 4143: 50,-5 - 4144: 51,-5 - 4145: 52,-5 - 4146: 53,-5 - 4147: 54,-5 - 4148: 55,-5 - 4149: 56,-5 - 4150: 57,-5 - 4151: 58,-5 - 4152: 59,-5 - 4153: 60,-5 - 4154: 61,-5 - 4172: 57,-14 - 4237: -62,46 - - node: - color: '#FFFFFFFF' - id: BrickTileWhiteLineN - decals: - 3874: 28,61 - 3875: 27,61 - 3876: 26,61 - 3877: 25,61 - 3878: 24,61 - 3879: 23,61 - 4019: -53,-31 - 4020: -52,-31 - 4021: -51,-31 - 4022: -50,-31 - 4023: -49,-31 - 4024: -48,-31 - 4025: -47,-31 - 4026: -46,-31 - 4027: -45,-31 - 4028: -44,-31 - 4029: -43,-31 - 4030: -42,-31 - 4031: -41,-31 - 4032: -40,-31 - 4033: -39,-31 - 4034: -38,-31 - 4035: -37,-31 - 4036: -36,-31 - 4037: -35,-31 - 4038: -34,-31 - 4039: -33,-31 - 4040: -32,-31 - 4041: -31,-31 - 4042: -30,-31 - 4059: -19,-29 - 4060: -18,-29 - 4445: -30,-12 - 4446: -31,-12 - 4447: -32,-12 - 4448: -33,-12 - 4449: -34,-12 - 4450: -35,-12 - 4451: -36,-12 - - node: - color: '#334E6DC8' - id: BrickTileWhiteLineS - decals: - 3494: 1,-10 - 3495: 2,-10 - 3496: 3,-10 - 3497: 4,-10 - 3498: 5,-10 - 3499: 6,-10 - 3500: 7,-10 - 3501: 8,-10 - 3502: 9,-10 - 3503: 10,-10 - 3504: 11,-10 - 3505: 12,-10 - 3506: 13,-10 - - node: - color: '#52B4E996' - id: BrickTileWhiteLineS - decals: - 4910: -51,-35 - 4911: -50,-35 - 4912: -49,-35 - 4935: -39,-41 - 4936: -38,-41 - 4937: -36,-40 - 4938: -35,-40 - 4939: -34,-40 - 4940: -33,-40 - 4941: -32,-40 - 4942: -31,-40 - - node: - color: '#A4610696' - id: BrickTileWhiteLineS - decals: - 3965: 37,18 - 3966: 36,18 - - node: - color: '#D381C996' - id: BrickTileWhiteLineS - decals: - 4341: 24,73 - 4342: 25,73 - 4343: 26,73 - 4344: 27,73 - 4345: 28,73 - 4346: 29,73 - 4347: 30,73 - 4362: 26,78 - 4363: 27,78 - 4633: 12,72 - 4634: 13,72 - 4635: 14,72 - 4636: 15,72 - 4637: 16,72 - 4638: 17,72 - 4639: 18,72 - - node: - color: '#DE3A3A96' - id: BrickTileWhiteLineS - decals: - 4137: 51,-6 - 4138: 50,-6 - 4139: 52,-6 - 4140: 53,-6 - 4157: 61,-6 - 4159: 60,-6 - 4160: 59,-6 - 4161: 58,-6 - 4162: 57,-6 - 4180: 57,-20 - 4181: 56,-20 - 4182: 55,-20 - - node: - color: '#F9801DFF' - id: BrickTileWhiteLineS - decals: - 4534: -32,-29 - 4535: -33,-29 - 4536: -34,-29 - 4537: -35,-29 - 4538: -36,-29 - 4539: -37,-29 - 4540: -38,-29 - 4541: -31,-29 - - node: - color: '#FFFFFFFF' - id: BrickTileWhiteLineS - decals: - 3880: 23,58 - 3881: 24,58 - 3882: 25,58 - 3883: 26,58 - 3884: 27,58 - 3885: 28,58 - 3995: -30,-33 - 3996: -31,-33 - 3997: -32,-33 - 3998: -33,-33 - 3999: -34,-33 - 4000: -35,-33 - 4001: -36,-33 - 4002: -37,-33 - 4003: -38,-33 - 4004: -39,-33 - 4005: -40,-33 - 4006: -41,-33 - 4007: -42,-33 - 4008: -43,-33 - 4009: -44,-33 - 4010: -45,-33 - 4011: -46,-33 - 4012: -47,-33 - 4013: -48,-33 - 4014: -49,-33 - 4015: -50,-33 - 4016: -51,-33 - 4017: -52,-33 - 4018: -53,-33 - 4061: -19,-31 - 4062: -18,-31 - 4437: -34,-14 - 4438: -33,-14 - 4439: -32,-14 - 4440: -31,-14 - 4441: -30,-14 - 4454: -36,-13 - 4455: -35,-13 - - node: - color: '#334E6DC8' - id: BrickTileWhiteLineW - decals: - 3508: 14,-11 - 3514: 9,-13 - 4707: -32,20 - 4754: -24,17 - 4755: -24,18 - - node: - color: '#52B4E996' - id: BrickTileWhiteLineW - decals: - 4708: -32,15 - 4914: -48,-36 - 4956: -40,-40 - 4957: -40,-39 - 4958: -40,-38 - 4959: -40,-37 - 4960: -40,-36 - - node: - color: '#A4610696' - id: BrickTileWhiteLineW - decals: - 3930: 39,28 - 3931: 39,29 - 3932: 39,27 - 3968: 35,19 - 3969: 35,20 - 4713: -32,19 - node: color: '#D381C996' id: BrickTileWhiteLineW decals: - 4336: 23,78 - 4337: 23,77 - 4338: 23,76 - 4339: 23,75 - 4340: 23,74 - 4401: 26,52 - 4402: 26,53 - 4645: 11,73 - 4712: -32,16 + 4323: 23,78 + 4324: 23,77 + 4325: 23,76 + 4326: 23,75 + 4327: 23,74 + 4388: 26,52 + 4389: 26,53 + 4632: 11,73 + 4699: -32,16 - node: color: '#D4D4D407' id: BrickTileWhiteLineW decals: - 4734: -28,17 - 4735: -28,18 + 4721: -28,17 + 4722: -28,18 - node: color: '#DE3A3A96' id: BrickTileWhiteLineW decals: - 4184: 54,-19 - 4185: 54,-18 - 4186: 54,-14 - 4187: 54,-13 - 4188: 54,-12 - 4189: 54,-11 - 4190: 54,-10 - 4191: 54,-9 - 4192: 54,-8 - 4193: 54,-7 - 4199: 39,0 - 4200: 39,-1 + 4171: 54,-19 + 4172: 54,-18 + 4173: 54,-14 + 4174: 54,-13 + 4175: 54,-12 + 4176: 54,-11 + 4177: 54,-10 + 4178: 54,-9 + 4179: 54,-8 + 4180: 54,-7 + 4186: 39,0 + 4187: 39,-1 - node: color: '#FFFFFFFF' id: BrickTileWhiteLineW decals: - 3732: -34,-14 - 3886: 22,59 - 3887: 22,60 - 4063: -20,-30 - 4069: 7,-40 - 4070: 7,-41 + 3719: -34,-14 + 3873: 22,59 + 3874: 22,60 + 4050: -20,-30 + 4056: 7,-40 + 4057: 7,-41 - node: color: '#9FED58B7' id: BushAThree decals: - 4779: -1.3686488,46.73154 + 4766: -1.3686488,46.73154 - node: color: '#9FED58B7' id: BushATwo decals: - 4776: -1.8939891,47.625587 + 4763: -1.8939891,47.625587 - node: color: '#9FED5888' id: Busha1 decals: - 4768: -3.0174823,45.91548 + 4755: -3.0174823,45.91548 - node: color: '#9FED5888' id: Busha2 decals: - 4758: -1.1858082,47.7461 - 4762: -2.0945249,48.15766 - 4763: -3.1452603,46.53989 - 4765: -1.0012178,48.11507 + 4745: -1.1858082,47.7461 + 4749: -2.0945249,48.15766 + 4750: -3.1452603,46.53989 + 4752: -1.0012178,48.11507 - node: color: '#FFFFFFC0' id: Busha2 decals: - 4464: -19.715633,-0.08040953 - 4465: -18.948898,1.7076702 - 4466: -19.360664,4.00663 + 4451: -19.715633,-0.08040953 + 4452: -18.948898,1.7076702 + 4453: -19.360664,4.00663 - node: color: '#60BC5DB1' id: Busha3 decals: - 4518: -19.190277,3.2119274 + 4505: -19.190277,3.2119274 - node: color: '#9FED5896' id: Busha3 decals: - 3231: -40.3527,-18.329292 - 3232: -43.1027,-18.48207 - 3233: -42.922146,-21.50985 - 3234: -41.408257,-22.968182 - 3235: -39.96381,-23.48207 - 3236: -39.99159,-21.829292 - 3237: -41.19992,-21.815403 - 3238: -40.86659,-18.565403 - 3239: -39.811035,-17.926516 - 3240: -41.11659,-17.75985 - 3241: -42.853085,-20.88498 + 3218: -40.3527,-18.329292 + 3219: -43.1027,-18.48207 + 3220: -42.922146,-21.50985 + 3221: -41.408257,-22.968182 + 3222: -39.96381,-23.48207 + 3223: -39.99159,-21.829292 + 3224: -41.19992,-21.815403 + 3225: -40.86659,-18.565403 + 3226: -39.811035,-17.926516 + 3227: -41.11659,-17.75985 + 3228: -42.853085,-20.88498 - node: color: '#A4DF8296' id: Busha3 decals: - 1686: -7.8109317,-1.9599552 + 1675: -7.8109317,-1.9599552 - node: color: '#9FED5888' id: Bushb1 decals: - 4761: -2.7476902,46.8379 + 4748: -2.7476902,46.8379 - node: color: '#60BC5DB1' id: Bushb2 decals: - 4517: -19.928616,2.0482564 - 4519: -19.786627,0.2601776 + 4504: -19.928616,2.0482564 + 4506: -19.786627,0.2601776 - node: color: '#60E25863' id: Bushb2 decals: - 3334: -17.64635,-37.739723 + 3321: -17.64635,-37.739723 - node: color: '#60E258BA' id: Bushb2 decals: - 3335: -16.049128,-37.545277 - 3336: -15.201906,-36.309166 - 3337: -15.313017,-37.7675 - 3338: -17.03524,-36.392498 - 3339: -17.868574,-36.281387 - 3340: -17.715796,-37.948055 - 3341: -16.118574,-38.059166 - 3342: -15.243574,-36.920277 - 3343: -16.826906,-36.850834 - 3344: -17.563017,-36.809166 - 3345: -16.701906,-37.670277 - 3346: -16.688017,-36.295277 - 3347: -15.729685,-36.670277 + 3322: -16.049128,-37.545277 + 3323: -15.201906,-36.309166 + 3324: -15.313017,-37.7675 + 3325: -17.03524,-36.392498 + 3326: -17.868574,-36.281387 + 3327: -17.715796,-37.948055 + 3328: -16.118574,-38.059166 + 3329: -15.243574,-36.920277 + 3330: -16.826906,-36.850834 + 3331: -17.563017,-36.809166 + 3332: -16.701906,-37.670277 + 3333: -16.688017,-36.295277 + 3334: -15.729685,-36.670277 - node: color: '#9FED5888' id: Bushb2 decals: - 4760: -2.932261,47.646793 - 4766: -0.98705816,45.801918 + 4747: -2.932261,47.646793 + 4753: -0.98705816,45.801918 - node: color: '#9FED5896' id: Bushb2 decals: - 3306: 78.083496,7.9973173 - 3307: 79.00016,7.900096 - 3308: 79.84738,7.8862066 + 3293: 78.083496,7.9973173 + 3294: 79.00016,7.900096 + 3295: 79.84738,7.8862066 - node: color: '#9FED58B7' id: Bushb2 decals: - 4775: -1.9508109,45.96523 - 4777: -0.9142871,46.774105 + 4762: -1.9508109,45.96523 + 4764: -0.9142871,46.774105 - node: color: '#A4DF8296' id: Bushb2 decals: - 1687: -6.2553773,-1.9043994 + 1676: -6.2553773,-1.9043994 - node: color: '#FFFFFFC0' id: Bushb2 decals: - 4467: -19.999609,3.2545013 - 4468: -19.85762,1.8637729 - 4469: -18.920502,0.8420129 - 4470: -20.184193,0.5156174 - 4471: -19.062489,3.4531765 - 4472: -20.212591,4.3046427 + 4454: -19.999609,3.2545013 + 4455: -19.85762,1.8637729 + 4456: -18.920502,0.8420129 + 4457: -20.184193,0.5156174 + 4458: -19.062489,3.4531765 + 4459: -20.212591,4.3046427 - node: color: '#60BC5DB1' id: Bushb3 decals: - 4514: -19.247074,3.6518526 - 4515: -19.871819,1.7928166 - 4516: -19.829224,0.13245726 - 4520: -18.948898,3.5241327 + 4501: -19.247074,3.6518526 + 4502: -19.871819,1.7928166 + 4503: -19.829224,0.13245726 + 4507: -18.948898,3.5241327 - node: color: '#9FED5888' id: Bushb3 decals: - 4759: -3.0174766,46.241875 - 4764: -3.1594381,47.859665 + 4746: -3.0174766,46.241875 + 4751: -3.1594381,47.859665 - node: color: '#9FED58B7' id: Bushb3 decals: - 4778: -1.666812,47.42691 + 4765: -1.666812,47.42691 - node: color: '#9FED5888' id: Bushc1 decals: - 4767: -2.8187013,45.81614 + 4754: -2.8187013,45.81614 - node: color: '#FFFFFFC0' id: Bushc1 decals: - 4462: -20.013807,2.6159015 - 4463: -20.042206,1.2393641 + 4449: -20.013807,2.6159015 + 4450: -20.042206,1.2393641 - node: color: '#9FED5896' id: Bushc3 decals: - 3242: -43.038807,-18.0765 + 3229: -43.038807,-18.0765 - node: color: '#FFFFFFFF' id: Bushg1 decals: - 4783: -16.08111,-40.251266 + 4770: -16.08111,-40.251266 - node: color: '#FFFFFFFF' id: Bushg2 decals: - 4782: -17.983753,-40.59182 + 4769: -17.983753,-40.59182 - node: color: '#FFFFFFFF' id: Bushg3 decals: - 4780: -14.888399,-39.371437 + 4767: -14.888399,-39.371437 - node: color: '#FFFFFFFF' id: Bushg4 decals: - 4781: -15.484749,-39.442383 + 4768: -15.484749,-39.442383 - node: color: '#A4DF8296' id: Bushj3 decals: - 1689: -7.4513307,-22.276455 - 1690: -9.062441,-22.720898 - 1691: -8.867998,-23.748676 - 1692: -7.340218,-23.748676 + 1678: -7.4513307,-22.276455 + 1679: -9.062441,-22.720898 + 1680: -8.867998,-23.748676 + 1681: -7.340218,-23.748676 - node: color: '#A4DF8296' id: Bushk1 decals: - 1688: -8.284664,-23.526455 - 1693: -7.340218,-22.970898 + 1677: -8.284664,-23.526455 + 1682: -7.340218,-22.970898 - node: color: '#FFFFFF6C' id: Bushk1 decals: - 4460: -18.991495,3.5808964 + 4447: -18.991495,3.5808964 - node: color: '#FFFFFFC0' id: Bushk1 decals: - 4461: -19.062489,2.7720032 + 4448: -19.062489,2.7720032 - node: color: '#60E25873' id: Bushm1 decals: - 3388: -59.97946,38.265724 - 3389: -60.02113,39.390724 - 3390: -59.99335,40.724056 - 3391: -59.91002,42.335167 - 3392: -60.090576,43.071278 - 3393: -60.10446,41.279613 - 3394: -60.04891,39.765724 + 3375: -59.97946,38.265724 + 3376: -60.02113,39.390724 + 3377: -59.99335,40.724056 + 3378: -59.91002,42.335167 + 3379: -60.090576,43.071278 + 3380: -60.10446,41.279613 + 3381: -60.04891,39.765724 - node: color: '#52B4E95A' id: CheckerNESW decals: - 4796: 73,-1 - 4797: 72,-1 - 4798: 72,0 - 4799: 73,0 - 4800: 85,-1 - 4801: 85,0 - 4802: 86,0 - 4803: 86,-1 + 4783: 73,-1 + 4784: 72,-1 + 4785: 72,0 + 4786: 73,0 + 4787: 85,-1 + 4788: 85,0 + 4789: 86,0 + 4790: 86,-1 - node: color: '#52B4E996' id: CheckerNESW decals: - 4881: -34,-43 - 4882: -34,-44 - 4917: -51,-36 - 4918: -50,-36 - 4919: -49,-36 + 4868: -34,-43 + 4869: -34,-44 + 4904: -51,-36 + 4905: -50,-36 + 4906: -49,-36 - node: color: '#52B4E996' id: CheckerNWSE decals: - 3274: -46,-35 - 3275: -46,-36 - 3276: -45,-35 - 3277: -45,-36 - 3278: -44,-35 - 3279: -44,-36 - 3280: -43,-35 - 3281: -43,-36 - 3282: -42,-35 - 3283: -42,-36 + 3261: -46,-35 + 3262: -46,-36 + 3263: -45,-35 + 3264: -45,-36 + 3265: -44,-35 + 3266: -44,-36 + 3267: -43,-35 + 3268: -43,-36 + 3269: -42,-35 + 3270: -42,-36 - node: color: '#D381C996' id: CheckerNWSE decals: - 962: 21,65 - 963: 21,64 - 964: 21,63 - 965: 22,65 - 966: 22,64 - 967: 22,63 - 968: 23,65 - 969: 23,64 - 970: 23,63 - 971: 24,65 - 972: 24,64 - 973: 24,63 + 952: 21,65 + 953: 21,64 + 954: 21,63 + 955: 22,65 + 956: 22,64 + 957: 22,63 + 958: 23,65 + 959: 23,64 + 960: 23,63 + 961: 24,65 + 962: 24,64 + 963: 24,63 - node: color: '#FED83D79' id: CheckerNWSE decals: - 4788: 85,-1 - 4789: 85,0 - 4790: 86,0 - 4791: 86,-1 - 4792: 72,-1 - 4793: 72,0 - 4794: 73,0 - 4795: 73,-1 + 4775: 85,-1 + 4776: 85,0 + 4777: 86,0 + 4778: 86,-1 + 4779: 72,-1 + 4780: 72,0 + 4781: 73,0 + 4782: 73,-1 - node: color: '#0E7F1BFF' id: Delivery decals: - 4993: 37,-12 + 4971: 37,-12 - node: color: '#1861D5FF' id: Delivery decals: - 4991: 34,-13 + 4969: 34,-13 - node: color: '#334E6DC8' id: Delivery decals: - 497: -6,-1 + 487: -6,-1 - node: color: '#79150096' id: Delivery decals: - 3297: 81,16 - 3298: 82,16 - 3299: 83,16 - 3300: 84,16 - 3301: 74,16 - 3302: 75,16 - 3303: 76,16 - 3304: 77,16 + 3284: 81,16 + 3285: 82,16 + 3286: 83,16 + 3287: 84,16 + 3288: 74,16 + 3289: 75,16 + 3290: 76,16 + 3291: 77,16 - node: color: '#951710FF' id: Delivery decals: - 4992: 34,-12 + 4970: 34,-12 - node: color: '#D58C18FF' id: Delivery decals: - 4994: 38,-12 + 4972: 38,-12 - node: color: '#EFB34196' id: Delivery decals: - 1046: 37,29 - 1207: -64,39 + 1036: 37,29 + 1197: -64,39 - node: color: '#EFB34196' id: DeliveryGreyscale decals: - 1111: 36,13 - 1112: 37,13 - 1113: 38,13 - 1118: 42,22 - 1119: 43,22 - 1122: 42,20 - 1123: 43,20 + 1101: 36,13 + 1102: 37,13 + 1103: 38,13 + 1108: 42,22 + 1109: 43,22 + 1112: 42,20 + 1113: 43,20 - node: color: '#52B4E996' id: DiagonalCheckerBOverlay decals: - 4043: -20,-29 - 4044: -20,-30 - 4045: -20,-31 - 4046: -19,-29 - 4047: -19,-30 - 4048: -19,-31 - 4049: -18,-29 - 4050: -18,-30 - 4051: -18,-31 - 4052: -17,-29 - 4053: -17,-30 - 4054: -17,-31 + 4030: -20,-29 + 4031: -20,-30 + 4032: -20,-31 + 4033: -19,-29 + 4034: -19,-30 + 4035: -19,-31 + 4036: -18,-29 + 4037: -18,-30 + 4038: -18,-31 + 4039: -17,-29 + 4040: -17,-30 + 4041: -17,-31 - node: color: '#D381C996' id: DiagonalCheckerBOverlay decals: - 3838: 22,58 - 3839: 22,59 - 3840: 22,61 - 3841: 22,60 - 3842: 23,61 - 3843: 23,60 - 3844: 23,59 - 3845: 23,58 - 3846: 24,58 - 3847: 24,59 - 3848: 24,60 - 3849: 24,61 - 3850: 25,61 - 3851: 25,60 - 3852: 25,59 - 3853: 25,58 - 3854: 26,58 - 3855: 26,59 - 3856: 26,60 - 3857: 26,61 - 3858: 27,61 - 3859: 27,60 - 3860: 27,59 - 3861: 27,58 - 3862: 28,58 - 3863: 28,59 - 3864: 28,60 - 3865: 28,61 - 3866: 29,61 - 3867: 29,60 - 3868: 29,59 - 3869: 29,58 + 3825: 22,58 + 3826: 22,59 + 3827: 22,61 + 3828: 22,60 + 3829: 23,61 + 3830: 23,60 + 3831: 23,59 + 3832: 23,58 + 3833: 24,58 + 3834: 24,59 + 3835: 24,60 + 3836: 24,61 + 3837: 25,61 + 3838: 25,60 + 3839: 25,59 + 3840: 25,58 + 3841: 26,58 + 3842: 26,59 + 3843: 26,60 + 3844: 26,61 + 3845: 27,61 + 3846: 27,60 + 3847: 27,59 + 3848: 27,58 + 3849: 28,58 + 3850: 28,59 + 3851: 28,60 + 3852: 28,61 + 3853: 29,61 + 3854: 29,60 + 3855: 29,59 + 3856: 29,58 - node: color: '#FFFFFFFF' id: DiagonalCheckerBOverlay decals: - 3716: -34,-14 - 3717: -33,-14 - 3718: -33,-13 - 3719: -29,-14 - 3720: -30,-14 - 3721: -31,-14 - 3722: -32,-14 - 3723: -32,-13 - 3724: -32,-12 - 3725: -33,-12 - 3726: -31,-12 - 3727: -31,-13 - 3728: -30,-12 - 3729: -30,-13 - 3730: -29,-13 - 3731: -29,-12 - 4429: -34,-13 - 4430: -34,-12 - 4431: -35,-12 - 4432: -35,-13 - 4433: -36,-13 - 4434: -36,-12 - 4435: -37,-13 - 4436: -37,-12 + 3703: -34,-14 + 3704: -33,-14 + 3705: -33,-13 + 3706: -29,-14 + 3707: -30,-14 + 3708: -31,-14 + 3709: -32,-14 + 3710: -32,-13 + 3711: -32,-12 + 3712: -33,-12 + 3713: -31,-12 + 3714: -31,-13 + 3715: -30,-12 + 3716: -30,-13 + 3717: -29,-13 + 3718: -29,-12 + 4416: -34,-13 + 4417: -34,-12 + 4418: -35,-12 + 4419: -35,-13 + 4420: -36,-13 + 4421: -36,-12 + 4422: -37,-13 + 4423: -37,-12 - node: cleanable: True color: '#8354328B' id: Dirt decals: - 4572: -38,-10 - 4573: -38,-13 - 4574: -32,-12 - 4575: -34,-13 - 4576: -34,-12 - 4577: -35,-12 - 4578: -36,-12 - 4579: -37,-13 - 4580: -35,-13 - 4581: -34,-13 - 4582: -33,-14 - 4583: -32,-14 - 4584: -31,-14 - 4585: -31,-12 - 4586: -30,-12 - 4587: -29,-14 - 4588: -29,-13 - 4589: -29,-12 - 4590: -31,-12 - 4591: -31,-14 - 4592: -29,-14 - 4593: -32,-16 - 4594: -33,-16 - 4595: -34,-16 - 4596: -37,-10 - 4597: -28,-12 - 4598: -32,-8 - 4599: -34,-9 - 4600: -31,-8 - 4601: -30,-7 - 4602: -33,-8 - 4603: -33,-8 - 4604: -34,-7 + 4559: -38,-10 + 4560: -38,-13 + 4561: -32,-12 + 4562: -34,-13 + 4563: -34,-12 + 4564: -35,-12 + 4565: -36,-12 + 4566: -37,-13 + 4567: -35,-13 + 4568: -34,-13 + 4569: -33,-14 + 4570: -32,-14 + 4571: -31,-14 + 4572: -31,-12 + 4573: -30,-12 + 4574: -29,-14 + 4575: -29,-13 + 4576: -29,-12 + 4577: -31,-12 + 4578: -31,-14 + 4579: -29,-14 + 4580: -32,-16 + 4581: -33,-16 + 4582: -34,-16 + 4583: -37,-10 + 4584: -28,-12 + 4585: -32,-8 + 4586: -34,-9 + 4587: -31,-8 + 4588: -30,-7 + 4589: -33,-8 + 4590: -33,-8 + 4591: -34,-7 - node: color: '#A4610696' id: Dirt decals: - 3395: -3,-35 - 3396: 1,-36 - 3397: -1,-36 - 3398: 2,-35 - 3399: 4,-36 - 3400: 8,-36 - 3401: 10,-35 - 3402: 11,-36 - 3403: 13,-36 - 3404: 15,-35 - 3405: 17,-36 - 3406: 7,-35 - 3407: 6,-35 - 3408: 4,-35 - 3409: 6,-36 - 3410: 2,-36 - 3411: 1,-35 - 3412: 3,-35 - 3413: 9,-36 - 3414: 11,-36 - 3415: 14,-36 + 3382: -3,-35 + 3383: 1,-36 + 3384: -1,-36 + 3385: 2,-35 + 3386: 4,-36 + 3387: 8,-36 + 3388: 10,-35 + 3389: 11,-36 + 3390: 13,-36 + 3391: 15,-35 + 3392: 17,-36 + 3393: 7,-35 + 3394: 6,-35 + 3395: 4,-35 + 3396: 6,-36 + 3397: 2,-36 + 3398: 1,-35 + 3399: 3,-35 + 3400: 9,-36 + 3401: 11,-36 + 3402: 14,-36 - node: cleanable: True color: '#A4610696' id: Dirt decals: - 1707: -5,50 - 1708: -6,46 - 1709: -7,44 - 1710: -4,48 - 1711: -1,50 - 1712: 2,49 - 1713: 5,49 - 1714: 6,51 - 1715: 7,49 - 1716: 9,50 - 1717: 13,49 - 1718: 16,51 - 1719: 19,49 - 1720: 23,50 - 1721: 23,49 - 1722: 29,51 - 1723: 31,51 - 1724: 32,49 - 1725: 33,47 - 1726: 31,48 - 1727: 34,53 - 1728: 33,49 - 1729: 30,49 - 1730: 32,42 - 1731: 33,40 - 1732: 33,36 - 1733: 32,34 - 1734: 32,32 - 1735: 33,33 - 1736: 32,29 - 1737: 31,27 - 1738: 32,28 - 1739: 33,24 - 1740: 32,22 - 1741: 33,23 - 1742: 31,21 - 1743: 33,19 - 1744: 32,17 - 1745: 31,16 - 1746: 32,15 - 1747: 33,14 - 1748: 31,12 - 1749: 31,11 - 1750: 33,9 - 1751: 32,8 - 1752: 31,7 - 1753: 33,4 - 1754: 30,3 - 1755: 30,2 - 1756: 30,2 - 1757: 28,1 - 1758: 28,0 - 1759: 29,0 - 1760: 27,-1 - 1761: 27,-2 - 1762: 28,-4 - 1763: 26,-4 - 1764: 25,-4 - 1765: 24,-5 - 1766: 22,-5 - 1767: 21,-4 - 1768: 20,-3 - 1769: 18,-4 - 1770: 12,-4 - 1771: 9,-4 - 1772: 7,-4 - 1773: 3,-4 - 1774: 0,-4 - 1775: 1,-4 - 1776: -5,-4 - 1777: -6,-5 - 1778: -7,-5 - 1779: -6,-4 - 1780: -10,-4 - 1781: -12,-5 - 1782: -14,-5 - 1783: -14,-4 - 1784: -16,-4 - 1785: -17,-5 - 1786: -18,-5 - 1787: -23,-5 - 1788: -24,-5 - 1789: -32,-4 - 1790: -38,-4 - 1791: -39,-4 - 1792: -40,-5 - 1793: -42,-5 - 1794: -42,-6 - 1795: -42,-7 - 1796: -42,-10 - 1797: -42,-12 - 1798: -42,-14 - 1799: -40,-16 - 1800: -42,-17 - 1801: -38,-7 - 1802: -38,-8 - 1803: -37,-7 - 1804: -33,-7 - 1805: -26,-4 - 1806: -24,-1 - 1807: -23,0 - 1808: -23,2 - 1809: -24,3 - 1810: -23,5 - 1811: -23,6 - 1812: -24,6 - 1813: -23,7 - 1814: -23,10 - 1815: -30,5 - 1816: -31,1 - 1817: -31,4 - 1818: -26,1 - 1819: -26,2 - 1820: -22,8 - 1821: -24,9 - 1822: -22,10 - 1823: -24,8 - 1824: -23,9 - 1825: -22,13 - 1826: -24,15 - 1827: -23,16 - 1828: -22,17 - 1829: -25,18 - 1830: -23,18 - 1831: -23,19 - 1832: -25,22 - 1833: -23,23 - 1834: -23,24 - 1835: -24,25 - 1836: -22,26 - 1837: -23,27 - 1838: -24,28 - 1839: -22,30 - 1840: -23,30 - 1841: -24,31 - 1842: -26,29 - 1843: -27,30 - 1844: -29,30 - 1845: -27,29 - 1846: -31,29 - 1847: -32,30 - 1848: -34,29 - 1849: -36,29 - 1850: -37,30 - 1851: -39,29 - 1852: -40,29 - 1853: -42,30 - 1854: -43,30 - 1855: -45,29 - 1856: -46,30 - 1857: -47,30 - 1858: -46,29 - 1859: -51,30 - 1860: -52,31 - 1861: -53,29 - 1862: -54,30 - 1863: -55,31 - 1864: -57,29 - 1865: -58,30 - 1866: -57,32 - 1867: -58,34 - 1868: -56,36 - 1869: -57,39 - 1870: -56,40 - 1871: -57,45 - 1872: -57,46 - 1873: -59,48 - 1874: -57,49 - 1875: -59,50 - 1876: -58,49 - 1877: -59,47 - 1878: -58,45 - 1879: -62,49 - 1880: -64,49 - 1881: -64,49 - 1882: -64,48 - 1883: -62,48 - 1884: -61,54 - 1885: -59,54 - 1886: -59,54 - 1887: -59,53 - 1888: -62,45 - 1889: -63,43 - 1890: -63,40 - 1891: -63,40 - 1892: -62,36 - 1893: -61,35 - 1894: -56,35 - 1895: -45,29 - 1896: -40,30 - 1897: -43,26 - 1898: -41,26 - 1899: -40,26 - 1900: -38,26 - 1901: -37,26 - 1902: -40,27 - 1903: -20,34 - 1904: -20,35 - 1905: -21,41 - 1906: -20,43 - 1907: -20,44 - 1908: -21,46 - 1909: -20,47 - 1910: -20,49 - 1911: -21,50 - 1912: -21,51 - 1913: -20,53 - 1914: -20,54 - 1915: -24,53 - 1916: -26,53 - 1917: -27,53 - 1918: -28,54 - 1919: -29,54 - 1920: -28,56 - 1921: -28,57 - 1922: -28,58 - 1923: -27,59 - 1924: -25,59 - 1925: -24,58 - 1926: -24,56 - 1927: -21,55 - 1928: -20,52 - 1929: -19,51 - 1930: -20,42 - 1931: -20,40 - 1932: -16,44 - 1933: -14,43 - 1934: -13,44 - 1935: -11,45 - 1936: -10,44 - 1937: -12,48 - 1938: -13,47 - 1939: -14,48 - 1940: -11,47 - 1941: -10,48 - 1942: -10,52 - 1943: -11,53 - 1944: -14,53 - 1945: -15,53 - 1946: -17,53 - 1947: -17,51 - 1948: -10,39 - 1949: -11,38 - 1950: -14,38 - 1951: -14,37 - 1952: -15,36 - 1953: -16,38 - 1954: -16,40 - 1955: -14,41 - 1956: -11,39 - 1957: -17,39 - 1958: -8,44 - 1959: -8,45 - 1960: -7,42 - 1961: -6,41 - 1962: -5,46 - 1963: -6,49 - 1964: -7,49 - 1965: 2,44 - 1966: -6,29 - 1967: -4,31 - 1968: -2,31 - 1969: 0,30 - 1970: 2,30 - 1971: 4,31 - 1972: 5,31 - 1973: 7,30 - 1974: 9,30 - 1975: 10,31 - 1976: 11,31 - 1977: 10,30 - 1978: 14,31 - 1979: 15,31 - 1980: 17,30 - 1981: 18,31 - 1982: 22,23 - 1983: 23,23 - 1984: 23,22 - 1985: 22,22 - 1986: 21,23 - 1987: 21,23 - 1988: 20,24 + 1696: -5,50 + 1697: -6,46 + 1698: -7,44 + 1699: -4,48 + 1700: -1,50 + 1701: 2,49 + 1702: 5,49 + 1703: 6,51 + 1704: 7,49 + 1705: 9,50 + 1706: 13,49 + 1707: 16,51 + 1708: 19,49 + 1709: 23,50 + 1710: 23,49 + 1711: 29,51 + 1712: 31,51 + 1713: 32,49 + 1714: 33,47 + 1715: 31,48 + 1716: 34,53 + 1717: 33,49 + 1718: 30,49 + 1719: 32,42 + 1720: 33,40 + 1721: 33,36 + 1722: 32,34 + 1723: 32,32 + 1724: 33,33 + 1725: 32,29 + 1726: 31,27 + 1727: 32,28 + 1728: 33,24 + 1729: 32,22 + 1730: 33,23 + 1731: 31,21 + 1732: 33,19 + 1733: 32,17 + 1734: 31,16 + 1735: 32,15 + 1736: 33,14 + 1737: 31,12 + 1738: 31,11 + 1739: 33,9 + 1740: 32,8 + 1741: 31,7 + 1742: 33,4 + 1743: 30,3 + 1744: 30,2 + 1745: 30,2 + 1746: 28,1 + 1747: 28,0 + 1748: 29,0 + 1749: 27,-1 + 1750: 27,-2 + 1751: 28,-4 + 1752: 26,-4 + 1753: 25,-4 + 1754: 24,-5 + 1755: 22,-5 + 1756: 21,-4 + 1757: 20,-3 + 1758: 18,-4 + 1759: 12,-4 + 1760: 9,-4 + 1761: 7,-4 + 1762: 3,-4 + 1763: 0,-4 + 1764: 1,-4 + 1765: -5,-4 + 1766: -6,-5 + 1767: -7,-5 + 1768: -6,-4 + 1769: -10,-4 + 1770: -12,-5 + 1771: -14,-5 + 1772: -14,-4 + 1773: -16,-4 + 1774: -17,-5 + 1775: -18,-5 + 1776: -23,-5 + 1777: -24,-5 + 1778: -32,-4 + 1779: -38,-4 + 1780: -39,-4 + 1781: -40,-5 + 1782: -42,-5 + 1783: -42,-6 + 1784: -42,-7 + 1785: -42,-10 + 1786: -42,-12 + 1787: -42,-14 + 1788: -40,-16 + 1789: -42,-17 + 1790: -38,-7 + 1791: -38,-8 + 1792: -37,-7 + 1793: -33,-7 + 1794: -26,-4 + 1795: -24,-1 + 1796: -23,0 + 1797: -23,2 + 1798: -24,3 + 1799: -23,5 + 1800: -23,6 + 1801: -24,6 + 1802: -23,7 + 1803: -23,10 + 1804: -30,5 + 1805: -31,1 + 1806: -31,4 + 1807: -26,1 + 1808: -26,2 + 1809: -22,8 + 1810: -24,9 + 1811: -22,10 + 1812: -24,8 + 1813: -23,9 + 1814: -22,13 + 1815: -24,15 + 1816: -23,16 + 1817: -22,17 + 1818: -25,18 + 1819: -23,18 + 1820: -23,19 + 1821: -25,22 + 1822: -23,23 + 1823: -23,24 + 1824: -24,25 + 1825: -22,26 + 1826: -23,27 + 1827: -24,28 + 1828: -22,30 + 1829: -23,30 + 1830: -24,31 + 1831: -26,29 + 1832: -27,30 + 1833: -29,30 + 1834: -27,29 + 1835: -31,29 + 1836: -32,30 + 1837: -34,29 + 1838: -36,29 + 1839: -37,30 + 1840: -39,29 + 1841: -40,29 + 1842: -42,30 + 1843: -43,30 + 1844: -45,29 + 1845: -46,30 + 1846: -47,30 + 1847: -46,29 + 1848: -51,30 + 1849: -52,31 + 1850: -53,29 + 1851: -54,30 + 1852: -55,31 + 1853: -57,29 + 1854: -58,30 + 1855: -57,32 + 1856: -58,34 + 1857: -56,36 + 1858: -57,39 + 1859: -56,40 + 1860: -57,45 + 1861: -57,46 + 1862: -59,48 + 1863: -57,49 + 1864: -59,50 + 1865: -58,49 + 1866: -59,47 + 1867: -58,45 + 1868: -62,49 + 1869: -64,49 + 1870: -64,49 + 1871: -64,48 + 1872: -62,48 + 1873: -61,54 + 1874: -59,54 + 1875: -59,54 + 1876: -59,53 + 1877: -62,45 + 1878: -63,43 + 1879: -63,40 + 1880: -63,40 + 1881: -62,36 + 1882: -61,35 + 1883: -56,35 + 1884: -45,29 + 1885: -40,30 + 1886: -43,26 + 1887: -41,26 + 1888: -40,26 + 1889: -38,26 + 1890: -37,26 + 1891: -40,27 + 1892: -20,34 + 1893: -20,35 + 1894: -21,41 + 1895: -20,43 + 1896: -20,44 + 1897: -21,46 + 1898: -20,47 + 1899: -20,49 + 1900: -21,50 + 1901: -21,51 + 1902: -20,53 + 1903: -20,54 + 1904: -24,53 + 1905: -26,53 + 1906: -27,53 + 1907: -28,54 + 1908: -29,54 + 1909: -28,56 + 1910: -28,57 + 1911: -28,58 + 1912: -27,59 + 1913: -25,59 + 1914: -24,58 + 1915: -24,56 + 1916: -21,55 + 1917: -20,52 + 1918: -19,51 + 1919: -20,42 + 1920: -20,40 + 1921: -16,44 + 1922: -14,43 + 1923: -13,44 + 1924: -11,45 + 1925: -10,44 + 1926: -12,48 + 1927: -13,47 + 1928: -14,48 + 1929: -11,47 + 1930: -10,48 + 1931: -10,52 + 1932: -11,53 + 1933: -14,53 + 1934: -15,53 + 1935: -17,53 + 1936: -17,51 + 1937: -10,39 + 1938: -11,38 + 1939: -14,38 + 1940: -14,37 + 1941: -15,36 + 1942: -16,38 + 1943: -16,40 + 1944: -14,41 + 1945: -11,39 + 1946: -17,39 + 1947: -8,44 + 1948: -8,45 + 1949: -7,42 + 1950: -6,41 + 1951: -5,46 + 1952: -6,49 + 1953: -7,49 + 1954: 2,44 + 1955: -6,29 + 1956: -4,31 + 1957: -2,31 + 1958: 0,30 + 1959: 2,30 + 1960: 4,31 + 1961: 5,31 + 1962: 7,30 + 1963: 9,30 + 1964: 10,31 + 1965: 11,31 + 1966: 10,30 + 1967: 14,31 + 1968: 15,31 + 1969: 17,30 + 1970: 18,31 + 1971: 22,23 + 1972: 23,23 + 1973: 23,22 + 1974: 22,22 + 1975: 21,23 + 1976: 21,23 + 1977: 20,24 + 1978: 20,23 + 1979: 21,21 + 1980: 20,20 + 1981: 20,19 + 1982: 22,19 + 1983: 24,19 + 1984: 27,19 + 1985: 29,19 + 1986: 29,19 + 1987: 24,19 + 1988: 22,21 1989: 20,23 - 1990: 21,21 - 1991: 20,20 - 1992: 20,19 - 1993: 22,19 - 1994: 24,19 - 1995: 27,19 - 1996: 29,19 - 1997: 29,19 - 1998: 24,19 - 1999: 22,21 - 2000: 20,23 - 2001: 20,26 - 2002: 20,29 - 2003: 20,31 - 2004: 23,31 - 2005: 27,31 - 2006: 29,31 - 2007: 29,30 - 2008: 27,30 - 2009: 24,30 - 2010: 21,31 - 2011: 20,33 - 2012: 21,35 - 2013: 22,35 - 2014: 26,37 - 2015: 25,35 - 2016: 25,36 - 2017: 26,34 - 2018: 27,34 - 2019: 28,36 - 2020: 28,37 - 2021: 27,34 - 2022: 28,35 - 2023: 26,34 - 2024: 25,33 - 2025: 24,34 - 2026: 24,36 - 2027: 25,38 - 2028: 27,38 - 2029: 29,37 - 2030: 29,35 - 2031: 20,38 - 2032: 21,40 - 2033: 22,41 - 2034: 23,40 - 2035: 21,41 - 2036: 21,43 - 2037: 21,43 - 2038: 20,45 - 2039: 17,45 - 2040: 20,46 - 2041: 14,45 - 2042: 12,45 - 2043: 11,41 - 2044: 10,41 - 2045: 8,41 - 2046: 6,41 - 2047: 5,39 - 2048: 5,38 - 2049: 4,43 - 2050: 5,45 - 2051: 5,47 - 2052: 6,47 - 2053: 9,47 - 2054: 25,47 - 2055: 25,46 - 2056: 26,45 - 2057: 26,45 - 2058: 22,8 - 2059: 21,8 - 2060: 22,9 - 2061: 21,10 - 2062: 20,10 - 2063: 21,13 - 2064: 20,14 - 2065: 21,15 - 2066: 19,14 - 2067: 18,16 - 2068: 18,16 - 2069: 17,15 - 2070: -4,11 - 2071: -4,10 - 2072: -5,10 - 2073: -6,10 - 2074: -7,10 - 2075: -7,8 - 2076: -7,7 - 2077: -9,8 - 2078: -6,12 - 2079: -6,16 - 2080: 29,7 - 2081: 29,8 - 2082: 29,9 - 2083: 28,10 - 2084: 26,9 - 2085: 25,8 - 2086: 25,7 - 2087: 29,8 - 2088: 27,8 - 2089: 47,29 - 2090: 45,29 - 2091: 43,29 - 2092: 42,29 - 2093: 42,28 - 2094: 44,28 - 2095: 46,27 - 2096: 46,27 - 2097: 44,27 - 2098: 43,27 - 2099: 45,26 - 2100: 44,25 - 2101: 43,25 - 2102: 44,24 - 2103: 41,23 - 2104: 43,22 - 2105: 43,22 - 2106: 42,21 - 2107: 43,20 - 2108: 42,19 - 2109: 43,19 - 2110: 41,18 - 2111: 43,17 - 2112: 42,17 - 2113: 43,20 - 2114: 42,21 - 2115: 43,21 - 2116: 45,20 - 2117: 43,20 - 2118: 45,21 - 2119: 46,21 - 2120: 45,22 - 2121: 44,22 - 2122: 44,21 - 2123: 45,21 - 2124: 44,23 - 2125: 44,23 - 2126: 47,23 - 2127: 48,23 - 2128: 48,23 - 2129: 48,23 - 2130: 47,23 - 2131: 48,22 - 2132: 48,21 - 2133: 47,21 - 2134: 47,21 - 2135: 47,21 - 2136: 48,21 - 2137: 45,22 - 2138: 45,23 - 2139: 44,23 - 2140: 45,24 - 2141: 43,18 - 2142: 41,17 - 2143: 42,16 - 2144: 43,15 - 2145: 43,15 - 2146: 42,14 - 2147: 41,13 - 2148: 42,12 - 2149: 43,14 - 2150: 43,13 - 2151: 39,14 - 2152: 39,12 - 2153: 37,12 - 2154: 36,13 - 2155: 35,14 - 2156: 34,13 - 2157: 38,33 - 2158: 39,33 - 2159: 41,33 - 2160: 42,33 - 2161: 44,33 - 2162: 45,36 - 2163: 46,36 - 2164: 46,35 - 2165: 46,33 - 2166: 44,32 - 2167: 43,33 - 2168: 40,33 - 2169: 43,34 - 2170: 45,37 - 2171: 46,36 - 2172: 47,33 - 2173: 47,33 - 2174: 39,33 - 2175: 43,33 - 2176: 37,33 - 2177: 35,33 - 2178: 34,34 - 2179: 32,37 - 2180: 32,42 - 2181: 33,44 - 2182: 32,47 - 2183: 33,48 - 2184: 33,50 - 2185: 13,55 - 2186: 14,55 - 2187: 15,55 - 2188: 15,54 - 2189: 15,54 - 2190: 14,54 - 2191: 13,54 - 2192: 14,53 - 2193: 15,53 - 2194: 14,53 - 2195: 13,53 - 2196: 16,53 - 2197: 16,53 - 2198: 16,55 - 2199: 16,56 - 2200: 14,56 - 2201: 14,56 - 2202: 16,57 - 2203: 14,57 - 2204: 13,57 - 2205: 12,57 - 2206: 11,55 - 2207: 12,54 - 2208: 11,53 - 2209: 19,60 - 2210: 19,57 - 2211: 18,60 - 2212: 18,64 - 2213: 20,65 - 2214: 22,66 - 2215: 21,66 - 2216: 22,64 - 2217: 21,64 - 2218: 23,65 - 2219: 24,66 - 2220: 23,67 - 2221: 23,69 - 2222: 24,71 - 2223: 26,71 - 2224: 26,69 - 2225: 27,68 - 2226: 29,69 - 2227: 11,72 - 2228: 20,74 - 2229: 20,73 - 2230: 23,47 - 2231: 23,47 - 2232: 23,47 - 2233: 23,46 - 2234: 23,46 - 2235: 22,47 - 2236: 35,57 - 2237: 36,56 - 2238: 36,56 - 2239: 37,56 - 2240: 36,56 - 2241: 36,55 - 2242: 36,54 - 2243: 36,53 - 2244: 38,53 - 2245: 40,53 - 2246: 40,55 - 2247: 40,56 - 2248: 41,57 - 2249: 41,56 - 2250: 39,56 - 2251: 40,55 - 2252: 41,53 - 2253: 41,53 - 2254: 43,54 - 2255: 43,55 - 2256: 43,57 - 2257: 43,55 - 2258: 43,53 - 2259: 43,52 - 2260: 43,50 - 2261: 45,50 - 2262: 46,50 - 2263: 47,50 - 2264: 47,49 - 2265: 47,47 - 2266: 47,46 - 2267: 47,46 - 2268: 46,44 - 2269: 46,44 - 2270: 46,45 - 2271: 46,46 - 2272: 46,47 - 2273: 40,50 - 2274: 40,48 - 2275: 40,46 - 2276: 39,45 - 2277: 37,46 - 2278: 35,46 - 2279: 40,50 - 2280: 40,52 - 2281: 40,51 - 2282: 40,50 - 2283: 40,43 - 2284: 40,43 - 2285: 40,44 - 2286: 39,44 - 2287: 39,44 - 2288: 39,43 - 2289: 39,42 - 2290: 39,40 - 2291: 39,39 - 2292: 40,39 - 2293: 43,39 - 2294: 45,39 - 2295: 46,39 - 2296: 47,39 - 2297: 47,40 - 2298: 46,41 - 2299: 47,42 - 2300: 47,44 - 2301: 47,46 - 2302: 47,48 - 2303: 43,44 - 2304: 44,44 - 2305: 42,43 - 2306: 42,42 - 2307: 43,41 - 2308: 44,41 - 2309: 44,43 - 2310: 43,45 - 2311: 43,47 - 2312: 44,48 - 2313: 44,48 - 2314: 49,33 - 2315: 49,34 - 2316: 50,35 - 2317: 50,36 - 2318: 50,36 - 2319: 35,7 - 2320: 35,8 - 2321: 36,8 - 2322: 37,8 - 2323: 40,8 - 2324: 40,8 - 2325: 40,7 - 2326: 38,7 - 2327: 38,7 - 2328: 41,9 - 2329: 44,9 - 2330: 42,9 - 2331: 46,9 - 2332: 47,9 - 2333: 49,9 - 2334: 49,9 - 2335: 50,9 - 2336: 38,4 - 2337: 35,4 - 2338: 39,2 - 2339: 43,3 - 2340: 45,3 - 2341: 44,0 - 2342: 44,-1 - 2343: 47,-1 - 2344: 44,-1 - 2345: 46,-1 - 2346: 46,-1 - 2347: 45,-1 - 2348: 46,0 - 2349: 45,0 - 2350: 46,3 - 2351: 47,3 - 2352: 45,3 - 2353: 46,4 - 2354: 49,3 - 2355: 51,3 - 2356: 48,2 - 2357: 53,3 - 2358: 55,3 - 2359: 57,2 - 2360: 59,3 - 2361: 61,2 - 2362: 63,4 - 2363: 64,2 - 2364: 65,3 - 2365: 66,3 - 2366: 69,3 - 2367: 69,3 - 2368: 72,4 - 2369: 73,3 - 2370: 75,3 - 2371: 76,3 - 2372: 78,3 - 2373: 79,3 - 2374: 81,3 - 2375: 83,4 - 2376: 84,2 - 2377: 85,3 - 2378: 86,4 - 2379: 83,7 - 2380: 80,7 - 2381: 78,6 - 2382: 76,8 - 2383: 77,9 - 2384: 80,9 - 2385: 83,9 - 2386: 82,12 - 2387: 82,13 - 2388: 83,14 - 2389: 83,14 - 2390: 83,13 - 2391: 75,13 - 2392: 75,15 - 2393: 76,15 - 2394: 76,14 - 2395: 76,9 - 2396: 76,6 - 2397: 77,6 - 2398: 83,6 - 2399: 83,8 - 2400: 84,3 - 2401: 67,2 - 2402: 66,4 - 2403: 61,2 - 2404: 58,4 - 2405: 57,3 - 2406: 56,2 - 2407: 52,4 - 2408: 51,3 - 2409: 53,-13 - 2410: 60,-20 - 2411: 62,-21 - 2412: 61,-22 - 2413: 60,-19 - 2415: 41,-16 - 2416: 38,-16 - 2417: 37,-16 - 2418: 37,-19 - 2419: 37,-20 - 2420: 37,-20 - 2421: 36,-20 - 2422: 37,-20 - 2423: 37,-20 - 2424: 40,-19 - 2425: 40,-19 - 2426: 39,-19 - 2427: 40,-20 - 2428: 43,-19 - 2429: 43,-20 - 2430: 42,-20 - 2431: 45,-19 - 2432: 45,-20 - 2433: 45,-20 - 2434: 46,-20 - 2435: 38,-16 - 2436: 36,-14 - 2437: 35,-13 - 2438: 35,-11 - 2439: 34,-9 - 2440: 35,-7 - 2441: 36,-6 - 2442: 36,-4 - 2443: 36,-3 - 2444: 38,-5 - 2445: 40,-3 - 2446: 39,-3 - 2447: 41,-3 - 2448: 39,2 - 2449: 41,2 - 2450: 31,2 - 2451: 30,3 - 2452: 28,1 - 2453: 28,3 - 2454: 29,0 - 2455: 23,-7 - 2456: 28,-7 - 2457: 7,-16 - 2458: 7,-16 - 2459: 7,-17 - 2460: -9,-2 - 2461: -9,-1 - 2462: -8,-1 - 2463: -7,-1 - 2464: -6,-1 - 2465: -5,-2 - 2466: -5,-6 - 2467: -5,-15 - 2468: -4,-15 - 2469: -6,-19 - 2470: -5,-17 - 2471: -6,-20 - 2472: -4,-22 - 2473: -4,-24 - 2474: -5,-26 - 2475: -8,-26 - 2476: -9,-26 - 2477: -10,-25 - 2478: -11,-27 - 2479: -10,-28 - 2480: -7,-28 - 2481: -13,-25 - 2482: -14,-26 - 2483: -17,-26 - 2484: -19,-25 - 2485: -20,-27 - 2486: -22,-26 - 2487: -25,-26 - 2488: -26,-29 - 2489: -27,-30 - 2490: -26,-31 - 2491: -27,-31 - 2492: -27,-33 - 2493: -25,-34 - 2494: -26,-35 - 2495: -24,-35 - 2496: -23,-35 - 2497: -23,-34 - 2498: -27,-26 - 2499: -28,-26 - 2500: -31,-28 - 2501: -33,-28 - 2502: -37,-28 - 2503: -31,-28 - 2504: -31,-27 - 2505: -37,-28 - 2506: -31,-31 - 2507: -33,-32 - 2508: -34,-33 - 2509: -36,-32 - 2510: -37,-32 - 2511: -39,-33 - 2512: -37,-32 - 2513: -41,-31 + 1990: 20,26 + 1991: 20,29 + 1992: 20,31 + 1993: 23,31 + 1994: 27,31 + 1995: 29,31 + 1996: 29,30 + 1997: 27,30 + 1998: 24,30 + 1999: 21,31 + 2000: 20,33 + 2001: 21,35 + 2002: 22,35 + 2003: 26,37 + 2004: 25,35 + 2005: 25,36 + 2006: 26,34 + 2007: 27,34 + 2008: 28,36 + 2009: 28,37 + 2010: 27,34 + 2011: 28,35 + 2012: 26,34 + 2013: 25,33 + 2014: 24,34 + 2015: 24,36 + 2016: 25,38 + 2017: 27,38 + 2018: 29,37 + 2019: 29,35 + 2020: 20,38 + 2021: 21,40 + 2022: 22,41 + 2023: 23,40 + 2024: 21,41 + 2025: 21,43 + 2026: 21,43 + 2027: 20,45 + 2028: 17,45 + 2029: 20,46 + 2030: 14,45 + 2031: 12,45 + 2032: 11,41 + 2033: 10,41 + 2034: 8,41 + 2035: 6,41 + 2036: 5,39 + 2037: 5,38 + 2038: 4,43 + 2039: 5,45 + 2040: 5,47 + 2041: 6,47 + 2042: 9,47 + 2043: 25,47 + 2044: 25,46 + 2045: 26,45 + 2046: 26,45 + 2047: 22,8 + 2048: 21,8 + 2049: 22,9 + 2050: 21,10 + 2051: 20,10 + 2052: 21,13 + 2053: 20,14 + 2054: 21,15 + 2055: 19,14 + 2056: 18,16 + 2057: 18,16 + 2058: 17,15 + 2059: -4,11 + 2060: -4,10 + 2061: -5,10 + 2062: -6,10 + 2063: -7,10 + 2064: -7,8 + 2065: -7,7 + 2066: -9,8 + 2067: -6,12 + 2068: -6,16 + 2069: 29,7 + 2070: 29,8 + 2071: 29,9 + 2072: 28,10 + 2073: 26,9 + 2074: 25,8 + 2075: 25,7 + 2076: 29,8 + 2077: 27,8 + 2078: 47,29 + 2079: 45,29 + 2080: 43,29 + 2081: 42,29 + 2082: 42,28 + 2083: 44,28 + 2084: 46,27 + 2085: 46,27 + 2086: 44,27 + 2087: 43,27 + 2088: 45,26 + 2089: 44,25 + 2090: 43,25 + 2091: 44,24 + 2092: 41,23 + 2093: 43,22 + 2094: 43,22 + 2095: 42,21 + 2096: 43,20 + 2097: 42,19 + 2098: 43,19 + 2099: 41,18 + 2100: 43,17 + 2101: 42,17 + 2102: 43,20 + 2103: 42,21 + 2104: 43,21 + 2105: 45,20 + 2106: 43,20 + 2107: 45,21 + 2108: 46,21 + 2109: 45,22 + 2110: 44,22 + 2111: 44,21 + 2112: 45,21 + 2113: 44,23 + 2114: 44,23 + 2115: 47,23 + 2116: 48,23 + 2117: 48,23 + 2118: 48,23 + 2119: 47,23 + 2120: 48,22 + 2121: 48,21 + 2122: 47,21 + 2123: 47,21 + 2124: 47,21 + 2125: 48,21 + 2126: 45,22 + 2127: 45,23 + 2128: 44,23 + 2129: 45,24 + 2130: 43,18 + 2131: 41,17 + 2132: 42,16 + 2133: 43,15 + 2134: 43,15 + 2135: 42,14 + 2136: 41,13 + 2137: 42,12 + 2138: 43,14 + 2139: 43,13 + 2140: 39,14 + 2141: 39,12 + 2142: 37,12 + 2143: 36,13 + 2144: 35,14 + 2145: 34,13 + 2146: 38,33 + 2147: 39,33 + 2148: 41,33 + 2149: 42,33 + 2150: 44,33 + 2151: 45,36 + 2152: 46,36 + 2153: 46,35 + 2154: 46,33 + 2155: 44,32 + 2156: 43,33 + 2157: 40,33 + 2158: 43,34 + 2159: 45,37 + 2160: 46,36 + 2161: 47,33 + 2162: 47,33 + 2163: 39,33 + 2164: 43,33 + 2165: 37,33 + 2166: 35,33 + 2167: 34,34 + 2168: 32,37 + 2169: 32,42 + 2170: 33,44 + 2171: 32,47 + 2172: 33,48 + 2173: 33,50 + 2174: 13,55 + 2175: 14,55 + 2176: 15,55 + 2177: 15,54 + 2178: 15,54 + 2179: 14,54 + 2180: 13,54 + 2181: 14,53 + 2182: 15,53 + 2183: 14,53 + 2184: 13,53 + 2185: 16,53 + 2186: 16,53 + 2187: 16,55 + 2188: 16,56 + 2189: 14,56 + 2190: 14,56 + 2191: 16,57 + 2192: 14,57 + 2193: 13,57 + 2194: 12,57 + 2195: 11,55 + 2196: 12,54 + 2197: 11,53 + 2198: 19,60 + 2199: 19,57 + 2200: 18,60 + 2201: 18,64 + 2202: 20,65 + 2203: 22,66 + 2204: 21,66 + 2205: 22,64 + 2206: 21,64 + 2207: 23,65 + 2208: 24,66 + 2209: 23,67 + 2210: 23,69 + 2211: 24,71 + 2212: 26,71 + 2213: 26,69 + 2214: 27,68 + 2215: 29,69 + 2216: 11,72 + 2217: 20,74 + 2218: 20,73 + 2219: 23,47 + 2220: 23,47 + 2221: 23,47 + 2222: 23,46 + 2223: 23,46 + 2224: 22,47 + 2225: 35,57 + 2226: 36,56 + 2227: 36,56 + 2228: 37,56 + 2229: 36,56 + 2230: 36,55 + 2231: 36,54 + 2232: 36,53 + 2233: 38,53 + 2234: 40,53 + 2235: 40,55 + 2236: 40,56 + 2237: 41,57 + 2238: 41,56 + 2239: 39,56 + 2240: 40,55 + 2241: 41,53 + 2242: 41,53 + 2243: 43,54 + 2244: 43,55 + 2245: 43,57 + 2246: 43,55 + 2247: 43,53 + 2248: 43,52 + 2249: 43,50 + 2250: 45,50 + 2251: 46,50 + 2252: 47,50 + 2253: 47,49 + 2254: 47,47 + 2255: 47,46 + 2256: 47,46 + 2257: 46,44 + 2258: 46,44 + 2259: 46,45 + 2260: 46,46 + 2261: 46,47 + 2262: 40,50 + 2263: 40,48 + 2264: 40,46 + 2265: 39,45 + 2266: 37,46 + 2267: 35,46 + 2268: 40,50 + 2269: 40,52 + 2270: 40,51 + 2271: 40,50 + 2272: 40,43 + 2273: 40,43 + 2274: 40,44 + 2275: 39,44 + 2276: 39,44 + 2277: 39,43 + 2278: 39,42 + 2279: 39,40 + 2280: 39,39 + 2281: 40,39 + 2282: 43,39 + 2283: 45,39 + 2284: 46,39 + 2285: 47,39 + 2286: 47,40 + 2287: 46,41 + 2288: 47,42 + 2289: 47,44 + 2290: 47,46 + 2291: 47,48 + 2292: 43,44 + 2293: 44,44 + 2294: 42,43 + 2295: 42,42 + 2296: 43,41 + 2297: 44,41 + 2298: 44,43 + 2299: 43,45 + 2300: 43,47 + 2301: 44,48 + 2302: 44,48 + 2303: 49,33 + 2304: 49,34 + 2305: 50,35 + 2306: 50,36 + 2307: 50,36 + 2308: 35,7 + 2309: 35,8 + 2310: 36,8 + 2311: 37,8 + 2312: 40,8 + 2313: 40,8 + 2314: 40,7 + 2315: 38,7 + 2316: 38,7 + 2317: 41,9 + 2318: 44,9 + 2319: 42,9 + 2320: 46,9 + 2321: 47,9 + 2322: 49,9 + 2323: 49,9 + 2324: 50,9 + 2325: 38,4 + 2326: 35,4 + 2327: 39,2 + 2328: 43,3 + 2329: 45,3 + 2330: 44,0 + 2331: 44,-1 + 2332: 47,-1 + 2333: 44,-1 + 2334: 46,-1 + 2335: 46,-1 + 2336: 45,-1 + 2337: 46,0 + 2338: 45,0 + 2339: 46,3 + 2340: 47,3 + 2341: 45,3 + 2342: 46,4 + 2343: 49,3 + 2344: 51,3 + 2345: 48,2 + 2346: 53,3 + 2347: 55,3 + 2348: 57,2 + 2349: 59,3 + 2350: 61,2 + 2351: 63,4 + 2352: 64,2 + 2353: 65,3 + 2354: 66,3 + 2355: 69,3 + 2356: 69,3 + 2357: 72,4 + 2358: 73,3 + 2359: 75,3 + 2360: 76,3 + 2361: 78,3 + 2362: 79,3 + 2363: 81,3 + 2364: 83,4 + 2365: 84,2 + 2366: 85,3 + 2367: 86,4 + 2368: 83,7 + 2369: 80,7 + 2370: 78,6 + 2371: 76,8 + 2372: 77,9 + 2373: 80,9 + 2374: 83,9 + 2375: 82,12 + 2376: 82,13 + 2377: 83,14 + 2378: 83,14 + 2379: 83,13 + 2380: 75,13 + 2381: 75,15 + 2382: 76,15 + 2383: 76,14 + 2384: 76,9 + 2385: 76,6 + 2386: 77,6 + 2387: 83,6 + 2388: 83,8 + 2389: 84,3 + 2390: 67,2 + 2391: 66,4 + 2392: 61,2 + 2393: 58,4 + 2394: 57,3 + 2395: 56,2 + 2396: 52,4 + 2397: 51,3 + 2398: 53,-13 + 2399: 60,-20 + 2400: 62,-21 + 2401: 61,-22 + 2402: 60,-19 + 2403: 41,-16 + 2404: 38,-16 + 2405: 37,-16 + 2406: 37,-19 + 2407: 37,-20 + 2408: 37,-20 + 2409: 36,-20 + 2410: 37,-20 + 2411: 37,-20 + 2412: 40,-19 + 2413: 40,-19 + 2414: 39,-19 + 2415: 40,-20 + 2416: 43,-19 + 2417: 43,-20 + 2418: 42,-20 + 2419: 45,-19 + 2420: 45,-20 + 2421: 45,-20 + 2422: 46,-20 + 2423: 38,-16 + 2424: 36,-14 + 2425: 35,-13 + 2426: 35,-11 + 2427: 34,-9 + 2428: 35,-7 + 2429: 36,-6 + 2430: 36,-4 + 2431: 36,-3 + 2432: 38,-5 + 2433: 40,-3 + 2434: 39,-3 + 2435: 41,-3 + 2436: 39,2 + 2437: 41,2 + 2438: 31,2 + 2439: 30,3 + 2440: 28,1 + 2441: 28,3 + 2442: 29,0 + 2443: 23,-7 + 2444: 28,-7 + 2445: 7,-16 + 2446: 7,-16 + 2447: 7,-17 + 2448: -9,-2 + 2449: -9,-1 + 2450: -8,-1 + 2451: -7,-1 + 2452: -6,-1 + 2453: -5,-2 + 2454: -5,-6 + 2455: -5,-15 + 2456: -4,-15 + 2457: -6,-19 + 2458: -5,-17 + 2459: -6,-20 + 2460: -4,-22 + 2461: -4,-24 + 2462: -5,-26 + 2463: -8,-26 + 2464: -9,-26 + 2465: -10,-25 + 2466: -11,-27 + 2467: -10,-28 + 2468: -7,-28 + 2469: -13,-25 + 2470: -14,-26 + 2471: -17,-26 + 2472: -19,-25 + 2473: -20,-27 + 2474: -22,-26 + 2475: -25,-26 + 2476: -26,-29 + 2477: -27,-30 + 2478: -26,-31 + 2479: -27,-31 + 2480: -27,-33 + 2481: -25,-34 + 2482: -26,-35 + 2483: -24,-35 + 2484: -23,-35 + 2485: -23,-34 + 2486: -27,-26 + 2487: -28,-26 + 2488: -31,-28 + 2489: -33,-28 + 2490: -37,-28 + 2491: -31,-28 + 2492: -31,-27 + 2493: -37,-28 + 2494: -31,-31 + 2495: -33,-32 + 2496: -34,-33 + 2497: -36,-32 + 2498: -37,-32 + 2499: -39,-33 + 2500: -37,-32 + 2501: -41,-31 + 2502: -42,-32 + 2503: -43,-32 + 2504: -45,-31 + 2505: -46,-32 + 2506: -46,-32 + 2507: -48,-31 + 2508: -49,-32 + 2509: -49,-32 + 2510: -50,-31 + 2511: -51,-32 + 2512: -52,-32 + 2513: -44,-33 2514: -42,-32 - 2515: -43,-32 - 2516: -45,-31 - 2517: -46,-32 - 2518: -46,-32 - 2519: -48,-31 - 2520: -49,-32 - 2521: -49,-32 - 2522: -50,-31 - 2523: -51,-32 - 2524: -52,-32 - 2525: -44,-33 - 2526: -42,-32 - 2527: -41,-31 - 2528: -39,-32 - 2529: -38,-33 - 2530: -37,-33 - 2531: -32,-33 - 2532: -39,-38 - 2533: -39,-39 - 2534: -41,-39 - 2535: -31,-37 - 2536: -31,-38 - 2537: -31,-39 - 2538: -27,-41 - 2539: -27,-39 - 2540: -26,-39 - 2541: -23,-40 - 2542: -24,-41 - 2543: -26,-39 - 2544: -23,-39 - 2545: -24,-39 - 2546: -25,-39 - 2547: -25,-38 - 2548: -35,-41 - 2549: -39,-39 - 2550: -39,-37 - 2551: -32,-36 - 2552: -32,-36 - 2553: -39,-36 - 2554: -49,-28 - 2555: -50,-27 - 2556: -52,-27 - 2557: -52,-28 - 2558: -51,-29 - 2559: -50,-29 - 2560: -50,-28 - 2561: -55,-32 - 2562: -56,-31 - 2563: -57,-31 - 2564: -57,-29 - 2565: -56,-29 - 2566: -55,-29 - 2567: -56,-25 - 2568: -55,-28 - 2569: -57,-27 - 2570: -57,-25 - 2571: -55,-26 - 2572: -55,-27 - 2573: -54,-22 - 2574: -55,-23 - 2575: -55,-23 - 2576: -56,-22 - 2577: -57,-23 - 2578: -59,-23 - 2579: -59,-23 - 2580: -60,-24 - 2581: -60,-25 - 2582: -61,-26 - 2583: -66,-26 - 2584: -64,-26 - 2585: -63,-26 - 2586: -61,-27 - 2587: -61,-29 - 2588: -60,-29 - 2589: -60,-31 - 2590: -60,-33 - 2591: -61,-33 - 2592: -61,-34 - 2593: -61,-36 - 2594: -61,-38 - 2595: -63,-36 - 2596: -64,-36 - 2597: -65,-36 - 2598: -65,-35 - 2599: -64,-34 - 2600: -63,-34 - 2601: -65,-34 - 2602: -65,-34 - 2603: -64,-35 - 2604: -64,-37 - 2605: -64,-37 - 2606: -64,-38 - 2607: -63,-37 - 2608: -63,-37 - 2609: -63,-38 - 2610: -64,-38 - 2611: -64,-37 - 2612: -65,-37 - 2613: -65,-36 - 2614: -64,-36 - 2615: -63,-36 + 2515: -41,-31 + 2516: -39,-32 + 2517: -38,-33 + 2518: -37,-33 + 2519: -32,-33 + 2520: -39,-38 + 2521: -39,-39 + 2522: -41,-39 + 2523: -31,-37 + 2524: -31,-38 + 2525: -31,-39 + 2526: -27,-41 + 2527: -27,-39 + 2528: -26,-39 + 2529: -23,-40 + 2530: -24,-41 + 2531: -26,-39 + 2532: -23,-39 + 2533: -24,-39 + 2534: -25,-39 + 2535: -25,-38 + 2536: -35,-41 + 2537: -39,-39 + 2538: -39,-37 + 2539: -32,-36 + 2540: -32,-36 + 2541: -39,-36 + 2542: -49,-28 + 2543: -50,-27 + 2544: -52,-27 + 2545: -52,-28 + 2546: -51,-29 + 2547: -50,-29 + 2548: -50,-28 + 2549: -55,-32 + 2550: -56,-31 + 2551: -57,-31 + 2552: -57,-29 + 2553: -56,-29 + 2554: -55,-29 + 2555: -56,-25 + 2556: -55,-28 + 2557: -57,-27 + 2558: -57,-25 + 2559: -55,-26 + 2560: -55,-27 + 2561: -54,-22 + 2562: -55,-23 + 2563: -55,-23 + 2564: -56,-22 + 2565: -57,-23 + 2566: -59,-23 + 2567: -59,-23 + 2568: -60,-24 + 2569: -60,-25 + 2570: -61,-26 + 2571: -66,-26 + 2572: -64,-26 + 2573: -63,-26 + 2574: -61,-27 + 2575: -61,-29 + 2576: -60,-29 + 2577: -60,-31 + 2578: -60,-33 + 2579: -61,-33 + 2580: -61,-34 + 2581: -61,-36 + 2582: -61,-38 + 2583: -63,-36 + 2584: -64,-36 + 2585: -65,-36 + 2586: -65,-35 + 2587: -64,-34 + 2588: -63,-34 + 2589: -65,-34 + 2590: -65,-34 + 2591: -64,-35 + 2592: -64,-37 + 2593: -64,-37 + 2594: -64,-38 + 2595: -63,-37 + 2596: -63,-37 + 2597: -63,-38 + 2598: -64,-38 + 2599: -64,-37 + 2600: -65,-37 + 2601: -65,-36 + 2602: -64,-36 + 2603: -63,-36 + 2604: -64,-35 + 2605: -63,-34 + 2606: -64,-34 + 2607: -63,-34 + 2608: -64,-34 + 2609: -65,-36 + 2610: -65,-37 + 2611: -63,-37 + 2612: -63,-38 + 2613: -65,-35 + 2614: -63,-35 + 2615: -64,-35 2616: -64,-35 - 2617: -63,-34 - 2618: -64,-34 - 2619: -63,-34 - 2620: -64,-34 - 2621: -65,-36 - 2622: -65,-37 - 2623: -63,-37 - 2624: -63,-38 - 2625: -65,-35 - 2626: -63,-35 - 2627: -64,-35 - 2628: -64,-35 - 2629: -63,-35 - 2630: -65,-35 - 2631: -61,-41 - 2632: -62,-41 - 2633: -63,-41 - 2634: -63,-43 - 2635: -63,-44 - 2636: -64,-45 - 2637: -66,-44 - 2638: -66,-44 - 2639: -66,-44 - 2640: -66,-43 - 2641: -59,-41 - 2642: -58,-41 - 2643: -58,-40 - 2644: -58,-39 - 2645: -57,-40 - 2646: -57,-43 - 2647: -59,-43 - 2648: -59,-43 - 2649: -60,-44 - 2650: -61,-44 - 2651: -36,-8 - 2652: -32,-12 - 2653: -37,-15 - 2654: -37,-16 - 2655: -38,-16 - 2656: -38,-16 - 2657: -36,-14 - 2658: -36,-16 - 2659: -37,-14 - 2660: -36,-15 - 2661: -32,-19 - 2662: -36,-19 - 2663: -37,-19 - 2664: -37,-21 - 2665: -35,-21 - 2666: -32,-22 - 2667: -33,-22 - 2668: -35,-23 - 2669: -36,-24 - 2670: -21,-8 - 2671: -20,-9 - 2672: -20,-10 - 2673: -24,-11 - 2674: -24,-13 - 2675: -21,-13 - 2676: -22,-16 - 2677: -24,-16 - 2678: -24,-17 - 2679: -23,-18 - 2680: -22,-18 - 2681: -24,-19 - 2682: -24,-20 - 2683: -23,-21 - 2684: -22,-21 - 2685: -26,-20 - 2686: -25,-18 - 2687: -25,-16 - 2688: -25,-15 - 2689: -21,-13 - 2690: -21,-15 - 2691: -21,-17 - 2692: -21,-18 - 2693: -22,-8 - 2694: -25,-10 - 2695: -25,-12 - 2696: -24,-12 - 2697: -24,-8 - 2698: -21,-10 - 2699: -22,-10 - 2700: -22,-13 - 2701: -8,-8 - 2702: -8,-10 - 2703: -8,-11 - 2704: -8,-13 - 2705: -8,-19 + 2617: -63,-35 + 2618: -65,-35 + 2619: -61,-41 + 2620: -62,-41 + 2621: -63,-41 + 2622: -63,-43 + 2623: -63,-44 + 2624: -64,-45 + 2625: -66,-44 + 2626: -66,-44 + 2627: -66,-44 + 2628: -66,-43 + 2629: -59,-41 + 2630: -58,-41 + 2631: -58,-40 + 2632: -58,-39 + 2633: -57,-40 + 2634: -57,-43 + 2635: -59,-43 + 2636: -59,-43 + 2637: -60,-44 + 2638: -61,-44 + 2639: -36,-8 + 2640: -32,-12 + 2641: -37,-15 + 2642: -37,-16 + 2643: -38,-16 + 2644: -38,-16 + 2645: -36,-14 + 2646: -36,-16 + 2647: -37,-14 + 2648: -36,-15 + 2649: -32,-19 + 2650: -36,-19 + 2651: -37,-19 + 2652: -37,-21 + 2653: -35,-21 + 2654: -32,-22 + 2655: -33,-22 + 2656: -35,-23 + 2657: -36,-24 + 2658: -21,-8 + 2659: -20,-9 + 2660: -20,-10 + 2661: -24,-11 + 2662: -24,-13 + 2663: -21,-13 + 2664: -22,-16 + 2665: -24,-16 + 2666: -24,-17 + 2667: -23,-18 + 2668: -22,-18 + 2669: -24,-19 + 2670: -24,-20 + 2671: -23,-21 + 2672: -22,-21 + 2673: -26,-20 + 2674: -25,-18 + 2675: -25,-16 + 2676: -25,-15 + 2677: -21,-13 + 2678: -21,-15 + 2679: -21,-17 + 2680: -21,-18 + 2681: -22,-8 + 2682: -25,-10 + 2683: -25,-12 + 2684: -24,-12 + 2685: -24,-8 + 2686: -21,-10 + 2687: -22,-10 + 2688: -22,-13 + 2689: -8,-8 + 2690: -8,-10 + 2691: -8,-11 + 2692: -8,-13 + 2693: -8,-19 + 2694: -9,-17 + 2695: -11,-18 + 2696: -11,-18 + 2697: -11,-17 + 2698: -10,-16 + 2699: -8,-16 + 2700: -8,-17 + 2701: -10,-17 + 2702: -9,-18 + 2703: -8,-19 + 2704: -9,-20 + 2705: -8,-18 2706: -9,-17 - 2707: -11,-18 - 2708: -11,-18 - 2709: -11,-17 - 2710: -10,-16 - 2711: -8,-16 - 2712: -8,-17 - 2713: -10,-17 - 2714: -9,-18 - 2715: -8,-19 - 2716: -9,-20 - 2717: -8,-18 - 2718: -9,-17 - 2719: -10,-17 - 2720: -10,-18 - 2721: -9,-17 - 2722: -8,-18 - 2723: -9,-19 - 2724: -9,-19 - 2725: -4,-9 - 2726: -5,-11 - 2727: -4,-10 - 2728: -5,-12 - 2729: -5,-14 - 2730: -7,-25 - 2731: -7,-26 - 2732: -6,-28 - 2733: 18,-35 - 2734: -2,-34 - 2735: 12,-32 - 2736: 11,-32 - 2737: 11,-33 - 2738: 12,-33 - 2739: 13,-32 - 2740: 16,-32 - 2741: 17,-32 - 2742: 16,-32 - 2743: 17,-32 - 2744: 16,-32 - 2745: 17,-32 - 2746: 6,-32 - 2747: 7,-33 - 2748: 8,-32 - 2749: -3,-39 - 2750: -3,-39 - 2751: -2,-40 - 2752: -1,-39 - 2753: -1,-38 - 2754: -2,-33 - 2755: -3,-33 - 2756: -3,-32 - 2757: -2,-32 - 2758: -2,-33 - 2759: -3,-33 - 2760: -3,-32 - 2761: -2,-32 - 2762: 7,-45 - 2763: 7,-46 - 2764: 8,-46 - 2765: 9,-46 - 2766: 9,-45 - 2767: 8,-45 - 2768: 8,-46 - 2769: 9,-45 - 2770: 8,-46 - 2771: 13,-43 - 2772: 12,-43 - 2773: 13,-43 - 2774: 12,-43 - 2775: 11,-45 - 2776: 11,-43 - 2777: 11,-46 - 2778: 13,-45 - 2779: 13,-46 - 2780: 13,-45 - 2781: 13,-46 - 2782: 13,-48 - 2783: 14,-49 - 2784: 14,-50 - 2785: 15,-51 - 2786: 16,-50 - 2787: 17,-49 - 2788: 17,-49 - 2789: 16,-48 - 2790: 14,-48 - 2791: 16,-51 - 2792: 16,-52 - 2793: 20,-58 - 2794: 21,-58 - 2795: 20,-57 - 2796: 19,-56 - 2797: 20,-56 - 2798: 20,-54 - 2799: 19,-54 - 2800: 20,-52 - 2801: 19,-51 - 2802: 20,-50 - 2803: 21,-49 - 2804: 19,-48 - 2805: 21,-46 - 2806: 21,-45 - 2807: 19,-44 - 2808: 21,-46 - 2809: 20,-42 - 2810: 19,-41 - 2811: 21,-40 - 2812: 19,-39 - 2813: 21,-38 - 2814: 20,-37 - 2815: 19,-36 - 2816: 21,-35 - 2817: 19,-34 - 2818: 20,-41 - 2819: 20,-38 - 2820: 20,-38 - 2821: 23,-28 - 2822: 21,-29 - 2823: 20,-29 - 2824: 19,-28 - 2825: 25,-28 - 2826: 28,-28 - 2827: 30,-26 - 2828: 31,-26 - 2829: 18,-25 - 2830: 20,-26 - 2831: 21,-24 - 2832: 20,-21 - 2833: 19,-20 - 2834: 21,-21 - 2835: 18,-22 - 2836: 19,-23 - 2837: 20,-24 - 2838: 17,-24 - 2839: 17,-26 - 2840: 12,-24 - 2841: 13,-26 - 2842: 14,-24 - 2843: 10,-24 - 2844: 9,-25 - 2845: 7,-25 - 2846: 8,-26 - 2847: 6,-24 - 2848: 5,-27 - 2849: 4,-25 - 2850: 2,-26 - 2851: 2,-27 - 2852: -2,-24 - 2853: -3,-26 - 2854: -4,-26 - 2855: -5,-24 - 2856: 2,-24 - 2857: 0,-24 - 2858: 0,-26 - 2859: 2,-26 - 2860: 9,-26 - 2861: 11,-26 - 2862: 15,-24 - 2863: 14,-25 - 2864: 21,-26 - 2865: 20,-21 - 2866: 19,-20 - 2867: 19,-19 - 2868: 19,-18 - 2869: 19,-17 - 2870: 19,-11 - 2871: 20,-11 - 2872: 19,-11 - 2873: 20,-12 - 2874: 19,-11 - 2875: 18,-10 - 2876: 19,-7 - 2877: 19,-6 - 2878: 18,-5 - 2879: 22,-15 - 2880: 23,-15 - 2881: 25,-15 - 2882: 25,-14 - 2883: 25,-13 - 2884: 23,-12 - 2885: 22,-12 - 2886: 25,-12 - 2887: 27,-12 - 2888: 28,-13 - 2889: 30,-13 - 2890: 31,-13 - 2891: 31,-12 - 2892: 31,-11 - 2893: 31,-10 - 2894: 31,-8 - 2895: 31,-8 - 2896: 31,-7 - 2897: 31,-4 - 2898: 33,-4 - 2899: 33,-4 - 2900: 32,-5 - 2901: 30,-16 - 2902: 30,-18 - 2903: 31,-15 - 2904: 31,-16 - 2905: 33,-16 - 2906: 33,-15 - 2907: 32,-16 - 2908: 32,-15 - 2909: 51,9 - 2910: 48,9 - 2911: 45,9 - 2912: 42,9 - 2913: 42,8 - 2914: 38,8 - 2915: 35,24 - 2916: 37,24 - 2917: 35,27 - 2918: 35,28 - 2919: 36,30 - 2920: 31,31 - 2921: 32,32 - 2922: 31,35 - 2923: 32,35 - 2924: 33,36 - 2925: 31,39 - 2926: 31,42 - 2927: 33,41 - 2928: 32,40 - 2929: 32,39 - 2930: 0,53 - 2931: 0,52 - 2932: 0,51 - 2933: 0,49 - 2934: 2,51 - 2935: 0,55 - 2936: 1,55 - 2937: 1,59 - 2938: 2,61 - 2939: 1,61 - 2940: -2,61 - 2941: -2,59 - 2942: -1,56 - 2943: -38,51 - 2944: -42,51 - 2945: -45,48 - 2946: -45,45 - 2947: -41,46 - 2948: -37,46 - 2949: -38,44 - 2950: -42,44 - 2951: -44,43 - 2952: -41,41 - 2953: -36,41 - 2954: -35,41 - 2955: -42,40 - 2956: -46,40 - 2957: -39,40 - 2958: -35,41 - 2959: -39,42 - 2960: -45,43 - 2961: -35,44 - 2962: -34,45 - 2963: -42,45 - 2964: -37,47 - 2965: -34,47 - 2966: -44,48 - 2967: -38,49 - 2968: -35,50 - 2969: -43,50 - 2970: -33,51 - 2971: -36,49 - 2972: -43,48 - 2973: -39,48 - 2974: -33,47 - 2975: -39,46 - 2976: -45,45 - 2977: -39,44 - 2978: -34,43 - 2979: -36,41 - 2980: -41,41 - 2981: -41,41 - 2982: -34,40 - 2983: -36,41 - 2984: -39,41 - 2985: -32,41 - 2986: -32,41 - 2987: -31,44 - 2988: -31,48 - 2989: -31,51 - 2990: -28,45 - 2991: -26,45 - 2992: -28,41 - 2993: -26,41 - 2994: -24,41 - 2995: -23,39 - 3137: 50,-37 - 3138: 53,-37 - 3139: 56,-38 - 3140: 55,-38 - 3141: 54,-39 - 3142: 53,-40 - 3143: 53,-42 - 3144: 51,-45 - 3145: 51,-46 - 3146: 46,-47 - 3147: 46,-46 - 3148: 48,-43 - 3149: 46,-45 - 3150: 45,-46 - 3151: 43,-46 - 3152: 47,-43 - 3153: 52,-46 - 3154: 52,-42 - 3155: 53,-42 - 3156: 50,-42 - 3157: 50,-40 - 3158: 50,-37 - 3159: 52,-36 - 3160: 55,-37 - 3161: 55,-38 - 3162: 53,-40 - 3163: 53,-42 - 3164: 52,-45 - 3165: 50,-45 - 3166: 54,-47 - 3167: 51,-47 - 3168: 46,-47 - 3169: 45,-47 - 3170: 44,-46 - 3171: 44,-44 - 3572: -5,-1 - 4417: 28,54 - 4418: 27,55 - 4419: 27,56 - 4420: 26,56 - 4421: 26,55 - 4422: 26,54 - 4423: 27,54 - 4424: 28,52 - 4425: 27,51 - 4426: 28,53 + 2707: -10,-17 + 2708: -10,-18 + 2709: -9,-17 + 2710: -8,-18 + 2711: -9,-19 + 2712: -9,-19 + 2713: -4,-9 + 2714: -5,-11 + 2715: -4,-10 + 2716: -5,-12 + 2717: -5,-14 + 2718: -7,-25 + 2719: -7,-26 + 2720: -6,-28 + 2721: 18,-35 + 2722: -2,-34 + 2723: 12,-32 + 2724: 11,-32 + 2725: 11,-33 + 2726: 12,-33 + 2727: 13,-32 + 2728: 16,-32 + 2729: 17,-32 + 2730: 16,-32 + 2731: 17,-32 + 2732: 16,-32 + 2733: 17,-32 + 2734: 6,-32 + 2735: 7,-33 + 2736: 8,-32 + 2737: -3,-39 + 2738: -3,-39 + 2739: -2,-40 + 2740: -1,-39 + 2741: -1,-38 + 2742: -2,-33 + 2743: -3,-33 + 2744: -3,-32 + 2745: -2,-32 + 2746: -2,-33 + 2747: -3,-33 + 2748: -3,-32 + 2749: -2,-32 + 2750: 7,-45 + 2751: 7,-46 + 2752: 8,-46 + 2753: 9,-46 + 2754: 9,-45 + 2755: 8,-45 + 2756: 8,-46 + 2757: 9,-45 + 2758: 8,-46 + 2759: 13,-43 + 2760: 12,-43 + 2761: 13,-43 + 2762: 12,-43 + 2763: 11,-45 + 2764: 11,-43 + 2765: 11,-46 + 2766: 13,-45 + 2767: 13,-46 + 2768: 13,-45 + 2769: 13,-46 + 2770: 13,-48 + 2771: 14,-49 + 2772: 14,-50 + 2773: 15,-51 + 2774: 16,-50 + 2775: 17,-49 + 2776: 17,-49 + 2777: 16,-48 + 2778: 14,-48 + 2779: 16,-51 + 2780: 16,-52 + 2781: 20,-58 + 2782: 21,-58 + 2783: 20,-57 + 2784: 19,-56 + 2785: 20,-56 + 2786: 20,-54 + 2787: 19,-54 + 2788: 20,-52 + 2789: 19,-51 + 2790: 20,-50 + 2791: 21,-49 + 2792: 19,-48 + 2793: 21,-46 + 2794: 21,-45 + 2795: 19,-44 + 2796: 21,-46 + 2797: 20,-42 + 2798: 19,-41 + 2799: 21,-40 + 2800: 19,-39 + 2801: 21,-38 + 2802: 20,-37 + 2803: 19,-36 + 2804: 21,-35 + 2805: 19,-34 + 2806: 20,-41 + 2807: 20,-38 + 2808: 20,-38 + 2809: 23,-28 + 2810: 21,-29 + 2811: 20,-29 + 2812: 19,-28 + 2813: 25,-28 + 2814: 28,-28 + 2815: 30,-26 + 2816: 31,-26 + 2817: 18,-25 + 2818: 20,-26 + 2819: 21,-24 + 2820: 20,-21 + 2821: 19,-20 + 2822: 21,-21 + 2823: 18,-22 + 2824: 19,-23 + 2825: 20,-24 + 2826: 17,-24 + 2827: 17,-26 + 2828: 12,-24 + 2829: 13,-26 + 2830: 14,-24 + 2831: 10,-24 + 2832: 9,-25 + 2833: 7,-25 + 2834: 8,-26 + 2835: 6,-24 + 2836: 5,-27 + 2837: 4,-25 + 2838: 2,-26 + 2839: 2,-27 + 2840: -2,-24 + 2841: -3,-26 + 2842: -4,-26 + 2843: -5,-24 + 2844: 2,-24 + 2845: 0,-24 + 2846: 0,-26 + 2847: 2,-26 + 2848: 9,-26 + 2849: 11,-26 + 2850: 15,-24 + 2851: 14,-25 + 2852: 21,-26 + 2853: 20,-21 + 2854: 19,-20 + 2855: 19,-19 + 2856: 19,-18 + 2857: 19,-17 + 2858: 19,-11 + 2859: 20,-11 + 2860: 19,-11 + 2861: 20,-12 + 2862: 19,-11 + 2863: 18,-10 + 2864: 19,-7 + 2865: 19,-6 + 2866: 18,-5 + 2867: 22,-15 + 2868: 23,-15 + 2869: 25,-15 + 2870: 25,-14 + 2871: 25,-13 + 2872: 23,-12 + 2873: 22,-12 + 2874: 25,-12 + 2875: 27,-12 + 2876: 28,-13 + 2877: 30,-13 + 2878: 31,-13 + 2879: 31,-12 + 2880: 31,-11 + 2881: 31,-10 + 2882: 31,-8 + 2883: 31,-8 + 2884: 31,-7 + 2885: 31,-4 + 2886: 33,-4 + 2887: 33,-4 + 2888: 32,-5 + 2889: 30,-16 + 2890: 30,-18 + 2891: 31,-15 + 2892: 31,-16 + 2893: 33,-16 + 2894: 33,-15 + 2895: 32,-16 + 2896: 32,-15 + 2897: 51,9 + 2898: 48,9 + 2899: 45,9 + 2900: 42,9 + 2901: 42,8 + 2902: 38,8 + 2903: 35,24 + 2904: 37,24 + 2905: 35,27 + 2906: 35,28 + 2907: 36,30 + 2908: 31,31 + 2909: 32,32 + 2910: 31,35 + 2911: 32,35 + 2912: 33,36 + 2913: 31,39 + 2914: 31,42 + 2915: 33,41 + 2916: 32,40 + 2917: 32,39 + 2918: 0,53 + 2919: 0,52 + 2920: 0,51 + 2921: 0,49 + 2922: 2,51 + 2923: 0,55 + 2924: 1,55 + 2925: 1,59 + 2926: 2,61 + 2927: 1,61 + 2928: -2,61 + 2929: -2,59 + 2930: -1,56 + 2931: -38,51 + 2932: -42,51 + 2933: -45,48 + 2934: -45,45 + 2935: -41,46 + 2936: -37,46 + 2937: -38,44 + 2938: -42,44 + 2939: -44,43 + 2940: -41,41 + 2941: -36,41 + 2942: -35,41 + 2943: -42,40 + 2944: -46,40 + 2945: -39,40 + 2946: -35,41 + 2947: -39,42 + 2948: -45,43 + 2949: -35,44 + 2950: -34,45 + 2951: -42,45 + 2952: -37,47 + 2953: -34,47 + 2954: -44,48 + 2955: -38,49 + 2956: -35,50 + 2957: -43,50 + 2958: -33,51 + 2959: -36,49 + 2960: -43,48 + 2961: -39,48 + 2962: -33,47 + 2963: -39,46 + 2964: -45,45 + 2965: -39,44 + 2966: -34,43 + 2967: -36,41 + 2968: -41,41 + 2969: -41,41 + 2970: -34,40 + 2971: -36,41 + 2972: -39,41 + 2973: -32,41 + 2974: -32,41 + 2975: -31,44 + 2976: -31,48 + 2977: -31,51 + 2978: -28,45 + 2979: -26,45 + 2980: -28,41 + 2981: -26,41 + 2982: -24,41 + 2983: -23,39 + 3124: 50,-37 + 3125: 53,-37 + 3126: 56,-38 + 3127: 55,-38 + 3128: 54,-39 + 3129: 53,-40 + 3130: 53,-42 + 3131: 51,-45 + 3132: 51,-46 + 3133: 46,-47 + 3134: 46,-46 + 3135: 48,-43 + 3136: 46,-45 + 3137: 45,-46 + 3138: 43,-46 + 3139: 47,-43 + 3140: 52,-46 + 3141: 52,-42 + 3142: 53,-42 + 3143: 50,-42 + 3144: 50,-40 + 3145: 50,-37 + 3146: 52,-36 + 3147: 55,-37 + 3148: 55,-38 + 3149: 53,-40 + 3150: 53,-42 + 3151: 52,-45 + 3152: 50,-45 + 3153: 54,-47 + 3154: 51,-47 + 3155: 46,-47 + 3156: 45,-47 + 3157: 44,-46 + 3158: 44,-44 + 3559: -5,-1 + 4404: 28,54 + 4405: 27,55 + 4406: 27,56 + 4407: 26,56 + 4408: 26,55 + 4409: 26,54 + 4410: 27,54 + 4411: 28,52 + 4412: 27,51 + 4413: 28,53 - node: cleanable: True color: '#FFFFFFFF' id: Dirt decals: - 3291: -65,-33 + 3278: -65,-33 - node: cleanable: True color: '#835432B7' id: DirtHeavy decals: - 4547: -28,-13 - 4548: -31,-11 - 4549: -30,-11 - 4550: -37,-10 - 4551: -37,-8 - 4552: -39,-8 - 4553: -38,-12 - 4554: -38,-11 - 4555: -36,-11 - 4556: -34,-15 - 4557: -34,-16 - 4558: -33,-15 - 4559: -32,-16 - 4560: -31,-16 - 4561: -31,-15 - 4562: -30,-15 + 4534: -28,-13 + 4535: -31,-11 + 4536: -30,-11 + 4537: -37,-10 + 4538: -37,-8 + 4539: -39,-8 + 4540: -38,-12 + 4541: -38,-11 + 4542: -36,-11 + 4543: -34,-15 + 4544: -34,-16 + 4545: -33,-15 + 4546: -32,-16 + 4547: -31,-16 + 4548: -31,-15 + 4549: -30,-15 - node: cleanable: True color: '#A4610696' id: DirtHeavy decals: - 2996: -20,45 - 2997: -20,52 - 2998: -21,35 - 2999: -19,37 - 3000: -19,35 - 3001: -20,35 - 3002: -11,40 - 3003: -10,44 - 3004: -10,48 - 3005: -15,48 - 3006: -5,43 - 3007: -2,50 - 3008: 5,50 - 3009: 12,50 - 3010: 15,55 - 3011: 18,58 - 3012: 19,63 - 3013: 23,67 - 3014: 33,47 - 3015: 31,40 - 3016: 26,35 - 3017: 33,31 - 3018: 32,25 - 3019: 31,22 - 3020: 36,23 - 3021: 37,27 - 3022: 42,30 - 3023: 43,27 - 3024: 44,21 - 3025: 42,16 - 3026: 41,13 - 3027: 43,15 - 3028: 44,19 - 3029: 32,8 - 3030: 27,7 - 3031: 40,3 - 3032: 46,3 - 3033: 56,3 - 3034: 64,3 - 3035: 70,3 - 3036: 73,3 - 3037: 83,3 - 3038: 83,10 - 3039: 76,9 - 3040: 80,6 - 3041: 53,-2 - 3042: 46,-16 - 3044: 35,-6 - 3045: 32,-4 - 3046: 26,-5 - 3047: 21,-4 - 3048: 12,-4 - 3049: -5,-4 - 3050: -34,-4 - 3051: -41,-5 - 3052: -46,-33 - 3053: -36,-33 - 3054: -32,-36 - 3055: -39,-39 - 3056: -29,-38 - 3057: -26,-39 - 3058: -24,-35 - 3059: -26,-30 - 3060: -23,-26 - 3061: -17,-26 - 3062: -8,-27 - 3063: -5,-31 - 3064: -6,-37 - 3065: -6,-43 - 3066: -6,-48 - 3067: -6,-53 - 3068: -5,-57 - 3069: 5,-53 - 3070: 3,-53 - 3071: 6,-52 - 3072: 5,-52 - 3073: 4,-52 - 3074: 5,-53 - 3075: 6,-53 - 3076: 28,-27 - 3077: -8,-1 - 3078: -31,-4 - 3079: -25,-17 - 3080: -26,1 - 3081: -23,13 - 3082: -21,19 - 3083: -17,20 - 3084: -13,20 - 3085: -18,14 - 3086: -13,14 - 3087: -23,26 - 3088: -23,30 - 3089: -31,30 - 3090: -42,29 - 3091: -50,30 - 3092: -50,29 - 3093: -56,29 - 3094: -58,35 - 3095: -57,44 - 3096: -58,49 - 3097: -64,43 - 3098: -63,38 - 3099: -52,31 - 3100: -40,29 - 3101: -29,30 - 3102: -22,30 - 3103: -21,32 - 3104: -20,37 - 3105: -20,42 - 3106: -19,51 - 3107: -25,54 - 3108: -27,53 - 3109: -11,47 - 3110: -9,45 - 3111: -5,47 - 3112: 4,50 - 3113: 7,49 - 3114: 16,49 - 3115: 23,50 - 3116: 26,50 - 3117: 19,54 - 3118: 19,63 - 3119: 23,68 - 3120: 32,43 - 3121: 32,36 - 3122: 32,29 - 3123: 32,22 - 3124: 32,19 - 3125: 33,9 - 3126: 33,20 - 3127: 31,26 - 3128: 33,35 - 3129: 15,30 - 3130: 8,30 - 3131: 0,30 - 3132: -8,9 - 3133: -4,10 - 3134: 20,15 - 3135: 21,9 - 3136: 29,4 - 3172: 52,-43 - 3173: 50,-47 - 3174: 45,-46 - 3175: 46,-43 - 3176: 52,-40 - 3177: 55,-37 - 3178: 55,-38 - 3179: 47,-45 - 3180: 44,-47 - 3181: 54,-47 - 3182: 53,-47 - 4427: 27,55 - 4428: 28,52 + 2984: -20,45 + 2985: -20,52 + 2986: -21,35 + 2987: -19,37 + 2988: -19,35 + 2989: -20,35 + 2990: -11,40 + 2991: -10,44 + 2992: -10,48 + 2993: -15,48 + 2994: -5,43 + 2995: -2,50 + 2996: 5,50 + 2997: 12,50 + 2998: 15,55 + 2999: 18,58 + 3000: 19,63 + 3001: 23,67 + 3002: 33,47 + 3003: 31,40 + 3004: 26,35 + 3005: 33,31 + 3006: 32,25 + 3007: 31,22 + 3008: 36,23 + 3009: 37,27 + 3010: 42,30 + 3011: 43,27 + 3012: 44,21 + 3013: 42,16 + 3014: 41,13 + 3015: 43,15 + 3016: 44,19 + 3017: 32,8 + 3018: 27,7 + 3019: 40,3 + 3020: 46,3 + 3021: 56,3 + 3022: 64,3 + 3023: 70,3 + 3024: 73,3 + 3025: 83,3 + 3026: 83,10 + 3027: 76,9 + 3028: 80,6 + 3029: 53,-2 + 3030: 46,-16 + 3031: 35,-6 + 3032: 32,-4 + 3033: 26,-5 + 3034: 21,-4 + 3035: 12,-4 + 3036: -5,-4 + 3037: -34,-4 + 3038: -41,-5 + 3039: -46,-33 + 3040: -36,-33 + 3041: -32,-36 + 3042: -39,-39 + 3043: -29,-38 + 3044: -26,-39 + 3045: -24,-35 + 3046: -26,-30 + 3047: -23,-26 + 3048: -17,-26 + 3049: -8,-27 + 3050: -5,-31 + 3051: -6,-37 + 3052: -6,-43 + 3053: -6,-48 + 3054: -6,-53 + 3055: -5,-57 + 3056: 5,-53 + 3057: 3,-53 + 3058: 6,-52 + 3059: 5,-52 + 3060: 4,-52 + 3061: 5,-53 + 3062: 6,-53 + 3063: 28,-27 + 3064: -8,-1 + 3065: -31,-4 + 3066: -25,-17 + 3067: -26,1 + 3068: -23,13 + 3069: -21,19 + 3070: -17,20 + 3071: -13,20 + 3072: -18,14 + 3073: -13,14 + 3074: -23,26 + 3075: -23,30 + 3076: -31,30 + 3077: -42,29 + 3078: -50,30 + 3079: -50,29 + 3080: -56,29 + 3081: -58,35 + 3082: -57,44 + 3083: -58,49 + 3084: -64,43 + 3085: -63,38 + 3086: -52,31 + 3087: -40,29 + 3088: -29,30 + 3089: -22,30 + 3090: -21,32 + 3091: -20,37 + 3092: -20,42 + 3093: -19,51 + 3094: -25,54 + 3095: -27,53 + 3096: -11,47 + 3097: -9,45 + 3098: -5,47 + 3099: 4,50 + 3100: 7,49 + 3101: 16,49 + 3102: 23,50 + 3103: 26,50 + 3104: 19,54 + 3105: 19,63 + 3106: 23,68 + 3107: 32,43 + 3108: 32,36 + 3109: 32,29 + 3110: 32,22 + 3111: 32,19 + 3112: 33,9 + 3113: 33,20 + 3114: 31,26 + 3115: 33,35 + 3116: 15,30 + 3117: 8,30 + 3118: 0,30 + 3119: -8,9 + 3120: -4,10 + 3121: 20,15 + 3122: 21,9 + 3123: 29,4 + 3159: 52,-43 + 3160: 50,-47 + 3161: 45,-46 + 3162: 46,-43 + 3163: 52,-40 + 3164: 55,-37 + 3165: 55,-38 + 3166: 47,-45 + 3167: 44,-47 + 3168: 54,-47 + 3169: 53,-47 + 4414: 27,55 + 4415: 28,52 - node: cleanable: True color: '#8354328B' id: DirtLight decals: - 4605: -33,-8 - 4606: -32,-8 - 4607: -30,-7 - 4608: -29,-8 + 4592: -33,-8 + 4593: -32,-8 + 4594: -30,-7 + 4595: -29,-8 - node: cleanable: True color: '#FFFFFFFF' id: DirtLight decals: - 3288: -65,-33 - 3289: -64,-33 - 3290: -63,-33 + 3275: -65,-33 + 3276: -64,-33 + 3277: -63,-33 - node: cleanable: True color: '#8354328B' id: DirtMedium decals: - 4609: -28,-8 - 4610: -28,-9 - 4611: -30,-9 + 4596: -28,-8 + 4597: -28,-9 + 4598: -30,-9 - node: cleanable: True color: '#835432B7' id: DirtMedium decals: - 4563: -31,-15 - 4564: -29,-15 - 4565: -28,-14 - 4566: -30,-11 - 4567: -32,-11 - 4568: -38,-13 - 4569: -38,-11 - 4570: -39,-8 - 4571: -28,-12 + 4550: -31,-15 + 4551: -29,-15 + 4552: -28,-14 + 4553: -30,-11 + 4554: -32,-11 + 4555: -38,-13 + 4556: -38,-11 + 4557: -39,-8 + 4558: -28,-12 - node: color: '#9FED58B7' id: FlowersBROne decals: - 4771: -2.6908832,47.53326 + 4758: -2.6908832,47.53326 - node: color: '#9FED5873' id: Flowersbr1 decals: - 3315: 78.72238,7.9556513 - 3316: 79.69461,7.9278736 + 3302: 78.72238,7.9556513 + 3303: 79.69461,7.9278736 - node: color: '#FFFFFFE3' id: Flowersbr1 decals: - 4486: -19.119284,3.6234694 - 4487: -19.829224,1.4664211 + 4473: -19.119284,3.6234694 + 4474: -19.829224,1.4664211 - node: color: '#FFFFFFFF' id: Flowersbr1 decals: - 3355: -17.368574,-37.531387 + 3342: -17.368574,-37.531387 - node: color: '#FFFFFFE3' id: Flowersbr2 decals: - 4488: -19.900217,3.027443 - 4489: -19.005693,2.0766392 + 4475: -19.900217,3.027443 + 4476: -19.005693,2.0766392 - node: color: '#FFFFFFFF' id: Flowersbr2 decals: - 3358: -15.424128,-36.586945 + 3345: -15.424128,-36.586945 - node: color: '#9FED58B7' id: Flowersbr3 decals: - 4770: -1.1716373,46.099934 + 4757: -1.1716373,46.099934 - node: color: '#FFFFFFE3' id: Flowersbr3 decals: - 4490: -19.886019,-0.0094537735 - 4491: -18.82111,0.8136306 + 4477: -19.886019,-0.0094537735 + 4478: -18.82111,0.8136306 - node: color: '#FFFFFFFF' id: Flowersbr3 decals: - 3359: -16.14635,-36.989723 - 3385: -60.04891,40.960167 - 3386: -60.00724,39.210167 - 3387: -60.02113,42.890724 + 3346: -16.14635,-36.989723 + 3372: -60.04891,40.960167 + 3373: -60.00724,39.210167 + 3374: -60.02113,42.890724 - node: color: '#9FED58B7' id: Flowerspv1 decals: - 4769: -2.7477016,46.156727 - 4772: -2.7050896,47.10753 - 4773: -1.4556177,45.858692 + 4756: -2.7477016,46.156727 + 4759: -2.7050896,47.10753 + 4760: -1.4556177,45.858692 - node: color: '#A4DF8296' id: Flowerspv1 decals: - 1702: -7.423552,-22.998676 - 1703: -8.506886,-23.19312 - 1704: -8.8402195,-23.776455 - 1705: -7.2846637,-23.80423 - 1706: -7.3957734,-22.05423 + 1691: -7.423552,-22.998676 + 1692: -8.506886,-23.19312 + 1693: -8.8402195,-23.776455 + 1694: -7.2846637,-23.80423 + 1695: -7.3957734,-22.05423 - node: color: '#FFFFFFE3' id: Flowerspv1 decals: - 4493: -19.928616,2.0766392 + 4480: -19.928616,2.0766392 - node: color: '#9FED5896' id: Flowerspv2 decals: - 3221: -40.505478,-22.24596 - 3222: -40.186035,-23.329292 - 3223: -41.505478,-22.968182 + 3208: -40.505478,-22.24596 + 3209: -40.186035,-23.329292 + 3210: -41.505478,-22.968182 - node: color: '#FFFFFFE3' id: Flowerspv2 decals: - 4492: -19.04829,0.0047369003 - 4494: -18.877905,2.8429594 - 4497: -18.82111,1.3387012 - 4502: -20.028008,-0.22232056 + 4479: -19.04829,0.0047369003 + 4481: -18.877905,2.8429594 + 4484: -18.82111,1.3387012 + 4489: -20.028008,-0.22232056 - node: color: '#FFFFFFFF' id: Flowerspv2 decals: - 3356: -15.688017,-37.836945 + 3343: -15.688017,-37.836945 - node: color: '#9FED5896' id: Flowerspv3 decals: - 3224: -43.172146,-21.537628 - 3225: -40.94992,-18.676516 - 3226: -40.061035,-18.162628 - 3227: -40.436035,-19.176516 - 3228: -43.061035,-17.85707 - 3229: -43.158257,-19.662628 - 3230: -40.99159,-23.49596 + 3211: -43.172146,-21.537628 + 3212: -40.94992,-18.676516 + 3213: -40.061035,-18.162628 + 3214: -40.436035,-19.176516 + 3215: -43.061035,-17.85707 + 3216: -43.158257,-19.662628 + 3217: -40.99159,-23.49596 - node: color: '#FFFFFFE3' id: Flowerspv3 decals: - 4495: -20.0848,3.8505278 - 4496: -19.786627,0.6575284 + 4482: -20.0848,3.8505278 + 4483: -19.786627,0.6575284 - node: color: '#FFFFFFFF' id: Flowerspv3 decals: - 3357: -17.27135,-36.48972 - 3382: -60.00724,38.321278 - 3383: -59.965576,40.001835 - 3384: -59.965576,41.821278 + 3344: -17.27135,-36.48972 + 3369: -60.00724,38.321278 + 3370: -59.965576,40.001835 + 3371: -59.965576,41.821278 - node: color: '#60E25873' id: Flowersy1 decals: - 3374: -60.062798,38.779613 - 3375: -59.965576,40.112946 - 3376: -59.97946,41.404613 + 3361: -60.062798,38.779613 + 3362: -59.965576,40.112946 + 3363: -59.97946,41.404613 - node: color: '#9FED5896' id: Flowersy1 decals: - 3217: -42.811035,-21.551517 - 3218: -42.99159,-18.176516 - 3219: -40.811035,-22.218182 - 3220: -42.894367,-22.87096 + 3204: -42.811035,-21.551517 + 3205: -42.99159,-18.176516 + 3206: -40.811035,-22.218182 + 3207: -42.894367,-22.87096 - node: color: '#A4DF8296' id: Flowersy1 decals: - 1699: -7.4791064,-22.526455 - 1700: -9.145773,-22.720898 - 1701: -8.673552,-23.748676 + 1688: -7.4791064,-22.526455 + 1689: -9.145773,-22.720898 + 1690: -8.673552,-23.748676 - node: color: '#FFFFFFE3' id: Flowersy1 decals: - 4498: -19.005693,3.8079538 + 4485: -19.005693,3.8079538 - node: color: '#FFFFFFE3' id: Flowersy2 decals: - 4499: -19.729832,2.999061 + 4486: -19.729832,2.999061 - node: color: '#9FED5896' id: Flowersy3 decals: - 3215: -41.672146,-22.10707 - 3216: -40.172146,-23.204292 + 3202: -41.672146,-22.10707 + 3203: -40.172146,-23.204292 - node: color: '#FFFFFFE3' id: Flowersy3 decals: - 4500: -19.332266,2.1475945 + 4487: -19.332266,2.1475945 - node: color: '#60E25873' id: Flowersy4 decals: - 3369: -59.937798,42.696278 - 3370: -59.99335,41.751835 - 3371: -60.00724,40.571278 - 3372: -60.062798,39.418503 - 3373: -59.965576,38.085167 + 3356: -59.937798,42.696278 + 3357: -59.99335,41.751835 + 3358: -60.00724,40.571278 + 3359: -60.062798,39.418503 + 3360: -59.965576,38.085167 - node: color: '#9FED5896' id: Flowersy4 decals: - 3212: -40.24159,-18.343182 - 3213: -41.172146,-18.63485 - 3214: -40.283257,-19.10707 + 3199: -40.24159,-18.343182 + 3200: -41.172146,-18.63485 + 3201: -40.283257,-19.10707 - node: color: '#FFFFFFE3' id: Flowersy4 decals: - 4501: -19.687237,1.0832615 + 4488: -19.687237,1.0832615 - node: color: '#D4D4D428' id: FullTileOverlayGreyscale decals: - 4804: 86,-2 - 4805: 85,-2 - 4806: 85,1 - 4807: 86,1 - 4808: 73,1 - 4809: 72,1 - 4810: 72,-2 - 4811: 73,-2 + 4791: 86,-2 + 4792: 85,-2 + 4793: 85,1 + 4794: 86,1 + 4795: 73,1 + 4796: 72,1 + 4797: 72,-2 + 4798: 73,-2 - node: color: '#A4DF8296' id: Grassa4 decals: - 1683: -7.8109317,-1.9877326 + 1672: -7.8109317,-1.9877326 - node: color: '#FFFFFF85' id: Grassd3 decals: - 4476: -19.488453,1.96311 - 4477: -18.70752,2.7436213 - 4478: -18.892103,0.898777 - 4479: -19.829224,-0.023644924 - 4480: -20.0848,2.4456081 - 4481: -20.311981,-0.37842274 + 4463: -19.488453,1.96311 + 4464: -18.70752,2.7436213 + 4465: -18.892103,0.898777 + 4466: -19.829224,-0.023644924 + 4467: -20.0848,2.4456081 + 4468: -20.311981,-0.37842274 - node: color: '#60E25873' id: Grasse1 decals: - 3360: -17.39635,-36.50361 - 3361: -15.813017,-36.434166 - 3362: -15.2157955,-36.545277 - 3363: -15.729685,-37.656387 - 3364: -17.590796,-37.531387 - 3365: -16.063017,-36.961945 - 3366: -15.674128,-37.948055 - 3367: -14.951906,-37.128613 - 3368: -15.229685,-38.073055 + 3347: -17.39635,-36.50361 + 3348: -15.813017,-36.434166 + 3349: -15.2157955,-36.545277 + 3350: -15.729685,-37.656387 + 3351: -17.590796,-37.531387 + 3352: -16.063017,-36.961945 + 3353: -15.674128,-37.948055 + 3354: -14.951906,-37.128613 + 3355: -15.229685,-38.073055 - node: color: '#FFFFFF85' id: Grasse1 decals: - 4482: -20.269386,0.16083956 - 4483: -18.792713,3.3112655 - 4484: -19.147682,2.431417 - 4485: -18.806911,4.205305 + 4469: -20.269386,0.16083956 + 4470: -18.792713,3.3112655 + 4471: -19.147682,2.431417 + 4472: -18.806911,4.205305 - node: color: '#60FF5D92' id: Grasse2 decals: - 4503: -20.0848,0.047310352 - 4504: -19.729832,0.99811506 - 4505: -18.906303,2.4172258 - 4506: -18.9347,3.7937632 - 4507: -19.985409,4.077585 - 4508: -20.028008,2.6726656 - 4509: -19.062489,1.1967907 - 4510: -19.957012,0.88458633 + 4490: -20.0848,0.047310352 + 4491: -19.729832,0.99811506 + 4492: -18.906303,2.4172258 + 4493: -18.9347,3.7937632 + 4494: -19.985409,4.077585 + 4495: -20.028008,2.6726656 + 4496: -19.062489,1.1967907 + 4497: -19.957012,0.88458633 - node: color: '#FFFFFF85' id: Grasse2 decals: - 4473: -19.034092,3.6092787 - 4474: -19.729832,3.0700169 - 4475: -20.0848,2.1475945 + 4460: -19.034092,3.6092787 + 4461: -19.729832,3.0700169 + 4462: -20.0848,2.1475945 - node: color: '#334E6DC8' id: HalfTileOverlayGreyscale decals: - 1224: -62,55 - 1225: -61,55 - 1226: -60,55 - 1227: -59,55 - 1228: -58,55 + 1214: -62,55 + 1215: -61,55 + 1216: -60,55 + 1217: -59,55 + 1218: -58,55 - node: color: '#52B4E996' id: HalfTileOverlayGreyscale @@ -4363,140 +4363,140 @@ entities: 297: -32,-42 298: -31,-42 299: -30,-42 - 503: -41,-38 - 4886: -35,-42 - 4887: -34,-42 - 4888: -33,-42 + 493: -41,-38 + 4873: -35,-42 + 4874: -34,-42 + 4875: -33,-42 - node: color: '#A4610696' id: HalfTileOverlayGreyscale decals: - 1039: 35,30 - 1040: 36,30 - 1041: 37,30 - 1048: 39,24 - 1049: 40,24 - 1050: 41,24 - 1051: 42,30 - 1052: 43,30 - 1053: 46,30 - 1054: 47,30 - 1061: 44,30 - 1062: 45,30 - 1507: 35,34 - 1508: 36,34 - 1509: 37,34 - 1510: 38,34 - 1511: 39,34 - 1512: 40,34 - 1513: 41,34 - 1514: 42,37 - 1515: 43,37 - 1516: 44,37 - 1517: 45,37 - 1518: 46,37 - 1519: 47,37 + 1029: 35,30 + 1030: 36,30 + 1031: 37,30 + 1038: 39,24 + 1039: 40,24 + 1040: 41,24 + 1041: 42,30 + 1042: 43,30 + 1043: 46,30 + 1044: 47,30 + 1051: 44,30 + 1052: 45,30 + 1497: 35,34 + 1498: 36,34 + 1499: 37,34 + 1500: 38,34 + 1501: 39,34 + 1502: 40,34 + 1503: 41,34 + 1504: 42,37 + 1505: 43,37 + 1506: 44,37 + 1507: 45,37 + 1508: 46,37 + 1509: 47,37 - node: color: '#D4D4D419' id: HalfTileOverlayGreyscale decals: - 1239: -54,31 - 1240: -53,31 - 1241: -52,31 - 1242: -51,31 - 1243: -50,31 - 1244: -49,31 - 1245: -48,31 - 1246: -47,31 - 1247: -46,31 - 1248: -45,31 - 1249: -44,31 - 1250: -43,31 - 1251: -42,31 - 1252: -41,31 - 1253: -40,31 - 1254: -39,31 - 1255: -38,31 - 1256: -37,31 - 1257: -36,31 - 1258: -35,31 - 1314: 17,31 - 1315: 16,31 - 1316: 15,31 - 1317: 14,31 - 1318: 13,31 - 1319: 12,31 - 1320: 11,31 - 1321: 9,31 - 1322: 8,31 - 1323: 7,31 - 1324: 5,31 - 1325: 4,31 - 1326: 3,31 - 1327: 2,31 - 1328: 1,31 - 1329: 0,31 - 1330: -1,31 - 1331: -2,31 - 1332: -3,31 + 1229: -54,31 + 1230: -53,31 + 1231: -52,31 + 1232: -51,31 + 1233: -50,31 + 1234: -49,31 + 1235: -48,31 + 1236: -47,31 + 1237: -46,31 + 1238: -45,31 + 1239: -44,31 + 1240: -43,31 + 1241: -42,31 + 1242: -41,31 + 1243: -40,31 + 1244: -39,31 + 1245: -38,31 + 1246: -37,31 + 1247: -36,31 + 1248: -35,31 + 1304: 17,31 + 1305: 16,31 + 1306: 15,31 + 1307: 14,31 + 1308: 13,31 + 1309: 12,31 + 1310: 11,31 + 1311: 9,31 + 1312: 8,31 + 1313: 7,31 + 1314: 5,31 + 1315: 4,31 + 1316: 3,31 + 1317: 2,31 + 1318: 1,31 + 1319: 0,31 + 1320: -1,31 + 1321: -2,31 + 1322: -3,31 - node: color: '#D4D4D433' id: HalfTileOverlayGreyscale decals: - 770: -11,-25 - 771: -10,-25 - 772: -9,-25 - 773: -8,-25 - 774: -7,-25 - 809: -16,-3 - 810: -14,-3 - 811: -12,-3 - 812: -11,-3 - 817: 17,-3 - 818: 18,-3 - 819: 20,-3 - 820: 21,-3 - 821: 23,-3 - 822: 24,-3 - 823: 25,-3 - 824: 26,-3 - 863: 22,-31 - 864: 23,-31 - 865: 24,-31 - 899: 35,4 - 900: 36,4 - 901: 37,4 - 902: 38,4 - 903: 39,4 - 904: 40,4 - 905: 41,4 - 906: 42,4 - 907: 43,4 - 908: 44,4 - 909: 45,4 - 910: 46,4 - 911: 47,4 - 912: 48,4 - 913: 49,4 - 914: 50,4 - 915: 51,4 - 916: 52,4 - 917: 53,4 - 918: 55,4 - 919: 56,4 - 920: 57,4 - 921: 58,4 - 922: 59,4 - 923: 60,4 - 924: 61,4 - 925: 62,4 - 926: 63,4 - 927: 64,4 - 928: 65,4 - 929: 66,4 - 930: 67,4 - 931: 68,4 - 932: 69,4 + 760: -11,-25 + 761: -10,-25 + 762: -9,-25 + 763: -8,-25 + 764: -7,-25 + 799: -16,-3 + 800: -14,-3 + 801: -12,-3 + 802: -11,-3 + 807: 17,-3 + 808: 18,-3 + 809: 20,-3 + 810: 21,-3 + 811: 23,-3 + 812: 24,-3 + 813: 25,-3 + 814: 26,-3 + 853: 22,-31 + 854: 23,-31 + 855: 24,-31 + 889: 35,4 + 890: 36,4 + 891: 37,4 + 892: 38,4 + 893: 39,4 + 894: 40,4 + 895: 41,4 + 896: 42,4 + 897: 43,4 + 898: 44,4 + 899: 45,4 + 900: 46,4 + 901: 47,4 + 902: 48,4 + 903: 49,4 + 904: 50,4 + 905: 51,4 + 906: 52,4 + 907: 53,4 + 908: 55,4 + 909: 56,4 + 910: 57,4 + 911: 58,4 + 912: 59,4 + 913: 60,4 + 914: 61,4 + 915: 62,4 + 916: 63,4 + 917: 64,4 + 918: 65,4 + 919: 66,4 + 920: 67,4 + 921: 68,4 + 922: 69,4 - node: color: '#DE3A3A96' id: HalfTileOverlayGreyscale @@ -4515,45 +4515,45 @@ entities: 344: 44,-3 345: 45,-3 346: 46,-3 - 391: 34,-7 - 504: -32,27 - 505: -31,27 - 506: -30,27 - 507: -28,27 - 508: -27,27 - 509: -26,27 - 519: -29,26 - 1208: -64,51 - 1209: -63,51 - 1210: -61,51 - 1463: 36,51 - 1464: 37,51 - 1602: 60,-19 - 1603: 61,-19 - 1604: 62,-19 + 383: 34,-7 + 494: -32,27 + 495: -31,27 + 496: -30,27 + 497: -28,27 + 498: -27,27 + 499: -26,27 + 509: -29,26 + 1198: -64,51 + 1199: -63,51 + 1200: -61,51 + 1453: 36,51 + 1454: 37,51 + 1592: 60,-19 + 1593: 61,-19 + 1594: 62,-19 - node: color: '#EFB34196' id: HalfTileOverlayGreyscale decals: - 603: -18,45 - 604: -17,45 - 605: -16,45 - 606: -15,45 - 607: -14,45 - 608: -13,45 - 609: -12,45 - 610: -11,45 - 611: -10,45 + 593: -18,45 + 594: -17,45 + 595: -16,45 + 596: -15,45 + 597: -14,45 + 598: -13,45 + 599: -12,45 + 600: -11,45 + 601: -10,45 - node: color: '#0E7F1BFF' id: HalfTileOverlayGreyscale180 decals: - 4983: 43,-17 + 4961: 43,-17 - node: color: '#1861D5FF' id: HalfTileOverlayGreyscale180 decals: - 4981: 37,-17 + 4959: 37,-17 - node: color: '#334E6DC8' id: HalfTileOverlayGreyscale180 @@ -4591,193 +4591,193 @@ entities: 305: -49,-33 306: -51,-33 307: -53,-33 - 1498: -43,-33 - 4883: -33,-45 - 4884: -34,-45 - 4885: -35,-45 + 1488: -43,-33 + 4870: -33,-45 + 4871: -34,-45 + 4872: -35,-45 - node: color: '#951710FF' id: HalfTileOverlayGreyscale180 decals: - 4982: 40,-17 + 4960: 40,-17 - node: color: '#A4610696' id: HalfTileOverlayGreyscale180 decals: - 1036: 35,23 - 1037: 36,23 - 1038: 37,23 - 1055: 47,26 - 1056: 46,26 - 1520: 44,32 - 1521: 45,32 - 1522: 43,32 - 1523: 42,32 - 1524: 41,32 - 1525: 40,32 - 1526: 39,32 - 1527: 38,32 - 1528: 37,32 - 1529: 36,32 - 1530: 35,32 - 1531: 46,32 - 1532: 47,32 + 1026: 35,23 + 1027: 36,23 + 1028: 37,23 + 1045: 47,26 + 1046: 46,26 + 1510: 44,32 + 1511: 45,32 + 1512: 43,32 + 1513: 42,32 + 1514: 41,32 + 1515: 40,32 + 1516: 39,32 + 1517: 38,32 + 1518: 37,32 + 1519: 36,32 + 1520: 35,32 + 1521: 46,32 + 1522: 47,32 - node: color: '#D381C996' id: HalfTileOverlayGreyscale180 decals: - 959: 21,66 - 960: 22,66 - 974: 23,66 - 975: 24,66 + 949: 21,66 + 950: 22,66 + 964: 23,66 + 965: 24,66 - node: color: '#D4D4D419' id: HalfTileOverlayGreyscale180 decals: - 1170: -25,29 - 1171: -26,29 - 1172: -27,29 - 1173: -28,29 - 1174: -29,29 - 1175: -30,29 - 1176: -31,29 - 1177: -32,29 - 1178: -33,29 - 1179: -36,29 - 1180: -37,29 - 1181: -38,29 - 1182: -39,29 - 1183: -42,29 - 1184: -43,29 - 1185: -44,29 - 1186: -45,29 - 1187: -46,29 - 1188: -48,29 - 1189: -49,29 - 1190: -50,29 - 1191: -51,29 - 1192: -52,29 - 1193: -53,29 - 1194: -54,29 - 1195: -56,29 - 1196: -57,29 - 1276: -21,29 - 1277: -20,29 - 1278: -19,29 - 1279: -18,29 - 1280: -17,29 - 1281: -16,29 - 1282: -15,29 - 1283: -14,29 - 1284: -13,29 - 1285: -12,29 - 1286: -11,29 - 1287: -10,29 - 1288: -9,29 - 1289: -8,29 - 1290: -5,29 - 1291: -3,30 - 1292: -2,30 - 1293: -1,30 - 1294: 0,30 - 1295: 1,30 - 1296: 2,30 - 1297: 3,30 - 1298: 4,30 - 1299: 5,30 - 1300: 6,30 - 1301: 7,30 - 1302: 8,30 - 1303: 9,30 - 1304: 10,30 - 1305: 11,30 - 1306: 12,30 - 1307: 13,30 - 1308: 14,30 - 1309: 15,30 - 1310: 16,30 - 1311: 17,30 - 1348: -3,49 - 1349: -2,49 - 1350: -1,49 - 1351: 0,49 - 1352: 1,49 - 1353: 2,49 - 1354: 4,49 - 1355: 5,49 - 1356: 6,49 - 1357: 7,49 - 1358: 8,49 - 1359: 9,49 - 1360: 10,49 - 1361: 11,49 - 1362: 12,49 - 1363: 13,49 - 1364: 11,49 - 1365: 13,49 - 1366: 14,49 - 1367: 15,49 - 1368: 16,49 - 1369: 17,49 - 1370: 18,49 - 1371: 19,49 - 1372: 21,49 - 1373: 22,49 - 1374: 23,49 - 1375: 25,49 - 1376: 26,49 - 1377: 24,49 - 1378: 27,49 - 1379: 29,49 - 1380: 28,49 - 1381: 20,49 + 1160: -25,29 + 1161: -26,29 + 1162: -27,29 + 1163: -28,29 + 1164: -29,29 + 1165: -30,29 + 1166: -31,29 + 1167: -32,29 + 1168: -33,29 + 1169: -36,29 + 1170: -37,29 + 1171: -38,29 + 1172: -39,29 + 1173: -42,29 + 1174: -43,29 + 1175: -44,29 + 1176: -45,29 + 1177: -46,29 + 1178: -48,29 + 1179: -49,29 + 1180: -50,29 + 1181: -51,29 + 1182: -52,29 + 1183: -53,29 + 1184: -54,29 + 1185: -56,29 + 1186: -57,29 + 1266: -21,29 + 1267: -20,29 + 1268: -19,29 + 1269: -18,29 + 1270: -17,29 + 1271: -16,29 + 1272: -15,29 + 1273: -14,29 + 1274: -13,29 + 1275: -12,29 + 1276: -11,29 + 1277: -10,29 + 1278: -9,29 + 1279: -8,29 + 1280: -5,29 + 1281: -3,30 + 1282: -2,30 + 1283: -1,30 + 1284: 0,30 + 1285: 1,30 + 1286: 2,30 + 1287: 3,30 + 1288: 4,30 + 1289: 5,30 + 1290: 6,30 + 1291: 7,30 + 1292: 8,30 + 1293: 9,30 + 1294: 10,30 + 1295: 11,30 + 1296: 12,30 + 1297: 13,30 + 1298: 14,30 + 1299: 15,30 + 1300: 16,30 + 1301: 17,30 + 1338: -3,49 + 1339: -2,49 + 1340: -1,49 + 1341: 0,49 + 1342: 1,49 + 1343: 2,49 + 1344: 4,49 + 1345: 5,49 + 1346: 6,49 + 1347: 7,49 + 1348: 8,49 + 1349: 9,49 + 1350: 10,49 + 1351: 11,49 + 1352: 12,49 + 1353: 13,49 + 1354: 11,49 + 1355: 13,49 + 1356: 14,49 + 1357: 15,49 + 1358: 16,49 + 1359: 17,49 + 1360: 18,49 + 1361: 19,49 + 1362: 21,49 + 1363: 22,49 + 1364: 23,49 + 1365: 25,49 + 1366: 26,49 + 1367: 24,49 + 1368: 27,49 + 1369: 29,49 + 1370: 28,49 + 1371: 20,49 - node: color: '#D4D4D433' id: HalfTileOverlayGreyscale180 decals: - 759: -4,-26 - 760: -3,-26 - 761: 17,-26 - 762: 18,-26 - 763: -8,-28 - 764: -9,-28 - 765: -10,-28 - 766: -11,-28 - 792: -7,-5 - 793: -9,-5 - 794: -10,-5 - 795: -11,-5 - 796: -13,-5 - 797: -14,-5 - 798: -15,-5 - 799: -16,-5 - 800: -17,-5 - 801: -19,-5 - 802: -22,-5 - 803: -23,-5 - 804: -24,-5 - 805: -40,-5 - 829: 28,-5 - 830: 27,-5 - 831: 26,-5 - 832: 25,-5 - 833: 24,-5 - 834: 23,-5 - 835: 22,-5 - 836: 21,-5 - 866: 24,-36 - 867: 23,-36 - 868: 22,-36 - 933: 65,2 - 934: 66,2 - 935: 67,2 - 936: 68,2 - 937: 69,2 + 749: -4,-26 + 750: -3,-26 + 751: 17,-26 + 752: 18,-26 + 753: -8,-28 + 754: -9,-28 + 755: -10,-28 + 756: -11,-28 + 782: -7,-5 + 783: -9,-5 + 784: -10,-5 + 785: -11,-5 + 786: -13,-5 + 787: -14,-5 + 788: -15,-5 + 789: -16,-5 + 790: -17,-5 + 791: -19,-5 + 792: -22,-5 + 793: -23,-5 + 794: -24,-5 + 795: -40,-5 + 819: 28,-5 + 820: 27,-5 + 821: 26,-5 + 822: 25,-5 + 823: 24,-5 + 824: 23,-5 + 825: 22,-5 + 826: 21,-5 + 856: 24,-36 + 857: 23,-36 + 858: 22,-36 + 923: 65,2 + 924: 66,2 + 925: 67,2 + 926: 68,2 + 927: 69,2 - node: color: '#D58C18FF' id: HalfTileOverlayGreyscale180 decals: - 4984: 46,-17 + 4962: 46,-17 - node: color: '#DE3A3A96' id: HalfTileOverlayGreyscale180 @@ -4788,179 +4788,179 @@ entities: 333: 44,-1 334: 45,-1 335: 46,-1 - 378: 45,-17 - 381: 42,-17 - 382: 41,-17 - 384: 39,-17 - 385: 38,-17 - 510: -32,25 - 511: -31,25 - 512: -30,25 - 513: -29,25 - 514: -28,25 - 515: -27,25 - 516: -26,25 - 1215: -63,48 - 1219: -62,48 - 1466: 36,48 - 1467: 37,48 - 1605: 60,-23 - 1606: 61,-23 - 1607: 62,-23 - 4980: 44,-17 - 4986: 34,-13 + 374: 45,-17 + 375: 42,-17 + 376: 41,-17 + 377: 39,-17 + 378: 38,-17 + 500: -32,25 + 501: -31,25 + 502: -30,25 + 503: -29,25 + 504: -28,25 + 505: -27,25 + 506: -26,25 + 1205: -63,48 + 1209: -62,48 + 1456: 36,48 + 1457: 37,48 + 1595: 60,-23 + 1596: 61,-23 + 1597: 62,-23 + 4958: 44,-17 + 4964: 34,-13 - node: color: '#EFB34196' id: HalfTileOverlayGreyscale180 decals: - 612: -10,43 - 613: -11,43 - 614: -12,43 - 615: -13,43 - 616: -14,43 - 617: -15,43 - 618: -16,43 - 619: -17,43 - 620: -18,43 + 602: -10,43 + 603: -11,43 + 604: -12,43 + 605: -13,43 + 606: -14,43 + 607: -15,43 + 608: -16,43 + 609: -17,43 + 610: -18,43 - node: color: '#334E6DC8' id: HalfTileOverlayGreyscale270 decals: - 1229: -63,54 - 1230: -63,53 - 1539: 18,-60 - 1540: 17,-61 - 1541: 17,-62 - 1542: 18,-63 + 1219: -63,54 + 1220: -63,53 + 1529: 18,-60 + 1530: 17,-61 + 1531: 17,-62 + 1532: 18,-63 - node: color: '#52B4E996' id: HalfTileOverlayGreyscale270 decals: 227: -26,-26 - 4961: -36,-37 - 4962: -35,-37 - 4963: -34,-37 - 4964: -35,-36 - 4965: -35,-38 + 4948: -36,-37 + 4949: -35,-37 + 4950: -34,-37 + 4951: -35,-36 + 4952: -35,-38 - node: color: '#9FED5896' id: HalfTileOverlayGreyscale270 decals: - 1499: -8,-60 - 1500: -9,-61 - 1501: -9,-62 - 1502: -8,-63 + 1489: -8,-60 + 1490: -9,-61 + 1491: -9,-62 + 1492: -8,-63 - node: color: '#A4610696' id: HalfTileOverlayGreyscale270 decals: - 1057: 40,21 - 1058: 40,18 - 1059: 40,19 - 1060: 40,20 - 1070: 41,17 - 1071: 41,16 - 1072: 41,15 - 1073: 41,14 - 1074: 41,13 - 1075: 41,12 + 1047: 40,21 + 1048: 40,18 + 1049: 40,19 + 1050: 40,20 + 1060: 41,17 + 1061: 41,16 + 1062: 41,15 + 1063: 41,14 + 1064: 41,13 + 1065: 41,12 - node: color: '#D381C996' id: HalfTileOverlayGreyscale270 decals: - 947: 18,54 - 948: 18,57 - 949: 18,58 - 950: 18,59 - 951: 18,60 - 952: 18,61 - 953: 18,62 - 954: 18,63 - 955: 18,64 - 956: 18,65 - 957: 18,66 + 937: 18,54 + 938: 18,57 + 939: 18,58 + 940: 18,59 + 941: 18,60 + 942: 18,61 + 943: 18,62 + 944: 18,63 + 945: 18,64 + 946: 18,65 + 947: 18,66 - node: color: '#D4D4D40F' id: HalfTileOverlayGreyscale270 decals: - 4722: -28,18 - 4723: -28,17 + 4709: -28,18 + 4710: -28,17 - node: color: '#D4D4D419' id: HalfTileOverlayGreyscale270 decals: - 1142: -24,-1 - 1143: -24,0 - 1144: -24,1 - 1145: -24,2 - 1146: -24,3 - 1147: -24,4 - 1148: -24,5 - 1149: -24,6 - 1150: -24,7 - 1151: -24,8 - 1152: -24,10 - 1153: -24,11 - 1154: -24,12 - 1155: -24,13 - 1156: -24,14 - 1157: -24,15 - 1158: -24,16 - 1159: -24,18 - 1160: -24,19 - 1161: -24,20 - 1162: -24,21 - 1163: -24,22 - 1164: -24,23 - 1165: -24,24 - 1166: -24,26 - 1167: -24,27 - 1198: -58,30 - 1199: -58,31 - 1200: -58,32 + 1132: -24,-1 + 1133: -24,0 + 1134: -24,1 + 1135: -24,2 + 1136: -24,3 + 1137: -24,4 + 1138: -24,5 + 1139: -24,6 + 1140: -24,7 + 1141: -24,8 + 1142: -24,10 + 1143: -24,11 + 1144: -24,12 + 1145: -24,13 + 1146: -24,14 + 1147: -24,15 + 1148: -24,16 + 1149: -24,18 + 1150: -24,19 + 1151: -24,20 + 1152: -24,21 + 1153: -24,22 + 1154: -24,23 + 1155: -24,24 + 1156: -24,26 + 1157: -24,27 + 1188: -58,30 + 1189: -58,31 + 1190: -58,32 - node: color: '#D4D4D433' id: HalfTileOverlayGreyscale270 decals: - 728: -7,-30 - 729: -7,-31 - 730: -7,-32 - 731: -7,-36 - 732: -7,-37 - 733: -7,-38 - 734: -7,-39 - 735: -7,-40 - 736: -7,-41 - 737: -7,-45 - 738: -7,-47 - 739: -7,-48 - 740: -7,-49 - 741: -7,-51 - 742: -7,-53 - 743: -7,-54 - 744: -7,-55 - 745: -7,-56 - 746: -7,-57 - 747: -7,-58 - 776: -6,-24 - 777: -6,-23 - 778: -6,-22 - 779: -6,-20 - 780: -6,-19 - 781: -6,-18 - 782: -6,-16 - 783: -6,-15 - 784: -6,-13 - 785: -6,-12 - 786: -6,-11 - 787: -6,-10 - 788: -6,-9 - 789: -6,-8 - 790: -6,-6 - 892: 19,-57 - 893: 19,-56 - 894: 19,-55 - 895: 19,-54 + 718: -7,-30 + 719: -7,-31 + 720: -7,-32 + 721: -7,-36 + 722: -7,-37 + 723: -7,-38 + 724: -7,-39 + 725: -7,-40 + 726: -7,-41 + 727: -7,-45 + 728: -7,-47 + 729: -7,-48 + 730: -7,-49 + 731: -7,-51 + 732: -7,-53 + 733: -7,-54 + 734: -7,-55 + 735: -7,-56 + 736: -7,-57 + 737: -7,-58 + 766: -6,-24 + 767: -6,-23 + 768: -6,-22 + 769: -6,-20 + 770: -6,-19 + 771: -6,-18 + 772: -6,-16 + 773: -6,-15 + 774: -6,-13 + 775: -6,-12 + 776: -6,-11 + 777: -6,-10 + 778: -6,-9 + 779: -6,-8 + 780: -6,-6 + 882: 19,-57 + 883: 19,-56 + 884: 19,-55 + 885: 19,-54 - node: color: '#DE3A3A96' id: HalfTileOverlayGreyscale270 @@ -4979,214 +4979,214 @@ entities: 354: 34,-9 355: 34,-10 356: 34,-11 - 359: 35,-14 - 360: 35,-15 - 361: 36,-16 - 362: 36,-17 - 518: -32,26 - 1216: -64,49 - 1217: -64,50 - 1461: 35,49 - 1462: 35,50 - 4987: 34,-13 - 4988: 34,-12 + 357: 35,-14 + 358: 35,-15 + 359: 36,-16 + 360: 36,-17 + 508: -32,26 + 1206: -64,49 + 1207: -64,50 + 1451: 35,49 + 1452: 35,50 + 4965: 34,-13 + 4966: 34,-12 - node: color: '#EFB34196' id: HalfTileOverlayGreyscale270 decals: - 583: -21,54 - 584: -21,53 - 585: -21,52 - 586: -21,51 - 587: -21,50 - 588: -21,49 - 589: -21,48 - 590: -21,47 - 591: -21,46 - 592: -21,45 - 593: -21,44 - 594: -21,43 - 595: -21,42 - 596: -21,41 - 597: -21,40 - 598: -21,39 - 599: -21,38 - 600: -21,37 - 601: -21,36 - 602: -21,35 + 573: -21,54 + 574: -21,53 + 575: -21,52 + 576: -21,51 + 577: -21,50 + 578: -21,49 + 579: -21,48 + 580: -21,47 + 581: -21,46 + 582: -21,45 + 583: -21,44 + 584: -21,43 + 585: -21,42 + 586: -21,41 + 587: -21,40 + 588: -21,39 + 589: -21,38 + 590: -21,37 + 591: -21,36 + 592: -21,35 - node: color: '#334E6DC8' id: HalfTileOverlayGreyscale90 decals: - 1231: -57,54 - 1232: -57,53 - 1535: 23,-61 - 1536: 23,-62 - 1537: 22,-63 - 1538: 22,-60 + 1221: -57,54 + 1222: -57,53 + 1525: 23,-61 + 1526: 23,-62 + 1527: 22,-63 + 1528: 22,-60 - node: color: '#52B4E996' id: HalfTileOverlayGreyscale90 decals: - 4966: -36,-37 - 4967: -35,-36 - 4968: -35,-37 - 4969: -35,-38 - 4970: -34,-37 + 4953: -36,-37 + 4954: -35,-36 + 4955: -35,-37 + 4956: -35,-38 + 4957: -34,-37 - node: color: '#9FED5896' id: HalfTileOverlayGreyscale90 decals: - 1503: -4,-60 - 1504: -3,-61 - 1505: -3,-62 - 1506: -4,-63 + 1493: -4,-60 + 1494: -3,-61 + 1495: -3,-62 + 1496: -4,-63 - node: color: '#A4610696' id: HalfTileOverlayGreyscale90 decals: - 1063: 45,25 - 1064: 45,24 - 1065: 45,21 - 1066: 45,20 - 1067: 45,19 - 1068: 44,17 - 1069: 44,16 - 1076: 43,12 - 1077: 43,14 - 1078: 43,13 - 1079: 43,15 - 1625: 45,22 - 1626: 45,23 + 1053: 45,25 + 1054: 45,24 + 1055: 45,21 + 1056: 45,20 + 1057: 45,19 + 1058: 44,17 + 1059: 44,16 + 1066: 43,12 + 1067: 43,14 + 1068: 43,13 + 1069: 43,15 + 1614: 45,22 + 1615: 45,23 - node: color: '#D381C996' id: HalfTileOverlayGreyscale90 decals: - 938: 20,56 - 939: 20,57 - 940: 20,58 - 941: 20,59 - 942: 20,61 - 943: 20,62 - 944: 20,63 - 945: 20,64 - 946: 20,65 - 977: 24,67 - 978: 24,68 - 979: 24,70 + 928: 20,56 + 929: 20,57 + 930: 20,58 + 931: 20,59 + 932: 20,61 + 933: 20,62 + 934: 20,63 + 935: 20,64 + 936: 20,65 + 967: 24,67 + 968: 24,68 + 969: 24,70 - node: color: '#D4D4D405' id: HalfTileOverlayGreyscale90 decals: - 4724: -29,18 - 4725: -29,17 + 4711: -29,18 + 4712: -29,17 - node: color: '#D4D4D419' id: HalfTileOverlayGreyscale90 decals: - 1124: -22,5 - 1125: -22,7 - 1126: -22,8 - 1127: -22,9 - 1128: -22,10 - 1129: -22,11 - 1130: -22,12 - 1131: -22,13 - 1132: -22,14 - 1133: -22,15 - 1134: -22,17 - 1135: -22,20 - 1136: -22,22 - 1137: -22,23 - 1138: -22,24 - 1139: -22,25 - 1140: -22,26 - 1141: -22,27 - 1202: -56,32 - 1203: -56,33 - 1333: -4,33 - 1334: -4,34 - 1335: -4,36 - 1336: -4,37 - 1337: -4,38 - 1338: -4,39 - 1339: -4,40 - 1340: -4,41 - 1341: -4,42 - 1342: -4,44 - 1343: -4,45 - 1344: -4,46 - 1345: -4,47 - 1346: -4,48 - 4720: -28,18 - 4721: -28,17 + 1114: -22,5 + 1115: -22,7 + 1116: -22,8 + 1117: -22,9 + 1118: -22,10 + 1119: -22,11 + 1120: -22,12 + 1121: -22,13 + 1122: -22,14 + 1123: -22,15 + 1124: -22,17 + 1125: -22,20 + 1126: -22,22 + 1127: -22,23 + 1128: -22,24 + 1129: -22,25 + 1130: -22,26 + 1131: -22,27 + 1192: -56,32 + 1193: -56,33 + 1323: -4,33 + 1324: -4,34 + 1325: -4,36 + 1326: -4,37 + 1327: -4,38 + 1328: -4,39 + 1329: -4,40 + 1330: -4,41 + 1331: -4,42 + 1332: -4,44 + 1333: -4,45 + 1334: -4,46 + 1335: -4,47 + 1336: -4,48 + 4707: -28,18 + 4708: -28,17 - node: color: '#D4D4D433' id: HalfTileOverlayGreyscale90 decals: - 748: -5,-58 - 749: -5,-57 - 750: -5,-56 - 751: -5,-55 - 752: -5,-54 - 753: -5,-53 - 754: -5,-51 - 755: -5,-50 - 756: -5,-28 - 757: -5,-27 - 807: -41,-11 - 826: 29,-3 - 827: 29,-4 - 838: 20,-6 - 839: 20,-8 - 840: 20,-9 - 841: 20,-10 - 842: 20,-11 - 843: 20,-12 - 844: 20,-14 - 845: 20,-15 - 846: 20,-16 - 849: 21,-18 - 850: 21,-19 - 851: 21,-20 - 852: 21,-21 - 853: 21,-22 - 854: 21,-23 - 855: 21,-24 - 856: 21,-25 - 857: 21,-26 - 858: 21,-27 - 859: 21,-28 - 860: 21,-29 - 861: 21,-30 - 870: 21,-38 - 871: 21,-39 - 872: 21,-40 - 873: 21,-41 - 874: 21,-42 - 875: 21,-43 - 876: 21,-44 - 877: 21,-45 - 878: 21,-46 - 879: 21,-47 - 880: 21,-48 - 881: 21,-49 - 882: 21,-50 - 883: 21,-51 - 884: 21,-52 - 885: 21,-53 - 886: 21,-54 - 887: 21,-55 - 888: 21,-56 - 889: 21,-57 - 896: 29,-1 - 897: 29,0 - 898: 29,1 + 738: -5,-58 + 739: -5,-57 + 740: -5,-56 + 741: -5,-55 + 742: -5,-54 + 743: -5,-53 + 744: -5,-51 + 745: -5,-50 + 746: -5,-28 + 747: -5,-27 + 797: -41,-11 + 816: 29,-3 + 817: 29,-4 + 828: 20,-6 + 829: 20,-8 + 830: 20,-9 + 831: 20,-10 + 832: 20,-11 + 833: 20,-12 + 834: 20,-14 + 835: 20,-15 + 836: 20,-16 + 839: 21,-18 + 840: 21,-19 + 841: 21,-20 + 842: 21,-21 + 843: 21,-22 + 844: 21,-23 + 845: 21,-24 + 846: 21,-25 + 847: 21,-26 + 848: 21,-27 + 849: 21,-28 + 850: 21,-29 + 851: 21,-30 + 860: 21,-38 + 861: 21,-39 + 862: 21,-40 + 863: 21,-41 + 864: 21,-42 + 865: 21,-43 + 866: 21,-44 + 867: 21,-45 + 868: 21,-46 + 869: 21,-47 + 870: 21,-48 + 871: 21,-49 + 872: 21,-50 + 873: 21,-51 + 874: 21,-52 + 875: 21,-53 + 876: 21,-54 + 877: 21,-55 + 878: 21,-56 + 879: 21,-57 + 886: 29,-1 + 887: 29,0 + 888: 29,1 - node: color: '#D58C18FF' id: HalfTileOverlayGreyscale90 decals: - 4985: 46,-17 + 4963: 46,-17 - node: color: '#DE3A3A96' id: HalfTileOverlayGreyscale90 @@ -5196,279 +5196,279 @@ entities: 327: 47,1 328: 47,0 329: 47,-1 - 363: 46,-11 - 364: 46,-10 - 365: 46,-9 - 366: 46,-8 - 367: 46,-7 - 368: 47,-6 - 369: 47,-5 - 370: 47,-4 - 517: -26,26 - 1212: -61,50 - 1213: -61,49 - 1455: 38,51 - 1456: 38,50 - 1457: 38,49 - 1608: 46,-16 - 1609: 46,-13 + 361: 46,-11 + 362: 46,-10 + 363: 46,-9 + 364: 46,-8 + 365: 46,-7 + 366: 47,-6 + 367: 47,-5 + 368: 47,-4 + 507: -26,26 + 1202: -61,50 + 1203: -61,49 + 1445: 38,51 + 1446: 38,50 + 1447: 38,49 + 1598: 46,-16 + 1599: 46,-13 - node: color: '#EFB34196' id: HalfTileOverlayGreyscale90 decals: - 566: -19,35 - 567: -19,36 - 568: -19,37 - 569: -19,38 - 570: -19,39 - 571: -19,40 - 572: -19,41 - 573: -19,42 - 574: -19,46 - 575: -19,47 - 576: -19,48 - 577: -19,49 - 578: -19,50 - 579: -19,51 - 580: -19,52 - 581: -19,53 - 582: -19,54 + 556: -19,35 + 557: -19,36 + 558: -19,37 + 559: -19,38 + 560: -19,39 + 561: -19,40 + 562: -19,41 + 563: -19,42 + 564: -19,46 + 565: -19,47 + 566: -19,48 + 567: -19,49 + 568: -19,50 + 569: -19,51 + 570: -19,52 + 571: -19,53 + 572: -19,54 - node: color: '#EFB34196' id: LoadingArea decals: - 489: 75,10 - 490: 76,10 + 479: 75,10 + 480: 76,10 - node: angle: 3.141592653589793 rad color: '#EFB34196' id: LoadingArea decals: - 491: 82,10 - 492: 83,10 + 481: 82,10 + 482: 83,10 - node: angle: 4.71238898038469 rad color: '#EFB34196' id: LoadingArea decals: - 1047: 36,29 - 1204: -64,46 - 1205: -64,40 - 1206: -64,38 - 1220: -64,48 + 1037: 36,29 + 1194: -64,46 + 1195: -64,40 + 1196: -64,38 + 1210: -64,48 - node: color: '#334E6DC8' id: LoadingAreaGreyscale decals: - 498: -5,-2 + 488: -5,-2 - node: angle: 3.141592653589793 rad color: '#334E6DC8' id: LoadingAreaGreyscale decals: - 499: -9,-2 + 489: -9,-2 - node: color: '#52B4E996' id: MiniTileCheckerAOverlay decals: - 3621: 26,-35 - 3622: 27,-35 - 3623: 28,-35 - 3624: 29,-35 - 3625: 30,-35 - 3626: 30,-34 - 3627: 29,-34 - 3628: 28,-34 - 3629: 27,-34 - 3630: 26,-34 - 3631: 26,-33 - 3632: 26,-32 - 3633: 27,-32 - 3634: 28,-32 - 3635: 29,-32 - 3636: 30,-32 - 3637: 30,-33 - 3638: 29,-33 - 3639: 28,-33 - 3640: 27,-33 + 3608: 26,-35 + 3609: 27,-35 + 3610: 28,-35 + 3611: 29,-35 + 3612: 30,-35 + 3613: 30,-34 + 3614: 29,-34 + 3615: 28,-34 + 3616: 27,-34 + 3617: 26,-34 + 3618: 26,-33 + 3619: 26,-32 + 3620: 27,-32 + 3621: 28,-32 + 3622: 29,-32 + 3623: 30,-32 + 3624: 30,-33 + 3625: 29,-33 + 3626: 28,-33 + 3627: 27,-33 - node: color: '#334E6DC8' id: MiniTileCheckerBOverlay decals: - 4687: -33,18 - 4688: -33,17 - 4689: -32,17 - 4690: -31,17 - 4691: -31,18 - 4692: -32,18 + 4674: -33,18 + 4675: -33,17 + 4676: -32,17 + 4677: -31,17 + 4678: -31,18 + 4679: -32,18 - node: color: '#FFFFFFFF' id: MiniTileCheckerBOverlay decals: - 3641: 26,-32 - 3642: 26,-33 - 3643: 26,-34 - 3644: 26,-35 - 3645: 27,-35 - 3646: 28,-35 - 3647: 29,-35 - 3648: 30,-35 - 3649: 30,-34 - 3650: 30,-33 - 3651: 30,-32 - 3652: 29,-32 - 3653: 28,-32 - 3654: 27,-32 - 3655: 27,-33 - 3656: 27,-34 - 3657: 28,-34 - 3658: 28,-33 - 3659: 29,-33 - 3660: 29,-34 + 3628: 26,-32 + 3629: 26,-33 + 3630: 26,-34 + 3631: 26,-35 + 3632: 27,-35 + 3633: 28,-35 + 3634: 29,-35 + 3635: 30,-35 + 3636: 30,-34 + 3637: 30,-33 + 3638: 30,-32 + 3639: 29,-32 + 3640: 28,-32 + 3641: 27,-32 + 3642: 27,-33 + 3643: 27,-34 + 3644: 28,-34 + 3645: 28,-33 + 3646: 29,-33 + 3647: 29,-34 - node: color: '#FFFFFFFF' id: MiniTileDarkCornerNe decals: - 3445: 46,36 + 3432: 46,36 - node: color: '#FFFFFFFF' id: MiniTileDarkCornerNw decals: - 3443: 43,36 + 3430: 43,36 - node: color: '#FFFFFFFF' id: MiniTileDarkCornerSe decals: - 3444: 46,33 + 3431: 46,33 - node: color: '#FFFFFFFF' id: MiniTileDarkCornerSw decals: - 3442: 43,33 + 3429: 43,33 - node: color: '#FFFFFFFF' id: MiniTileDarkInnerSw decals: - 3472: -24,-18 + 3459: -24,-18 - node: color: '#FFFFFFFF' id: MiniTileDarkLineE decals: - 3448: 46,35 - 3449: 46,34 + 3435: 46,35 + 3436: 46,34 - node: color: '#FFFFFFFF' id: MiniTileDarkLineN decals: - 3446: 44,36 - 3447: 45,36 + 3433: 44,36 + 3434: 45,36 - node: color: '#FFFFFFFF' id: MiniTileDarkLineS decals: - 3450: 44,33 - 3451: 45,33 - 3473: -25,-18 - 3474: -26,-18 - 3475: -27,-18 - 3483: 25,-1 - 3484: 25,-1 + 3437: 44,33 + 3438: 45,33 + 3460: -25,-18 + 3461: -26,-18 + 3462: -27,-18 + 3470: 25,-1 + 3471: 25,-1 - node: color: '#FFFFFFFF' id: MiniTileDarkLineW decals: - 3452: 43,34 - 3453: 43,35 - 3469: -24,-21 - 3470: -24,-20 - 3471: -24,-19 + 3439: 43,34 + 3440: 43,35 + 3456: -24,-21 + 3457: -24,-20 + 3458: -24,-19 - node: color: '#666C6CA4' id: MiniTileDiagonalCheckerBOverlay decals: - 4295: 58,-37 - 4296: 58,-38 - 4297: 59,-38 - 4298: 59,-37 + 4282: 58,-37 + 4283: 58,-38 + 4284: 59,-38 + 4285: 59,-37 - node: color: '#FFFFFFFF' id: MiniTileSteelEndE decals: - 3455: 41,-9 + 3442: 41,-9 - node: color: '#FFFFFFFF' id: MiniTileSteelEndW decals: - 3454: 39,-9 + 3441: 39,-9 - node: color: '#FFFFFFFF' id: MiniTileSteelLineN decals: - 3456: 40,-9 + 3443: 40,-9 - node: color: '#FFFFFFFF' id: MiniTileSteelLineS decals: - 3457: 40,-9 + 3444: 40,-9 - node: color: '#52B4E996' id: MiniTileWhiteCornerNe decals: - 4894: -40,-43 + 4881: -40,-43 - node: zIndex: 1 color: '#52B4E996' id: MiniTileWhiteCornerNe decals: - 4907: -42,-40 + 4894: -42,-40 - node: color: '#52B4E996' id: MiniTileWhiteCornerNw decals: - 4895: -44,-40 + 4882: -44,-40 - node: color: '#52B4E996' id: MiniTileWhiteCornerSe decals: - 4892: -40,-45 + 4879: -40,-45 - node: color: '#52B4E996' id: MiniTileWhiteCornerSw decals: - 4893: -44,-45 + 4880: -44,-45 - node: color: '#52B4E996' id: MiniTileWhiteInnerNe decals: - 4896: -42,-43 + 4883: -42,-43 - node: color: '#52B4E996' id: MiniTileWhiteLineE decals: - 4902: -42,-41 - 4903: -42,-42 - 4908: -40,-44 + 4889: -42,-41 + 4890: -42,-42 + 4895: -40,-44 - node: color: '#52B4E996' id: MiniTileWhiteLineN decals: - 4900: -43,-40 - 4901: -41,-43 + 4887: -43,-40 + 4888: -41,-43 - node: color: '#52B4E996' id: MiniTileWhiteLineS decals: - 4889: -43,-45 - 4890: -42,-45 - 4891: -41,-45 + 4876: -43,-45 + 4877: -42,-45 + 4878: -41,-45 - node: color: '#52B4E996' id: MiniTileWhiteLineW decals: - 4897: -44,-43 - 4898: -44,-42 - 4899: -44,-41 - 4909: -44,-44 + 4884: -44,-43 + 4885: -44,-42 + 4886: -44,-41 + 4896: -44,-44 - node: color: '#334E6DC8' id: QuarterTileOverlayGreyscale @@ -5525,13 +5525,13 @@ entities: 217: -23,-33 218: -24,-33 231: -26,-34 - 687: 25,10 - 688: 27,10 - 689: 29,10 - 694: 25,6 - 695: 24,7 - 696: 24,9 - 3284: -26,-27 + 677: 25,10 + 678: 27,10 + 679: 29,10 + 684: 25,6 + 685: 24,7 + 686: 24,9 + 3271: -26,-27 - node: color: '#9FED5896' id: QuarterTileOverlayGreyscale @@ -5584,18 +5584,18 @@ entities: color: '#D4D4D433' id: QuarterTileOverlayGreyscale decals: - 768: -11,-28 - 775: -6,-25 - 825: 27,-3 - 891: 19,-58 + 758: -11,-28 + 765: -6,-25 + 815: 27,-3 + 881: 19,-58 - node: color: '#DE3A3A96' id: QuarterTileOverlayGreyscale decals: - 392: 35,-7 - 520: -32,25 - 523: -28,26 - 1465: 38,51 + 384: 35,-7 + 510: -32,25 + 513: -28,26 + 1455: 38,51 - node: color: '#EFB34196' id: QuarterTileOverlayGreyscale @@ -5624,56 +5624,56 @@ entities: 44: 27,0 45: 27,-1 46: 27,-2 - 528: -33,31 - 529: -32,31 - 530: -31,31 - 531: -30,31 - 532: -29,31 - 533: -28,31 - 534: -27,31 - 535: -26,31 - 536: -25,31 - 537: -24,31 - 538: -23,31 - 539: -22,31 - 540: -21,31 - 541: -21,32 - 625: -19,54 - 642: -28,39 - 643: -27,39 - 644: -26,39 - 645: -25,39 - 646: -24,39 - 647: -23,39 - 648: -28,38 - 649: -28,37 - 652: -11,41 - 653: -12,41 - 654: -13,41 - 655: -14,41 - 656: -15,41 - 657: -16,41 - 658: -17,41 - 659: -17,40 - 660: -17,39 - 661: -17,38 - 662: -17,37 - 663: -17,36 - 664: -17,35 - 677: 24,10 - 678: 26,10 - 679: 28,10 - 686: 24,8 - 1404: -6,37 - 1405: -6,36 - 1406: -6,35 - 1407: -6,34 - 1408: -6,33 - 1431: -6,38 - 1432: -6,39 - 1433: -6,40 - 1434: -6,41 - 1435: -6,42 + 518: -33,31 + 519: -32,31 + 520: -31,31 + 521: -30,31 + 522: -29,31 + 523: -28,31 + 524: -27,31 + 525: -26,31 + 526: -25,31 + 527: -24,31 + 528: -23,31 + 529: -22,31 + 530: -21,31 + 531: -21,32 + 615: -19,54 + 632: -28,39 + 633: -27,39 + 634: -26,39 + 635: -25,39 + 636: -24,39 + 637: -23,39 + 638: -28,38 + 639: -28,37 + 642: -11,41 + 643: -12,41 + 644: -13,41 + 645: -14,41 + 646: -15,41 + 647: -16,41 + 648: -17,41 + 649: -17,40 + 650: -17,39 + 651: -17,38 + 652: -17,37 + 653: -17,36 + 654: -17,35 + 667: 24,10 + 668: 26,10 + 669: 28,10 + 676: 24,8 + 1394: -6,37 + 1395: -6,36 + 1396: -6,35 + 1397: -6,34 + 1398: -6,33 + 1421: -6,38 + 1422: -6,39 + 1423: -6,40 + 1424: -6,41 + 1425: -6,42 - node: color: '#52B4E996' id: QuarterTileOverlayGreyscale180 @@ -5698,76 +5698,76 @@ entities: 226: -22,-27 228: -26,-26 229: -27,-26 - 690: 29,9 - 691: 29,7 - 692: 28,6 - 693: 26,6 - 3285: -25,-27 + 680: 29,9 + 681: 29,7 + 682: 28,6 + 683: 26,6 + 3272: -25,-27 - node: color: '#A4610696' id: QuarterTileOverlayGreyscale180 decals: - 1627: 45,26 - 1628: 43,16 + 1616: 45,26 + 1617: 43,16 - node: color: '#D381C996' id: QuarterTileOverlayGreyscale180 decals: - 961: 20,66 - 980: 24,71 + 951: 20,66 + 970: 24,71 - node: color: '#D4D4D419' id: QuarterTileOverlayGreyscale180 decals: - 1169: -22,29 - 1347: -4,49 + 1159: -22,29 + 1337: -4,49 - node: color: '#D4D4D433' id: QuarterTileOverlayGreyscale180 decals: - 758: -5,-26 - 806: -41,-5 - 837: 20,-5 - 869: 21,-36 + 748: -5,-26 + 796: -41,-5 + 827: 20,-5 + 859: 21,-36 - node: color: '#DE3A3A96' id: QuarterTileOverlayGreyscale180 decals: 238: -27,-40 336: 43,-1 - 372: 35,-15 - 373: 36,-17 - 374: 33,-8 - 393: 46,-6 - 524: -26,27 - 525: -30,27 - 1211: -61,51 - 1610: 46,-12 + 369: 35,-15 + 370: 36,-17 + 371: 33,-8 + 385: 46,-6 + 514: -26,27 + 515: -30,27 + 1201: -61,51 + 1600: 46,-12 - node: color: '#EFB34196' id: QuarterTileOverlayGreyscale180 decals: - 622: -19,43 - 650: -24,36 - 651: -23,36 - 665: -17,35 - 666: -16,35 - 667: -15,35 - 668: -14,35 - 669: -13,35 - 670: -13,36 - 671: -13,37 - 672: -13,38 - 673: -12,38 - 674: -11,38 - 680: 29,10 - 681: 29,8 - 682: 29,6 - 683: 27,6 - 684: 25,6 - 685: 24,7 - 1436: -7,43 - 1437: -8,43 + 612: -19,43 + 640: -24,36 + 641: -23,36 + 655: -17,35 + 656: -16,35 + 657: -15,35 + 658: -14,35 + 659: -13,35 + 660: -13,36 + 661: -13,37 + 662: -13,38 + 663: -12,38 + 664: -11,38 + 670: 29,10 + 671: 29,8 + 672: 29,6 + 673: 27,6 + 674: 25,6 + 675: 24,7 + 1426: -7,43 + 1427: -8,43 - node: color: '#52B4E996' id: QuarterTileOverlayGreyscale270 @@ -5782,11 +5782,11 @@ entities: 186: -13,-27 230: -26,-33 232: -26,-34 - 425: 51,-13 - 426: 51,-12 - 1599: 53,-14 - 1600: 52,-14 - 1601: 51,-14 + 415: 51,-13 + 416: 51,-12 + 1589: 53,-14 + 1590: 52,-14 + 1591: 51,-14 - node: color: '#9FED5896' id: QuarterTileOverlayGreyscale270 @@ -5798,35 +5798,35 @@ entities: color: '#A4610696' id: QuarterTileOverlayGreyscale270 decals: - 1629: 44,16 + 1618: 44,16 - node: color: '#D381C996' id: QuarterTileOverlayGreyscale270 decals: - 958: 18,67 - 1013: 11,58 - 1014: 11,57 - 1015: 11,56 - 1016: 11,55 - 1017: 11,54 - 1018: 11,53 - 1019: 12,53 + 948: 18,67 + 1003: 11,58 + 1004: 11,57 + 1005: 11,56 + 1006: 11,55 + 1007: 11,54 + 1008: 11,53 + 1009: 12,53 - node: color: '#D4D4D419' id: QuarterTileOverlayGreyscale270 decals: - 1168: -24,29 - 1312: 18,30 + 1158: -24,29 + 1302: 18,30 - node: color: '#D4D4D433' id: QuarterTileOverlayGreyscale270 decals: - 767: -7,-28 - 769: -11,-27 - 791: -6,-5 - 815: 17,-5 - 816: 18,-6 - 828: 29,-5 + 757: -7,-28 + 759: -11,-27 + 781: -6,-5 + 805: 17,-5 + 806: 18,-6 + 818: 29,-5 - node: color: '#DE3A3A96' id: QuarterTileOverlayGreyscale270 @@ -5863,54 +5863,54 @@ entities: 89: 64,2 237: -25,-40 337: 47,-1 - 375: 47,-6 - 387: 35,-13 - 388: 36,-15 - 389: 34,-8 - 400: 37,-6 - 401: 38,-6 - 402: 39,-6 - 403: 40,-6 - 404: 41,-6 - 405: 42,-6 - 406: 43,-6 - 407: 44,-6 - 408: 44,-7 - 409: 44,-8 - 410: 44,-9 - 411: 44,-10 - 412: 44,-11 - 427: 49,-3 - 428: 50,-3 - 429: 51,-3 - 430: 52,-3 - 431: 53,-3 - 432: 54,-3 - 433: 55,-3 - 434: 56,-3 - 444: 49,-1 - 445: 49,-2 - 446: 58,0 - 447: 58,-1 - 448: 58,-2 - 449: 58,-3 - 450: 59,-3 - 451: 60,-3 - 452: 61,-3 - 453: 62,-3 - 526: -28,27 - 527: -32,27 - 1218: -64,51 + 372: 47,-6 + 379: 35,-13 + 380: 36,-15 + 381: 34,-8 + 392: 37,-6 + 393: 38,-6 + 394: 39,-6 + 395: 40,-6 + 396: 41,-6 + 397: 42,-6 + 398: 43,-6 + 399: 44,-6 + 400: 44,-7 + 401: 44,-8 + 402: 44,-9 + 403: 44,-10 + 404: 44,-11 + 417: 49,-3 + 418: 50,-3 + 419: 51,-3 + 420: 52,-3 + 421: 53,-3 + 422: 54,-3 + 423: 55,-3 + 424: 56,-3 + 434: 49,-1 + 435: 49,-2 + 436: 58,0 + 437: 58,-1 + 438: 58,-2 + 439: 58,-3 + 440: 59,-3 + 441: 60,-3 + 442: 61,-3 + 443: 62,-3 + 516: -28,27 + 517: -32,27 + 1208: -64,51 - node: color: '#EFB34196' id: QuarterTileOverlayGreyscale270 decals: - 1425: -6,51 - 1426: -6,50 - 1427: -6,49 - 1428: -6,48 - 1429: -6,47 - 1430: -6,46 + 1415: -6,51 + 1416: -6,50 + 1417: -6,49 + 1418: -6,48 + 1419: -6,47 + 1420: -6,46 - node: color: '#334E6DC8' id: QuarterTileOverlayGreyscale90 @@ -5934,11 +5934,11 @@ entities: decals: 233: -26,-34 234: -27,-34 - 420: 53,-12 - 421: 52,-12 - 422: 51,-12 - 423: 53,-13 - 424: 53,-14 + 410: 53,-12 + 411: 52,-12 + 412: 51,-12 + 413: 53,-13 + 414: 53,-14 - node: color: '#9FED5896' id: QuarterTileOverlayGreyscale90 @@ -5998,672 +5998,672 @@ entities: 21: 33,20 22: 33,19 90: 33,7 - 1440: 33,23 - 1441: 33,24 - 1442: 33,25 - 1443: 33,26 - 1444: 33,27 - 1445: 33,28 - 1446: 33,29 - 1447: 33,30 - 3984: 33,35 + 1430: 33,23 + 1431: 33,24 + 1432: 33,25 + 1433: 33,26 + 1434: 33,27 + 1435: 33,28 + 1436: 33,29 + 1437: 33,30 + 3971: 33,35 - node: color: '#D381C996' id: QuarterTileOverlayGreyscale90 decals: - 561: 25,51 - 562: 24,51 - 563: 23,51 - 564: 22,51 - 565: 21,51 - 976: 24,66 - 1006: 16,57 - 1007: 16,58 - 1008: 15,58 - 1009: 14,58 - 1010: 13,58 - 1011: 12,58 - 1012: 11,58 - 1382: 20,51 - 1383: 19,51 - 1384: 18,51 - 1385: 17,51 - 1386: 16,51 - 1387: 12,51 - 1388: 11,51 - 1389: 10,51 - 1390: 9,51 - 1391: 8,51 - 1392: 7,51 - 1393: 6,51 - 1394: 5,51 - 1395: 4,51 + 551: 25,51 + 552: 24,51 + 553: 23,51 + 554: 22,51 + 555: 21,51 + 966: 24,66 + 996: 16,57 + 997: 16,58 + 998: 15,58 + 999: 14,58 + 1000: 13,58 + 1001: 12,58 + 1002: 11,58 + 1372: 20,51 + 1373: 19,51 + 1374: 18,51 + 1375: 17,51 + 1376: 16,51 + 1377: 12,51 + 1378: 11,51 + 1379: 10,51 + 1380: 9,51 + 1381: 8,51 + 1382: 7,51 + 1383: 6,51 + 1384: 5,51 + 1385: 4,51 - node: color: '#D4D4D419' id: QuarterTileOverlayGreyscale90 decals: - 1201: -56,31 + 1191: -56,31 - node: color: '#D4D4D433' id: QuarterTileOverlayGreyscale90 decals: - 848: 20,-17 - 862: 21,-31 - 890: 21,-58 + 838: 20,-17 + 852: 21,-31 + 880: 21,-58 - node: color: '#DE3A3A96' id: QuarterTileOverlayGreyscale90 decals: 347: 37,-3 - 376: 46,-12 - 390: 33,-7 - 394: 36,-12 - 395: 36,-11 - 396: 36,-10 - 397: 36,-9 - 398: 36,-8 - 399: 36,-7 - 413: 43,-12 - 414: 42,-12 - 415: 41,-12 - 416: 40,-12 - 417: 39,-12 - 435: 56,-3 - 436: 56,-2 - 437: 56,-1 - 438: 54,-1 - 439: 53,-1 - 440: 52,-1 - 441: 51,-1 - 442: 50,-1 - 443: 49,-1 - 454: 62,-3 - 455: 62,-2 - 456: 62,-1 - 457: 62,0 - 458: 61,0 - 459: 60,0 - 460: 59,0 - 461: 58,0 - 521: -26,25 - 522: -30,26 - 4989: 37,-12 - 4990: 38,-12 + 373: 46,-12 + 382: 33,-7 + 386: 36,-12 + 387: 36,-11 + 388: 36,-10 + 389: 36,-9 + 390: 36,-8 + 391: 36,-7 + 405: 43,-12 + 406: 42,-12 + 407: 41,-12 + 408: 40,-12 + 409: 39,-12 + 425: 56,-3 + 426: 56,-2 + 427: 56,-1 + 428: 54,-1 + 429: 53,-1 + 430: 52,-1 + 431: 51,-1 + 432: 50,-1 + 433: 49,-1 + 444: 62,-3 + 445: 62,-2 + 446: 62,-1 + 447: 62,0 + 448: 61,0 + 449: 60,0 + 450: 59,0 + 451: 58,0 + 511: -26,25 + 512: -30,26 + 4967: 37,-12 + 4968: 38,-12 - node: color: '#EFB34196' id: QuarterTileOverlayGreyscale90 decals: - 542: -19,32 - 543: -19,31 - 544: -18,31 - 545: -17,31 - 546: -16,31 - 547: -15,31 - 548: -14,31 - 549: -13,31 - 550: -12,31 - 551: -11,31 - 552: -10,31 - 553: -9,31 - 554: -8,31 - 621: -19,45 - 626: -20,54 - 1396: 2,51 - 1397: 1,51 - 1398: -1,51 - 1399: -2,51 - 1400: -3,51 - 1401: -4,51 - 1402: -5,51 - 1403: -6,51 - 1438: -7,45 - 1439: -8,45 + 532: -19,32 + 533: -19,31 + 534: -18,31 + 535: -17,31 + 536: -16,31 + 537: -15,31 + 538: -14,31 + 539: -13,31 + 540: -12,31 + 541: -11,31 + 542: -10,31 + 543: -9,31 + 544: -8,31 + 611: -19,45 + 616: -20,54 + 1386: 2,51 + 1387: 1,51 + 1388: -1,51 + 1389: -2,51 + 1390: -3,51 + 1391: -4,51 + 1392: -5,51 + 1393: -6,51 + 1428: -7,45 + 1429: -8,45 - node: color: '#FFFFFFFF' id: Remains decals: - 3318: -29.994413,-49.927315 + 3305: -29.994413,-49.927315 - node: color: '#60E25873' id: Rock01 decals: - 3377: -59.92391,38.210167 - 3378: -59.99335,38.974056 - 3379: -59.99335,39.946278 - 3380: -59.965576,41.015724 - 3381: -59.965576,42.321278 + 3364: -59.92391,38.210167 + 3365: -59.99335,38.974056 + 3366: -59.99335,39.946278 + 3367: -59.965576,41.015724 + 3368: -59.965576,42.321278 - node: color: '#9FED5896' id: Rock01 decals: - 3462: 24.034931,-33.3361 - 3463: 23.951597,-33.863876 + 3449: 24.034931,-33.3361 + 3450: 23.951597,-33.863876 - node: color: '#9FED5873' id: Rock02 decals: - 3311: 78.26405,7.9695406 - 3312: 79.31961,7.983429 - 3313: 79.93072,7.941762 - 3314: 78.26405,7.9556513 + 3298: 78.26405,7.9695406 + 3299: 79.31961,7.983429 + 3300: 79.93072,7.941762 + 3301: 78.26405,7.9556513 - node: color: '#9FED5896' id: Rock02 decals: - 3197: -40.422146,-22.63485 - 3198: -41.797146,-22.468182 - 3199: -42.797146,-21.815403 - 3200: -42.297146,-22.87096 - 3201: -43.158257,-18.593182 - 3202: -43.047146,-19.73207 - 3203: -40.61659,-18.329292 - 3204: -39.922146,-18.940403 - 3205: -39.797146,-22.565403 - 3206: -39.86659,-23.50985 - 3207: -41.283257,-21.787628 - 3208: -42.797146,-20.87096 - 3209: -42.7277,-17.940403 - 3210: -41.061035,-18.12096 - 3211: -41.21381,-19.176516 + 3184: -40.422146,-22.63485 + 3185: -41.797146,-22.468182 + 3186: -42.797146,-21.815403 + 3187: -42.297146,-22.87096 + 3188: -43.158257,-18.593182 + 3189: -43.047146,-19.73207 + 3190: -40.61659,-18.329292 + 3191: -39.922146,-18.940403 + 3192: -39.797146,-22.565403 + 3193: -39.86659,-23.50985 + 3194: -41.283257,-21.787628 + 3195: -42.797146,-20.87096 + 3196: -42.7277,-17.940403 + 3197: -41.061035,-18.12096 + 3198: -41.21381,-19.176516 - node: color: '#9FED5896' id: Rock05 decals: - 3458: 23.909931,-33.22499 - 3459: 24.007153,-33.9611 + 3445: 23.909931,-33.22499 + 3446: 24.007153,-33.9611 - node: color: '#FFFFFFFF' id: Rock05 decals: - 4774: -1.8656068,46.688976 + 4761: -1.8656068,46.688976 - node: color: '#FFFFFFFF' id: Rock07 decals: - 3317: -16.459831,-40.314075 + 3304: -16.459831,-40.314075 - node: cleanable: True color: '#FFFFFFFF' id: Rust decals: - 3292: -64,-33 - 3293: -65,-33 - 3294: -63,-33 + 3279: -64,-33 + 3280: -65,-33 + 3281: -63,-33 - node: color: '#B78FB4FF' id: SpaceStationSign1 decals: - 1543: 4,-4 + 1533: 4,-4 - node: color: '#B78FB4FF' id: SpaceStationSign2 decals: - 1544: 5,-4 + 1534: 5,-4 - node: color: '#B78FB4FF' id: SpaceStationSign3 decals: - 1545: 6,-4 + 1535: 6,-4 - node: color: '#B78FB4FF' id: SpaceStationSign4 decals: - 1546: 7,-4 + 1536: 7,-4 - node: color: '#B78FB4FF' id: SpaceStationSign5 decals: - 1547: 8,-4 + 1537: 8,-4 - node: color: '#B78FB4FF' id: SpaceStationSign6 decals: - 1548: 9,-4 + 1538: 9,-4 - node: color: '#B78FB4FF' id: SpaceStationSign7 decals: - 1549: 10,-4 + 1539: 10,-4 - node: color: '#A4610696' id: StandClear decals: - 3976: 34,20 - 3977: 34,19 - 3978: 34,20 - 3979: 34,19 - 3980: 39,20 - 3981: 39,19 - 3982: 39,20 - 3983: 39,19 + 3963: 34,20 + 3964: 34,19 + 3965: 34,20 + 3966: 34,19 + 3967: 39,20 + 3968: 39,19 + 3969: 39,20 + 3970: 39,19 - node: color: '#EFB34196' id: StandClear decals: - 462: 35,-2 - 463: 36,-2 - 464: 37,-2 - 719: 23,14 - 720: 23,13 - 721: 23,12 - 1043: 37,26 - 1551: 34,14 - 1552: 34,13 - 1553: 34,12 - 1554: 53,-26 - 1555: 53,-27 - 1556: 53,-28 - 1557: 53,-29 - 1558: 53,-30 - 1559: 53,-31 - 1560: 56,-31 - 1561: 56,-30 - 1562: 56,-29 - 1563: 56,-28 - 1564: 56,-27 - 1565: 56,-26 - 1630: -22,50 - 1631: -22,49 - 1632: -22,48 - 1633: -22,47 + 452: 35,-2 + 453: 36,-2 + 454: 37,-2 + 709: 23,14 + 710: 23,13 + 711: 23,12 + 1033: 37,26 + 1541: 34,14 + 1542: 34,13 + 1543: 34,12 + 1544: 53,-26 + 1545: 53,-27 + 1546: 53,-28 + 1547: 53,-29 + 1548: 53,-30 + 1549: 53,-31 + 1550: 56,-31 + 1551: 56,-30 + 1552: 56,-29 + 1553: 56,-28 + 1554: 56,-27 + 1555: 56,-26 + 1619: -22,50 + 1620: -22,49 + 1621: -22,48 + 1622: -22,47 - node: angle: 1.5707963267948966 rad color: '#EFB34196' id: StandClear decals: - 1235: -56,39 - 1236: -56,37 - 1237: -56,46 - 1238: -56,48 + 1225: -56,39 + 1226: -56,37 + 1227: -56,46 + 1228: -56,48 - node: color: '#52B4E996' id: StandClearGreyscale decals: - 4071: -3,-11 - 4072: -3,-12 - 4073: -1,-11 - 4074: -1,-12 - 4075: 15,-11 - 4076: 15,-12 - 4077: 17,-11 - 4078: 17,-12 - 4742: -27,17 - 4743: -27,18 - 4744: -25,18 - 4745: -25,17 + 4058: -3,-11 + 4059: -3,-12 + 4060: -1,-11 + 4061: -1,-12 + 4062: 15,-11 + 4063: 15,-12 + 4064: 17,-11 + 4065: 17,-12 + 4729: -27,17 + 4730: -27,18 + 4731: -25,18 + 4732: -25,17 - node: color: '#D381C996' id: StandClearGreyscale decals: - 3890: 25,54 - 3891: 25,55 - 3892: 21,55 - 3893: 21,54 - 3985: 16,64 - 3986: 18,68 - 3987: 19,68 - 3988: 23,72 - 3989: 24,72 - 4374: 25,79 - 4375: 25,78 - 4376: 28,79 - 4377: 28,78 - 4378: 32,79 - 4379: 32,78 - 4380: 32,77 + 3877: 25,54 + 3878: 25,55 + 3879: 21,55 + 3880: 21,54 + 3972: 16,64 + 3973: 18,68 + 3974: 19,68 + 3975: 23,72 + 3976: 24,72 + 4361: 25,79 + 4362: 25,78 + 4363: 28,79 + 4364: 28,78 + 4365: 32,79 + 4366: 32,78 + 4367: 32,77 - node: color: '#DE3A3A96' id: StandClearGreyscale decals: - 1618: 47,-14 - 1619: 47,-15 - 1620: 50,-18 - 1676: 41,1 - 1677: 39,1 - 1678: 39,-2 - 1679: 41,-2 + 1607: 47,-14 + 1608: 47,-15 + 1609: 50,-18 + 1665: 41,1 + 1666: 39,1 + 1667: 39,-2 + 1668: 41,-2 - node: color: '#D4D4D433' id: ThreeQuarterTileOverlayGreyscale decals: - 808: -43,-3 + 798: -43,-3 - node: color: '#DE3A3A96' id: ThreeQuarterTileOverlayGreyscale decals: 243: -28,-38 - 1460: 35,51 + 1450: 35,51 - node: color: '#D4D4D433' id: ThreeQuarterTileOverlayGreyscale180 decals: - 813: -3,-6 + 803: -3,-6 - node: color: '#DE3A3A96' id: ThreeQuarterTileOverlayGreyscale180 decals: 235: -27,-41 241: -22,-41 - 1214: -61,48 - 1458: 38,48 + 1204: -61,48 + 1448: 38,48 - node: color: '#D4D4D419' id: ThreeQuarterTileOverlayGreyscale270 decals: - 1197: -58,29 + 1187: -58,29 - node: color: '#D4D4D433' id: ThreeQuarterTileOverlayGreyscale270 decals: - 814: 17,-6 + 804: 17,-6 - node: color: '#DE3A3A96' id: ThreeQuarterTileOverlayGreyscale270 decals: 236: -25,-41 242: -28,-41 - 1459: 35,48 + 1449: 35,48 - node: color: '#D4D4D419' id: ThreeQuarterTileOverlayGreyscale90 decals: - 1313: 18,31 + 1303: 18,31 - node: color: '#D4D4D433' id: ThreeQuarterTileOverlayGreyscale90 decals: - 847: 21,-17 + 837: 21,-17 - node: color: '#DE3A3A96' id: ThreeQuarterTileOverlayGreyscale90 decals: 244: -22,-38 - 3485: 47,-3 + 3472: 47,-3 - node: color: '#FFFFFFFF' id: VentSmall decals: - 3571: -5,-1 + 3558: -5,-1 - node: color: '#79150096' id: WarnBox decals: - 1494: -52,-24 - 1495: -52,-25 - 3261: -6,13 - 3262: -6,13 - 3263: -6,14 - 3264: -6,14 - 3265: -6,15 - 3266: -6,15 - 3270: 30,13 - 3271: 30,12 - 3272: 30,13 - 3273: 30,12 + 1484: -52,-24 + 1485: -52,-25 + 3248: -6,13 + 3249: -6,13 + 3250: -6,14 + 3251: -6,14 + 3252: -6,15 + 3253: -6,15 + 3257: 30,13 + 3258: 30,12 + 3259: 30,13 + 3260: 30,12 - node: color: '#52B4E996' id: WarnBoxGreyscale decals: - 1496: -49,-25 - 1497: -49,-24 - 3267: 22,17 - 3268: 22,16 - 3269: 22,15 - 4925: -51,-38 - 4926: -49,-38 + 1486: -49,-25 + 1487: -49,-24 + 3254: 22,17 + 3255: 22,16 + 3256: 22,15 + 4912: -51,-38 + 4913: -49,-38 - node: color: '#EFB34196' id: WarnCornerNE decals: - 1003: 16,56 - 1102: 39,14 - 1424: -7,42 + 993: 16,56 + 1092: 39,14 + 1414: -7,42 - node: color: '#FFFFFFFF' id: WarnCornerNE decals: - 4849: 27,12 - 4853: -25,36 - 4857: 54,-15 + 4836: 27,12 + 4840: -25,36 + 4844: 54,-15 - node: color: '#EFB34196' id: WarnCornerNW decals: - 727: 24,14 - 1099: 35,14 + 717: 24,14 + 1089: 35,14 - node: color: '#FFFFFFFF' id: WarnCornerNW decals: - 4681: -29,16 - 4848: 25,12 - 4854: -28,36 - 4855: -10,41 + 4668: -29,16 + 4835: 25,12 + 4841: -28,36 + 4842: -10,41 - node: color: '#EFB34196' id: WarnCornerSE decals: - 1100: 39,12 - 1259: -22,32 - 1418: -7,46 - 3259: -2,43 + 1090: 39,12 + 1249: -22,32 + 1408: -7,46 + 3246: -2,43 - node: color: '#FFFFFFFF' id: WarnCornerSE decals: - 4666: 10,72 - 4858: 54,-17 + 4653: 10,72 + 4845: 54,-17 - node: color: '#EFB34196' id: WarnCornerSW decals: - 1101: 35,12 - 1260: -18,32 + 1091: 35,12 + 1250: -18,32 - node: color: '#FFFFFFFF' id: WarnCornerSW decals: - 4684: -29,19 - 4856: -10,40 + 4671: -29,19 + 4843: -10,40 - node: color: '#EFB34196' id: WarnCornerSmallNE decals: - 1489: -2,57 + 1479: -2,57 - node: color: '#FFFFFFFF' id: WarnCornerSmallNE decals: - 4818: 73,-5 - 4819: 73,-12 - 4879: -40,26 + 4805: 73,-5 + 4806: 73,-12 + 4866: -40,26 - node: color: '#EFB34196' id: WarnCornerSmallNW decals: - 641: -23,48 - 1488: 2,57 + 631: -23,48 + 1478: 2,57 - node: color: '#FFFFFFFF' id: WarnCornerSmallNW decals: - 4820: 85,-5 - 4821: 85,-12 - 4880: -41,26 + 4807: 85,-5 + 4808: 85,-12 + 4867: -41,26 - node: color: '#EFB34196' id: WarnCornerSmallSE decals: - 1486: -2,61 - 3246: 49,-20 - 3260: -2,44 + 1476: -2,61 + 3233: 49,-20 + 3247: -2,44 - node: color: '#FFFFFFFF' id: WarnCornerSmallSE decals: - 4816: 73,-3 - 4817: 73,-10 + 4803: 73,-3 + 4804: 73,-10 - node: color: '#EFB34196' id: WarnCornerSmallSW decals: - 999: 16,56 - 1487: 2,61 - 3247: 51,-20 + 989: 16,56 + 1477: 2,61 + 3234: 51,-20 - node: color: '#FFFFFFFF' id: WarnCornerSmallSW decals: - 4822: 85,-10 - 4823: 85,-3 + 4809: 85,-10 + 4810: 85,-3 - node: color: '#EFB34196' id: WarnEndE decals: - 1681: -19,-23 + 1670: -19,-23 - node: color: '#FFFFFFFF' id: WarnEndE decals: - 4665: 21,74 + 4652: 21,74 - node: color: '#FFFFFFFF' id: WarnEndN decals: - 4860: 40,-10 + 4847: 40,-10 - node: color: '#EFB34196' id: WarnEndS decals: - 3243: 49,-21 - 3244: 51,-21 + 3230: 49,-21 + 3231: 51,-21 - node: color: '#EFB34196' id: WarnEndW decals: - 1000: 13,56 - 1680: -20,-23 + 990: 13,56 + 1669: -20,-23 - node: color: '#FFFFFFFF' id: WarnEndW decals: - 4664: 20,74 + 4651: 20,74 - node: color: '#334E6DC8' id: WarnFullGreyscale decals: - 4740: -26,17 - 4741: -26,18 + 4727: -26,17 + 4728: -26,18 - node: color: '#EFB34196' id: WarnLineE decals: - 474: 74,14 - 475: 74,13 - 476: 74,12 - 477: 81,15 - 478: 81,14 - 479: 81,13 - 480: 81,12 - 487: 74,15 - 637: -23,50 - 638: -23,49 - 639: -23,48 - 640: -23,47 - 675: -10,38 - 676: -10,39 - 722: 22,14 - 723: 22,13 - 724: 22,12 - 991: 24,69 - 992: 20,60 - 1004: 16,55 - 1020: 17,65 - 1021: 17,64 - 1022: 17,63 - 1028: 24,69 - 1031: 20,60 - 1032: 15,64 - 1110: 39,13 - 1264: -22,33 - 1409: -7,38 - 1410: -7,39 - 1411: -7,40 - 1412: -7,41 - 1413: -7,47 - 1414: -7,48 - 1415: -7,49 - 1416: -7,50 - 1417: -7,51 - 1468: 33,12 - 1469: 33,13 - 1470: 33,14 - 1471: 33,12 - 1472: 33,13 - 1473: 33,14 - 1477: -2,58 - 1478: -2,59 - 1479: -2,60 - 1533: 47,33 - 1534: 47,34 - 1598: 62,-21 - 1612: 46,-14 - 1613: 46,-15 - 1614: 46,-14 - 1615: 46,-15 - 1623: 51,-17 - 1624: 51,-16 - 3248: 51,-20 - 3249: 51,-19 - 3894: 24,54 - 3895: 24,55 - 3898: 20,54 - 3899: 20,55 - 3900: 20,54 - 3901: 20,55 - 4350: 24,79 - 4351: 24,79 - 4352: 24,78 - 4353: 24,78 - 4366: 27,79 - 4367: 27,79 - 4368: 27,78 - 4369: 27,78 + 464: 74,14 + 465: 74,13 + 466: 74,12 + 467: 81,15 + 468: 81,14 + 469: 81,13 + 470: 81,12 + 477: 74,15 + 627: -23,50 + 628: -23,49 + 629: -23,48 + 630: -23,47 + 665: -10,38 + 666: -10,39 + 712: 22,14 + 713: 22,13 + 714: 22,12 + 981: 24,69 + 982: 20,60 + 994: 16,55 + 1010: 17,65 + 1011: 17,64 + 1012: 17,63 + 1018: 24,69 + 1021: 20,60 + 1022: 15,64 + 1100: 39,13 + 1254: -22,33 + 1399: -7,38 + 1400: -7,39 + 1401: -7,40 + 1402: -7,41 + 1403: -7,47 + 1404: -7,48 + 1405: -7,49 + 1406: -7,50 + 1407: -7,51 + 1458: 33,12 + 1459: 33,13 + 1460: 33,14 + 1461: 33,12 + 1462: 33,13 + 1463: 33,14 + 1467: -2,58 + 1468: -2,59 + 1469: -2,60 + 1523: 47,33 + 1524: 47,34 + 1588: 62,-21 + 1601: 46,-14 + 1602: 46,-15 + 1603: 46,-14 + 1604: 46,-15 + 1612: 51,-17 + 1613: 51,-16 + 3235: 51,-20 + 3236: 51,-19 + 3881: 24,54 + 3882: 24,55 + 3885: 20,54 + 3886: 20,55 + 3887: 20,54 + 3888: 20,55 + 4337: 24,79 + 4338: 24,79 + 4339: 24,78 + 4340: 24,78 + 4353: 27,79 + 4354: 27,79 + 4355: 27,78 + 4356: 27,78 - node: color: '#FFFFFFFF' id: WarnLineE decals: - 4457: 19,15 - 4458: 19,16 - 4459: 19,17 - 4668: 10,73 - 4669: 10,74 - 4670: 10,75 - 4671: 10,76 - 4814: 73,-11 - 4815: 73,-4 - 4828: -54,47 - 4829: -54,46 - 4830: -54,39 - 4831: -54,38 - 4859: 54,-16 - 4864: -40,27 + 4444: 19,15 + 4445: 19,16 + 4446: 19,17 + 4655: 10,73 + 4656: 10,74 + 4657: 10,75 + 4658: 10,76 + 4801: 73,-11 + 4802: 73,-4 + 4815: -54,47 + 4816: -54,46 + 4817: -54,39 + 4818: -54,38 + 4846: 54,-16 + 4851: -40,27 - node: color: '#DE3A3A96' id: WarnLineGreyscaleN decals: - 1570: 64,-22 - 1571: 65,-22 - 1572: 66,-22 - 1573: 67,-22 - 1574: 64,-21 - 1575: 64,-21 - 1576: 65,-21 - 1577: 65,-21 - 1578: 66,-21 - 1579: 66,-21 - 1580: 67,-21 - 1581: 67,-21 + 1560: 64,-22 + 1561: 65,-22 + 1562: 66,-22 + 1563: 67,-22 + 1564: 64,-21 + 1565: 64,-21 + 1566: 65,-21 + 1567: 65,-21 + 1568: 66,-21 + 1569: 66,-21 + 1570: 67,-21 + 1571: 67,-21 - node: color: '#D381C996' id: WarnLineGreyscaleS @@ -6677,94 +6677,94 @@ entities: color: '#DE3A3A96' id: WarnLineGreyscaleS decals: - 1566: 64,-20 - 1567: 65,-20 - 1568: 66,-20 - 1569: 67,-20 - 1582: 64,-21 - 1583: 64,-21 - 1584: 65,-21 - 1585: 65,-21 - 1586: 66,-21 - 1587: 66,-21 - 1588: 67,-21 - 1589: 67,-21 + 1556: 64,-20 + 1557: 65,-20 + 1558: 66,-20 + 1559: 67,-20 + 1572: 64,-21 + 1573: 64,-21 + 1574: 65,-21 + 1575: 65,-21 + 1576: 66,-21 + 1577: 66,-21 + 1578: 67,-21 + 1579: 67,-21 - node: color: '#EFB34196' id: WarnLineN decals: 311: -41,-26 - 623: -21,55 - 624: -20,55 - 985: 18,69 - 986: 19,69 - 997: 15,56 - 998: 14,56 - 1106: 36,12 - 1107: 37,12 - 1108: 38,12 - 1222: -62,53 - 1223: -58,53 - 1266: -27,32 - 1267: -26,32 - 1268: -25,32 - 1269: -24,32 - 1270: -23,32 - 1271: -17,32 - 1272: -16,32 - 1273: -15,32 - 1274: -14,32 - 1275: -13,32 - 1419: -8,46 - 1448: -23,55 - 1449: -24,55 - 1450: -25,55 - 1451: -26,55 - 1452: -27,55 - 1453: -28,55 - 1454: -29,55 - 1475: 0,52 - 1480: -1,61 - 1481: 0,61 - 1482: 1,61 - 1492: 23,54 - 1493: 24,54 - 1590: 64,-22 - 1591: 65,-22 - 1592: 66,-22 - 1593: 67,-22 - 1621: 50,-17 - 1664: -43,-17 - 1665: -42,-17 - 1666: -41,-17 - 3245: 50,-20 - 3254: 2,44 - 3255: 3,44 - 3256: 1,44 - 3257: 0,44 - 3258: -1,44 - 3295: 22,54 + 613: -21,55 + 614: -20,55 + 975: 18,69 + 976: 19,69 + 987: 15,56 + 988: 14,56 + 1096: 36,12 + 1097: 37,12 + 1098: 38,12 + 1212: -62,53 + 1213: -58,53 + 1256: -27,32 + 1257: -26,32 + 1258: -25,32 + 1259: -24,32 + 1260: -23,32 + 1261: -17,32 + 1262: -16,32 + 1263: -15,32 + 1264: -14,32 + 1265: -13,32 + 1409: -8,46 + 1438: -23,55 + 1439: -24,55 + 1440: -25,55 + 1441: -26,55 + 1442: -27,55 + 1443: -28,55 + 1444: -29,55 + 1465: 0,52 + 1470: -1,61 + 1471: 0,61 + 1472: 1,61 + 1482: 23,54 + 1483: 24,54 + 1580: 64,-22 + 1581: 65,-22 + 1582: 66,-22 + 1583: 67,-22 + 1610: 50,-17 + 1653: -43,-17 + 1654: -42,-17 + 1655: -41,-17 + 3232: 50,-20 + 3241: 2,44 + 3242: 3,44 + 3243: 1,44 + 3244: 0,44 + 3245: -1,44 + 3282: 22,54 - node: color: '#FFFFFFFF' id: WarnLineN decals: - 4667: 9,72 - 4685: -28,19 - 4824: 88,3 - 4836: -47,-50 - 4837: -48,-50 - 4838: 10,-51 - 4839: 9,-51 - 4861: 55,0 - 4862: 56,0 - 4871: -44,26 - 4872: -43,26 - 4873: -42,26 - 4874: -41,26 - 4875: -40,26 - 4876: -39,26 - 4877: -38,26 - 4878: -37,26 + 4654: 9,72 + 4672: -28,19 + 4811: 88,3 + 4823: -47,-50 + 4824: -48,-50 + 4825: 10,-51 + 4826: 9,-51 + 4848: 55,0 + 4849: 56,0 + 4858: -44,26 + 4859: -43,26 + 4860: -42,26 + 4861: -41,26 + 4862: -40,26 + 4863: -39,26 + 4864: -38,26 + 4865: -37,26 - node: color: '#EFB34196' id: WarnLineS @@ -6772,391 +6772,391 @@ entities: 308: -40,-27 309: -40,-28 310: -40,-29 - 481: 77,14 - 482: 77,13 - 483: 77,12 - 484: 84,15 - 485: 84,13 - 486: 84,12 - 488: 77,15 - 558: -8,45 - 559: -8,44 - 560: -8,43 - 635: -23,49 - 636: -23,50 - 725: 24,13 - 726: 24,12 - 993: 18,55 - 994: 18,56 - 995: 16,53 - 996: 16,55 - 1005: 16,54 - 1023: 17,64 - 1029: 18,56 - 1030: 18,55 - 1033: 14,63 - 1034: 14,64 - 1035: 14,65 - 1109: 35,13 - 1265: -18,33 - 1420: -8,45 - 1421: -8,44 - 1422: -8,43 - 1483: 2,60 - 1484: 2,59 - 1485: 2,58 - 1616: 48,-15 - 1617: 48,-14 - 3250: 49,-20 - 3251: 49,-19 - 3252: 30,66 - 3253: 30,66 - 3305: 84,14 - 3896: 22,55 - 3897: 22,54 - 4354: 29,79 - 4355: 29,79 - 4356: 29,78 - 4357: 29,78 - 4370: 26,79 - 4371: 26,79 - 4372: 26,78 - 4373: 26,78 - 4415: 26,54 - 4416: 26,55 + 471: 77,14 + 472: 77,13 + 473: 77,12 + 474: 84,15 + 475: 84,13 + 476: 84,12 + 478: 77,15 + 548: -8,45 + 549: -8,44 + 550: -8,43 + 625: -23,49 + 626: -23,50 + 715: 24,13 + 716: 24,12 + 983: 18,55 + 984: 18,56 + 985: 16,53 + 986: 16,55 + 995: 16,54 + 1013: 17,64 + 1019: 18,56 + 1020: 18,55 + 1023: 14,63 + 1024: 14,64 + 1025: 14,65 + 1099: 35,13 + 1255: -18,33 + 1410: -8,45 + 1411: -8,44 + 1412: -8,43 + 1473: 2,60 + 1474: 2,59 + 1475: 2,58 + 1605: 48,-15 + 1606: 48,-14 + 3237: 49,-20 + 3238: 49,-19 + 3239: 30,66 + 3240: 30,66 + 3292: 84,14 + 3883: 22,55 + 3884: 22,54 + 4341: 29,79 + 4342: 29,79 + 4343: 29,78 + 4344: 29,78 + 4357: 26,79 + 4358: 26,79 + 4359: 26,78 + 4360: 26,78 + 4402: 26,54 + 4403: 26,55 - node: color: '#FFFFFFFF' id: WarnLineS decals: - 4682: -29,15 - 4683: -29,20 - 4812: 85,-11 - 4813: 85,-4 - 4826: -54,46 - 4827: -54,47 - 4832: -54,39 - 4833: -54,38 - 4863: -41,27 + 4669: -29,15 + 4670: -29,20 + 4799: 85,-11 + 4800: 85,-4 + 4813: -54,46 + 4814: -54,47 + 4819: -54,39 + 4820: -54,38 + 4850: -41,27 - node: color: '#EFB34196' id: WarnLineW decals: - 471: 35,-2 - 472: 36,-2 - 473: 37,-2 - 555: -21,33 - 556: -20,33 - 557: -19,33 - 627: -21,56 - 628: -20,56 - 629: -29,48 - 630: -28,48 - 631: -27,48 - 632: -26,48 - 633: -25,48 - 634: -24,48 - 697: 25,14 - 698: 26,14 - 699: 27,14 - 700: 28,14 - 981: 18,69 - 982: 19,69 - 983: 20,69 - 984: 21,69 - 987: 18,67 - 988: 19,67 - 989: 23,71 - 990: 24,71 - 1001: 14,56 - 1002: 15,56 - 1024: 18,67 - 1025: 19,67 - 1026: 23,71 - 1027: 24,71 - 1103: 36,14 - 1104: 37,14 - 1105: 38,14 - 1221: -62,51 - 1261: -21,33 - 1262: -20,33 - 1263: -19,33 - 1423: -8,42 - 1474: 0,53 - 1476: -1,57 - 1490: 23,55 - 1491: 24,55 - 1594: 64,-20 - 1595: 65,-20 - 1596: 66,-20 - 1597: 67,-20 - 1622: 50,-19 - 3296: 22,55 - 3836: 0,57 - 3837: 1,57 + 461: 35,-2 + 462: 36,-2 + 463: 37,-2 + 545: -21,33 + 546: -20,33 + 547: -19,33 + 617: -21,56 + 618: -20,56 + 619: -29,48 + 620: -28,48 + 621: -27,48 + 622: -26,48 + 623: -25,48 + 624: -24,48 + 687: 25,14 + 688: 26,14 + 689: 27,14 + 690: 28,14 + 971: 18,69 + 972: 19,69 + 973: 20,69 + 974: 21,69 + 977: 18,67 + 978: 19,67 + 979: 23,71 + 980: 24,71 + 991: 14,56 + 992: 15,56 + 1014: 18,67 + 1015: 19,67 + 1016: 23,71 + 1017: 24,71 + 1093: 36,14 + 1094: 37,14 + 1095: 38,14 + 1211: -62,51 + 1251: -21,33 + 1252: -20,33 + 1253: -19,33 + 1413: -8,42 + 1464: 0,53 + 1466: -1,57 + 1480: 23,55 + 1481: 24,55 + 1584: 64,-20 + 1585: 65,-20 + 1586: 66,-20 + 1587: 67,-20 + 1611: 50,-19 + 3283: 22,55 + 3823: 0,57 + 3824: 1,57 - node: color: '#FFFFFFFF' id: WarnLineW decals: - 4672: 18,71 - 4673: 19,71 - 4674: 20,71 - 4675: 21,71 - 4676: 18,69 - 4677: 19,69 - 4678: 20,69 - 4679: 21,69 - 4686: -28,16 - 4784: 86,-3 - 4785: 85,-3 - 4786: 73,-3 - 4787: 72,-3 - 4825: 88,3 - 4834: -47,-50 - 4835: -48,-50 - 4840: 10,-51 - 4841: 9,-51 - 4850: 26,12 - 4851: -27,36 - 4852: -26,36 - 4865: -44,26 - 4866: -43,26 - 4867: -42,26 - 4868: -39,26 - 4869: -38,26 - 4870: -37,26 + 4659: 18,71 + 4660: 19,71 + 4661: 20,71 + 4662: 21,71 + 4663: 18,69 + 4664: 19,69 + 4665: 20,69 + 4666: 21,69 + 4673: -28,16 + 4771: 86,-3 + 4772: 85,-3 + 4773: 73,-3 + 4774: 72,-3 + 4812: 88,3 + 4821: -47,-50 + 4822: -48,-50 + 4827: 10,-51 + 4828: 9,-51 + 4837: 26,12 + 4838: -27,36 + 4839: -26,36 + 4852: -44,26 + 4853: -43,26 + 4854: -42,26 + 4855: -39,26 + 4856: -38,26 + 4857: -37,26 - node: color: '#FFFFFFFF' id: WoodTrimThinCornerNe decals: - 3464: -25,-19 - 3559: 13,-18 + 3451: -25,-19 + 3546: 13,-18 - node: color: '#FFFFFFFF' id: WoodTrimThinCornerNw decals: - 3686: 30,-18 + 3673: 30,-18 - node: color: '#FFFFFFFF' id: WoodTrimThinCornerSe decals: - 3558: 13,-19 + 3545: 13,-19 - node: color: '#FFFFFFFF' id: WoodTrimThinCornerSw decals: - 3563: 9,-19 - 3691: 30,-23 + 3550: 9,-19 + 3678: 30,-23 - node: color: '#FFFFFFFF' id: WoodTrimThinEndN decals: - 3561: 9,-17 + 3548: 9,-17 - node: color: '#FFFFFFFF' id: WoodTrimThinInnerNe decals: - 3565: 9,-18 - 3819: -11,33 + 3552: 9,-18 + 3806: -11,33 - node: color: '#FFFFFFFF' id: WoodTrimThinInnerNw decals: - 3817: -8,33 + 3804: -8,33 - node: color: '#FFFFFFFF' id: WoodTrimThinInnerSe decals: - 3818: -11,36 - 4311: -18,-10 - 4312: -18,-9 + 3805: -11,36 + 4298: -18,-10 + 4299: -18,-9 - node: color: '#FFFFFFFF' id: WoodTrimThinInnerSw decals: - 3816: -8,36 + 3803: -8,36 - node: color: '#FFFFFFFF' id: WoodTrimThinLineE decals: - 3467: -25,-20 - 3468: -25,-21 - 3810: -11,34 - 3811: -11,35 + 3454: -25,-20 + 3455: -25,-21 + 3797: -11,34 + 3798: -11,35 - node: color: '#FFFFFFFF' id: WoodTrimThinLineN decals: - 3422: -2,-46 - 3423: -1,-46 - 3424: 0,-46 - 3425: 1,-46 - 3426: -3,-42 - 3427: -2,-42 - 3428: -1,-42 - 3429: 0,-42 - 3430: 1,-42 - 3465: -26,-19 - 3466: -27,-19 - 3482: -21,-13 - 3560: 12,-18 - 3687: 31,-18 - 3688: 32,-18 - 3689: 33,-18 - 3690: 34,-18 - 3808: -10,33 - 3809: -9,33 + 3409: -2,-46 + 3410: -1,-46 + 3411: 0,-46 + 3412: 1,-46 + 3413: -3,-42 + 3414: -2,-42 + 3415: -1,-42 + 3416: 0,-42 + 3417: 1,-42 + 3452: -26,-19 + 3453: -27,-19 + 3469: -21,-13 + 3547: 12,-18 + 3674: 31,-18 + 3675: 32,-18 + 3676: 33,-18 + 3677: 34,-18 + 3795: -10,33 + 3796: -9,33 - node: color: '#FFFFFFFF' id: WoodTrimThinLineS decals: - 3431: -3,-44 - 3432: -2,-44 - 3433: -1,-44 - 3434: 0,-44 - 3435: 1,-44 - 3436: -3,-48 - 3437: -2,-48 - 3438: -1,-48 - 3439: 0,-48 - 3440: 1,-48 - 3441: -12,-32 - 3564: 12,-19 - 3692: 31,-23 - 3693: 32,-23 - 3694: 33,-23 - 3695: 34,-23 - 3814: -10,36 - 3815: -9,36 + 3418: -3,-44 + 3419: -2,-44 + 3420: -1,-44 + 3421: 0,-44 + 3422: 1,-44 + 3423: -3,-48 + 3424: -2,-48 + 3425: -1,-48 + 3426: 0,-48 + 3427: 1,-48 + 3428: -12,-32 + 3551: 12,-19 + 3679: 31,-23 + 3680: 32,-23 + 3681: 33,-23 + 3682: 34,-23 + 3801: -10,36 + 3802: -9,36 - node: color: '#FFFFFFFF' id: WoodTrimThinLineW decals: - 3416: -3,-42 - 3417: -3,-43 - 3418: -3,-44 - 3419: -3,-46 - 3420: -3,-47 - 3421: -3,-48 - 3476: -21,-13 - 3477: -21,-14 - 3478: -21,-15 - 3479: -21,-16 - 3480: -21,-17 - 3481: -21,-18 - 3562: 9,-18 - 3681: 30,-22 - 3682: 30,-21 - 3683: 30,-20 - 3684: 30,-19 - 3685: 23,-21 - 3812: -8,34 - 3813: -8,35 + 3403: -3,-42 + 3404: -3,-43 + 3405: -3,-44 + 3406: -3,-46 + 3407: -3,-47 + 3408: -3,-48 + 3463: -21,-13 + 3464: -21,-14 + 3465: -21,-15 + 3466: -21,-16 + 3467: -21,-17 + 3468: -21,-18 + 3549: 9,-18 + 3668: 30,-22 + 3669: 30,-21 + 3670: 30,-20 + 3671: 30,-19 + 3672: 23,-21 + 3799: -8,34 + 3800: -8,35 - node: color: '#9FED5896' id: bushsnowa1 decals: - 3183: -41.436035,-22.25985 - 3184: -41.283257,-23.079292 - 3185: -40.255478,-23.398739 - 3186: -40.019367,-18.10707 - 3187: -41.005478,-18.926516 - 3188: -43.061035,-18.00985 - 3189: -43.130478,-18.718182 - 3190: -43.07492,-19.940405 - 3191: -43.1027,-21.551517 - 3192: -41.880478,-23.204292 - 3193: -40.172146,-23.787628 - 3194: -41.11659,-23.75985 - 3195: -39.880478,-22.273739 - 3196: -40.130478,-19.079292 + 3170: -41.436035,-22.25985 + 3171: -41.283257,-23.079292 + 3172: -40.255478,-23.398739 + 3173: -40.019367,-18.10707 + 3174: -41.005478,-18.926516 + 3175: -43.061035,-18.00985 + 3176: -43.130478,-18.718182 + 3177: -43.07492,-19.940405 + 3178: -43.1027,-21.551517 + 3179: -41.880478,-23.204292 + 3180: -40.172146,-23.787628 + 3181: -41.11659,-23.75985 + 3182: -39.880478,-22.273739 + 3183: -40.130478,-19.079292 - node: color: '#9FED5896' id: bushsnowb3 decals: - 3460: 24.076597,-33.183323 - 3461: 23.937708,-34.09999 + 3447: 24.076597,-33.183323 + 3448: 23.937708,-34.09999 - node: color: '#A4DF8296' id: bushsnowb3 decals: - 1694: -7.3679967,-22.387566 - 1695: -9.20133,-22.69312 - 1696: -9.062441,-23.859787 - 1697: -7.2291064,-23.637566 - 1698: -8.423552,-23.276455 + 1683: -7.3679967,-22.387566 + 1684: -9.20133,-22.69312 + 1685: -9.062441,-23.859787 + 1686: -7.2291064,-23.637566 + 1687: -8.423552,-23.276455 - node: color: '#9FED5896' id: grasssnow07 decals: - 3309: 78.19461,7.941762 - 3310: 79.52794,7.9139843 + 3296: 78.19461,7.941762 + 3297: 79.52794,7.9139843 - node: color: '#60AC5863' id: grasssnow09 decals: - 3328: -12.979685,-40.336945 - 3329: -11.368574,-40.225834 - 3330: -11.4657955,-39.059166 - 3331: -13.701906,-39.198055 - 3332: -12.507462,-39.503613 - 3333: -12.799128,-40.614723 + 3315: -12.979685,-40.336945 + 3316: -11.368574,-40.225834 + 3317: -11.4657955,-39.059166 + 3318: -13.701906,-39.198055 + 3319: -12.507462,-39.503613 + 3320: -12.799128,-40.614723 - node: color: '#9FED587C' id: grasssnow09 decals: - 3327: -13.604685,-40.086945 + 3314: -13.604685,-40.086945 - node: color: '#60FF5D92' id: grasssnow10 decals: - 4511: -19.105085,3.5241327 - 4512: -19.957012,2.1050215 - 4513: -19.829224,0.3878975 + 4498: -19.105085,3.5241327 + 4499: -19.957012,2.1050215 + 4500: -19.829224,0.3878975 - node: color: '#9FED587C' id: grasssnow10 decals: - 3319: -13.5907955,-40.670277 - 3320: -12.229685,-40.475834 - 3321: -11.354685,-39.475834 - 3322: -13.813017,-39.350834 - 3323: -12.826906,-39.614723 - 3324: -11.271351,-40.698055 - 3325: -11.41024,-38.989723 - 3326: -12.979685,-38.961945 + 3306: -13.5907955,-40.670277 + 3307: -12.229685,-40.475834 + 3308: -11.354685,-39.475834 + 3309: -13.813017,-39.350834 + 3310: -12.826906,-39.614723 + 3311: -11.271351,-40.698055 + 3312: -11.41024,-38.989723 + 3313: -12.979685,-38.961945 - node: color: '#A4DF8296' id: grasssnow10 decals: - 1684: -7.4220443,-1.9321766 + 1673: -7.4220443,-1.9321766 - node: color: '#A4DF8296' id: grasssnowc1 decals: - 1685: -6.4220433,-1.9599552 + 1674: -6.4220433,-1.9599552 - node: color: '#60E2588B' id: grasssnowc3 decals: - 3348: -15.396351,-36.573055 - 3349: -17.549128,-36.656387 - 3350: -17.604685,-37.795277 - 3351: -16.007462,-37.8925 - 3352: -16.354685,-36.698055 - 3353: -15.299128,-37.6425 - 3354: -16.118574,-37.031387 + 3335: -15.396351,-36.573055 + 3336: -17.549128,-36.656387 + 3337: -17.604685,-37.795277 + 3338: -16.007462,-37.8925 + 3339: -16.354685,-36.698055 + 3340: -15.299128,-37.6425 + 3341: -16.118574,-37.031387 - node: cleanable: True color: '#800080FF' id: prolizard decals: - 4680: 27.413673,-33.665314 + 4667: 27.413673,-33.665314 - node: color: '#9FED5896' id: shop decals: - 3286: -4,-42 - 3287: -4,-48 + 3273: -4,-42 + 3274: -4,-48 type: DecalGrid - version: 2 data: @@ -38285,6 +38285,16 @@ entities: - pos: 16.5,-18.5 parent: 82 type: Transform + - uid: 22707 + components: + - pos: 40.5,-19.5 + parent: 82 + type: Transform + - uid: 22712 + components: + - pos: 40.5,-20.5 + parent: 82 + type: Transform - uid: 22740 components: - pos: -36.5,37.5 @@ -46965,6 +46975,11 @@ entities: - pos: -3.5,-13.5 parent: 82 type: Transform + - uid: 22959 + components: + - pos: -25.5,45.5 + parent: 82 + type: Transform - uid: 22970 components: - pos: -2.5,-13.5 @@ -47359,6 +47374,51 @@ entities: - pos: -34.5,-25.5 parent: 82 type: Transform + - uid: 2731 + components: + - pos: -22.5,53.5 + parent: 82 + type: Transform + - uid: 2757 + components: + - pos: -27.5,56.5 + parent: 82 + type: Transform + - uid: 2819 + components: + - pos: -23.5,53.5 + parent: 82 + type: Transform + - uid: 2839 + components: + - pos: -24.5,53.5 + parent: 82 + type: Transform + - uid: 2846 + components: + - pos: -25.5,53.5 + parent: 82 + type: Transform + - uid: 2847 + components: + - pos: -26.5,53.5 + parent: 82 + type: Transform + - uid: 2869 + components: + - pos: -27.5,55.5 + parent: 82 + type: Transform + - uid: 3147 + components: + - pos: -27.5,53.5 + parent: 82 + type: Transform + - uid: 3148 + components: + - pos: -27.5,54.5 + parent: 82 + type: Transform - uid: 3869 components: - pos: -11.5,4.5 @@ -47494,6 +47554,11 @@ entities: - pos: -11.5,-5.5 parent: 82 type: Transform + - uid: 5620 + components: + - pos: -26.5,57.5 + parent: 82 + type: Transform - uid: 5644 components: - pos: -34.5,64.5 @@ -47754,6 +47819,11 @@ entities: - pos: -35.5,64.5 parent: 82 type: Transform + - uid: 5729 + components: + - pos: -27.5,57.5 + parent: 82 + type: Transform - uid: 5732 components: - pos: -22.5,56.5 @@ -47761,47 +47831,12 @@ entities: type: Transform - uid: 5733 components: - - pos: -22.5,55.5 + - pos: -27.5,59.5 parent: 82 type: Transform - uid: 5734 components: - - pos: -22.5,54.5 - parent: 82 - type: Transform - - uid: 5735 - components: - - pos: -21.5,54.5 - parent: 82 - type: Transform - - uid: 5736 - components: - - pos: -20.5,54.5 - parent: 82 - type: Transform - - uid: 5737 - components: - - pos: -20.5,55.5 - parent: 82 - type: Transform - - uid: 5738 - components: - - pos: -20.5,56.5 - parent: 82 - type: Transform - - uid: 5739 - components: - - pos: -20.5,57.5 - parent: 82 - type: Transform - - uid: 5740 - components: - - pos: -20.5,58.5 - parent: 82 - type: Transform - - uid: 5741 - components: - - pos: -20.5,59.5 + - pos: -27.5,58.5 parent: 82 type: Transform - uid: 5776 @@ -47909,16 +47944,6 @@ entities: - pos: -21.5,79.5 parent: 82 type: Transform - - uid: 6738 - components: - - pos: -23.5,55.5 - parent: 82 - type: Transform - - uid: 6739 - components: - - pos: -23.5,54.5 - parent: 82 - type: Transform - uid: 6740 components: - pos: -23.5,56.5 @@ -47929,16 +47954,6 @@ entities: - pos: -23.5,57.5 parent: 82 type: Transform - - uid: 6742 - components: - - pos: -23.5,58.5 - parent: 82 - type: Transform - - uid: 6743 - components: - - pos: -23.5,59.5 - parent: 82 - type: Transform - uid: 6744 components: - pos: -23.5,60.5 @@ -48054,6 +48069,11 @@ entities: - pos: -34.5,72.5 parent: 82 type: Transform + - uid: 11206 + components: + - pos: -20.5,53.5 + parent: 82 + type: Transform - uid: 11218 components: - pos: -30.5,80.5 @@ -51909,6 +51929,11 @@ entities: - pos: -17.5,76.5 parent: 82 type: Transform + - uid: 21689 + components: + - pos: -21.5,53.5 + parent: 82 + type: Transform - uid: 21843 components: - pos: 0.5,40.5 @@ -52309,6 +52334,36 @@ entities: - pos: 1.5,63.5 parent: 82 type: Transform + - uid: 22934 + components: + - pos: -20.5,54.5 + parent: 82 + type: Transform + - uid: 22935 + components: + - pos: -20.5,55.5 + parent: 82 + type: Transform + - uid: 22936 + components: + - pos: -20.5,56.5 + parent: 82 + type: Transform + - uid: 22937 + components: + - pos: -20.5,57.5 + parent: 82 + type: Transform + - uid: 22943 + components: + - pos: -20.5,58.5 + parent: 82 + type: Transform + - uid: 22958 + components: + - pos: -20.5,59.5 + parent: 82 + type: Transform - uid: 24163 components: - pos: -13.5,48.5 @@ -52710,6 +52765,13 @@ entities: - pos: 58.456696,-37.53437 parent: 82 type: Transform +- proto: CannedApplauseInstrument + entities: + - uid: 8618 + components: + - pos: -42.56837,12.580838 + parent: 82 + type: Transform - proto: CapacitorStockPart entities: - uid: 9432 @@ -61920,15 +61982,6 @@ entities: - pos: 13.647984,38.49309 parent: 82 type: Transform -- proto: Claymore - entities: - - uid: 25509 - components: - - name: Maintscalibur - type: MetaData - - pos: 33.46861,68.93209 - parent: 82 - type: Transform - proto: CloningConsoleComputerCircuitboard entities: - uid: 19831 @@ -64352,7 +64405,7 @@ entities: type: EntityStorage - uid: 22642 components: - - pos: -18.5,54.5 + - pos: -19.77381,54.505054 parent: 82 type: Transform - air: @@ -64375,9 +64428,11 @@ entities: type: EntityStorage - uid: 22643 components: - - pos: -18.5,53.5 + - pos: -18.250603,54.50595 parent: 82 type: Transform + - sleepTime: 0.049999803 + type: Physics - air: volume: 200 immutable: False @@ -65179,13 +65234,6 @@ entities: - pos: -9.140789,-47.293507 parent: 82 type: Transform -- proto: ClothingBackpackMerc - entities: - - uid: 19820 - components: - - pos: 20.916914,-91.30483 - parent: 82 - type: Transform - proto: ClothingBeltChampion entities: - uid: 4365 @@ -65201,13 +65249,6 @@ entities: pos: 46.357616,16.331951 parent: 82 type: Transform -- proto: ClothingBeltMercWebbing - entities: - - uid: 6372 - components: - - pos: 20.291391,-103.31173 - parent: 82 - type: Transform - proto: ClothingBeltUtilityFilled entities: - uid: 6412 @@ -65267,13 +65308,6 @@ entities: - pos: 39.829994,-14.370501 parent: 82 type: Transform -- proto: ClothingEyesGlassesMercenary - entities: - - uid: 5386 - components: - - pos: 20.651289,-91.50796 - parent: 82 - type: Transform - proto: ClothingEyesGlassesMeson entities: - uid: 6410 @@ -66020,13 +66054,6 @@ entities: - pos: 33.54575,56.683422 parent: 82 type: Transform -- proto: ClothingOuterVestWebMerc - entities: - - uid: 20497 - components: - - pos: 20.541391,-103.546104 - parent: 82 - type: Transform - proto: ClothingOuterWinterCargo entities: - uid: 19400 @@ -66279,13 +66306,6 @@ entities: - pos: 60.777298,-16.464449 parent: 82 type: Transform -- proto: ClothingUniformJumpsuitMercenary - entities: - - uid: 20144 - components: - - pos: 20.557539,-91.30483 - parent: 82 - type: Transform - proto: ClothingUniformJumpsuitNanotrasen entities: - uid: 8620 @@ -66873,6 +66893,11 @@ entities: - pos: -51.5,12.5 parent: 82 type: Transform + - uid: 22960 + components: + - pos: -25.5,45.5 + parent: 82 + type: Transform - proto: ComputerRadar entities: - uid: 2245 @@ -117601,13 +117626,6 @@ entities: - pos: -15.03525,21.629791 parent: 82 type: Transform -- proto: KukriKnife - entities: - - uid: 8825 - components: - - pos: 20.432016,-103.4957 - parent: 82 - type: Transform - proto: Lamp entities: - uid: 19045 @@ -120595,9 +120613,11 @@ entities: type: Transform - uid: 10013 components: - - pos: -21.5,59.5 + - pos: -21.601662,59.538593 parent: 82 type: Transform + - sleepTime: 0.0166666 + type: Physics - uid: 11881 components: - pos: -51.5,10.5 @@ -120898,6 +120918,13 @@ entities: type: Transform - proto: PaperOffice entities: + - uid: 5386 + components: + - pos: 33.503384,69.00901 + parent: 82 + type: Transform + - content: Made you look. + type: Paper - uid: 10996 components: - pos: -34.351803,-28.541927 @@ -127120,69 +127147,71 @@ entities: type: Transform - proto: RadiationCollector entities: - - uid: 5620 - components: - - pos: -33.5,73.5 - parent: 82 - type: Transform - - uid: 5729 - components: - - pos: -33.5,75.5 - parent: 82 - type: Transform - - uid: 5847 - components: - - pos: -33.5,74.5 - parent: 82 - type: Transform - - uid: 5992 - components: - - pos: -33.5,70.5 - parent: 82 - type: Transform - - uid: 6175 - components: - - pos: -33.5,69.5 - parent: 82 - type: Transform - uid: 7097 components: - pos: -28.5,52.5 parent: 82 type: Transform - - uid: 11225 - components: - - pos: -17.5,70.5 - parent: 82 - type: Transform - - uid: 11442 - components: - - pos: -33.5,71.5 - parent: 82 - type: Transform - - uid: 21689 - components: - - pos: -17.5,73.5 - parent: 82 - type: Transform - - uid: 21722 - components: - - pos: -17.5,69.5 - parent: 82 - type: Transform - - uid: 22707 +- proto: RadiationCollectorFullTank + entities: + - uid: 5735 components: - pos: -17.5,71.5 parent: 82 type: Transform - - uid: 22712 + - uid: 5736 + components: + - pos: -17.5,69.5 + parent: 82 + type: Transform + - uid: 5737 + components: + - pos: -17.5,70.5 + parent: 82 + type: Transform + - uid: 5738 + components: + - pos: -17.5,74.5 + parent: 82 + type: Transform + - uid: 5739 components: - pos: -17.5,75.5 parent: 82 type: Transform - - uid: 22736 + - uid: 5740 components: - - pos: -17.5,74.5 + - pos: -33.5,70.5 + parent: 82 + type: Transform + - uid: 5741 + components: + - pos: -17.5,73.5 + parent: 82 + type: Transform + - uid: 5847 + components: + - pos: -33.5,73.5 + parent: 82 + type: Transform + - uid: 5992 + components: + - pos: -33.5,69.5 + parent: 82 + type: Transform + - uid: 6175 + components: + - pos: -33.5,71.5 + parent: 82 + type: Transform + - uid: 6738 + components: + - pos: -33.5,75.5 + parent: 82 + type: Transform + - uid: 6739 + components: + - pos: -33.5,74.5 parent: 82 type: Transform - proto: RadioHandheld @@ -138657,7 +138686,7 @@ entities: type: Transform - uid: 6034 components: - - pos: -23.5,49.5 + - pos: -25.5,72.5 parent: 82 type: Transform - proto: Sink @@ -141973,6 +142002,8 @@ entities: type: Transform - setupAvailableNetworks: - SurveillanceCameraEngineering + nameSet: True + id: Reception type: SurveillanceCamera - uid: 3849 components: @@ -142382,6 +142413,28 @@ entities: nameSet: True id: 'Checkpoint: Evac' type: SurveillanceCamera + - uid: 6372 + components: + - rot: 3.141592653589793 rad + pos: 41.5,-21.5 + parent: 82 + type: Transform + - setupAvailableNetworks: + - SurveillanceCameraSecurity + nameSet: True + id: Brig Exterior + type: SurveillanceCamera + - uid: 8825 + components: + - rot: 1.5707963267948966 rad + pos: 52.5,-24.5 + parent: 82 + type: Transform + - setupAvailableNetworks: + - SurveillanceCameraSecurity + nameSet: True + id: Armory Exterior + type: SurveillanceCamera - uid: 11474 components: - rot: 3.141592653589793 rad @@ -142423,7 +142476,7 @@ entities: - setupAvailableNetworks: - SurveillanceCameraSecurity nameSet: True - id: Brig + id: Permabrig type: SurveillanceCamera - uid: 21766 components: @@ -142433,6 +142486,8 @@ entities: type: Transform - setupAvailableNetworks: - SurveillanceCameraSecurity + nameSet: True + id: Shooting range hallway type: SurveillanceCamera - uid: 21771 components: @@ -145615,7 +145670,7 @@ entities: type: Transform - uid: 9682 components: - - pos: 20.601238,-103.10646 + - pos: 20.478569,-103.253105 parent: 82 type: Transform - uid: 11932 @@ -145948,13 +146003,6 @@ entities: - pos: 42.55547,-8.463266 parent: 82 type: Transform -- proto: VehicleKeySyndicateSegway - entities: - - uid: 8618 - components: - - pos: -42.48091,12.587237 - parent: 82 - type: Transform - proto: VendingBarDrobe entities: - uid: 4252 @@ -166018,6 +166066,17 @@ entities: pos: -59.5,39.5 parent: 82 type: Transform + - uid: 6742 + components: + - rot: 3.141592653589793 rad + pos: -39.5,-39.5 + parent: 82 + type: Transform + - uid: 6743 + components: + - pos: -38.5,-35.5 + parent: 82 + type: Transform - uid: 7927 components: - pos: 79.5,8.5 @@ -166137,6 +166196,23 @@ entities: pos: -17.5,-35.5 parent: 82 type: Transform + - uid: 11205 + components: + - rot: 1.5707963267948966 rad + pos: -36.5,-39.5 + parent: 82 + type: Transform + - uid: 11225 + components: + - rot: -1.5707963267948966 rad + pos: -30.5,-38.5 + parent: 82 + type: Transform + - uid: 11442 + components: + - pos: -35.5,-37.5 + parent: 82 + type: Transform - uid: 12766 components: - pos: -6.5,-1.5 @@ -166184,6 +166260,17 @@ entities: pos: -59.5,39.5 parent: 82 type: Transform + - uid: 14895 + components: + - rot: -1.5707963267948966 rad + pos: -30.5,-36.5 + parent: 82 + type: Transform + - uid: 14897 + components: + - pos: -39.5,-35.5 + parent: 82 + type: Transform - uid: 15512 components: - pos: -58.5,-41.5 @@ -166212,12 +166299,81 @@ entities: pos: 79.5,8.5 parent: 82 type: Transform + - uid: 18582 + components: + - pos: -30.5,-36.5 + parent: 82 + type: Transform + - uid: 18617 + components: + - rot: -1.5707963267948966 rad + pos: -30.5,-39.5 + parent: 82 + type: Transform + - uid: 19812 + components: + - rot: 1.5707963267948966 rad + pos: -36.5,-38.5 + parent: 82 + type: Transform + - uid: 19820 + components: + - rot: -1.5707963267948966 rad + pos: -30.5,-34.5 + parent: 82 + type: Transform + - uid: 20144 + components: + - pos: -31.5,-37.5 + parent: 82 + type: Transform + - uid: 20497 + components: + - pos: -33.5,-37.5 + parent: 82 + type: Transform - uid: 20681 components: - rot: 3.141592653589793 rad pos: 78.5,8.5 parent: 82 type: Transform + - uid: 21722 + components: + - rot: 3.141592653589793 rad + pos: -38.5,-39.5 + parent: 82 + type: Transform + - uid: 22463 + components: + - rot: -1.5707963267948966 rad + pos: -30.5,-35.5 + parent: 82 + type: Transform + - uid: 22736 + components: + - rot: -1.5707963267948966 rad + pos: -37.5,-36.5 + parent: 82 + type: Transform + - uid: 22764 + components: + - rot: -1.5707963267948966 rad + pos: -37.5,-38.5 + parent: 82 + type: Transform + - uid: 22928 + components: + - rot: 1.5707963267948966 rad + pos: -34.5,-38.5 + parent: 82 + type: Transform + - uid: 22933 + components: + - rot: 1.5707963267948966 rad + pos: -34.5,-39.5 + parent: 82 + type: Transform - uid: 24769 components: - rot: 1.5707963267948966 rad @@ -166389,23 +166545,6 @@ entities: type: Transform - proto: WindowReinforcedDirectional entities: - - uid: 2731 - components: - - rot: -1.5707963267948966 rad - pos: -30.5,-39.5 - parent: 82 - type: Transform - - uid: 2757 - components: - - pos: -33.5,-37.5 - parent: 82 - type: Transform - - uid: 2819 - components: - - rot: 1.5707963267948966 rad - pos: -34.5,-38.5 - parent: 82 - type: Transform - uid: 2828 components: - rot: 1.5707963267948966 rad @@ -166430,39 +166569,6 @@ entities: pos: -32.5,-44.5 parent: 82 type: Transform - - uid: 2839 - components: - - pos: -35.5,-37.5 - parent: 82 - type: Transform - - uid: 2846 - components: - - rot: 3.141592653589793 rad - pos: -38.5,-39.5 - parent: 82 - type: Transform - - uid: 2847 - components: - - rot: 1.5707963267948966 rad - pos: -36.5,-39.5 - parent: 82 - type: Transform - - uid: 2869 - components: - - rot: -1.5707963267948966 rad - pos: -30.5,-36.5 - parent: 82 - type: Transform - - uid: 3147 - components: - - pos: -31.5,-37.5 - parent: 82 - type: Transform - - uid: 3148 - components: - - pos: -30.5,-36.5 - parent: 82 - type: Transform - uid: 3346 components: - rot: -1.5707963267948966 rad @@ -166603,18 +166709,6 @@ entities: pos: 64.5,-10.5 parent: 82 type: Transform - - uid: 11205 - components: - - rot: 3.141592653589793 rad - pos: -39.5,-39.5 - parent: 82 - type: Transform - - uid: 11206 - components: - - rot: 1.5707963267948966 rad - pos: -34.5,-39.5 - parent: 82 - type: Transform - uid: 11450 components: - rot: 1.5707963267948966 rad @@ -166633,17 +166727,6 @@ entities: pos: 69.5,-20.5 parent: 82 type: Transform - - uid: 14895 - components: - - rot: -1.5707963267948966 rad - pos: -30.5,-34.5 - parent: 82 - type: Transform - - uid: 14897 - components: - - pos: -38.5,-35.5 - parent: 82 - type: Transform - uid: 17772 components: - pos: 64.5,-16.5 @@ -166678,23 +166761,6 @@ entities: pos: 69.5,-22.5 parent: 82 type: Transform - - uid: 18582 - components: - - rot: 1.5707963267948966 rad - pos: -36.5,-38.5 - parent: 82 - type: Transform - - uid: 18617 - components: - - pos: -39.5,-35.5 - parent: 82 - type: Transform - - uid: 19812 - components: - - rot: -1.5707963267948966 rad - pos: -30.5,-38.5 - parent: 82 - type: Transform - uid: 20488 components: - rot: 3.141592653589793 rad @@ -166719,12 +166785,6 @@ entities: pos: 64.5,-11.5 parent: 82 type: Transform - - uid: 22764 - components: - - rot: -1.5707963267948966 rad - pos: -30.5,-35.5 - parent: 82 - type: Transform - uid: 22886 components: - pos: 65.5,-16.5 From 43d5c006488a457fc32b2206756e6d81620960b8 Mon Sep 17 00:00:00 2001 From: DrSmugleaf Date: Sun, 22 Oct 2023 21:01:48 -0700 Subject: [PATCH 002/102] Store round start date in the database (#21153) --- .../20231021071411_RoundStartDate.Designer.cs | 1775 +++++++++++++++++ .../Postgres/20231021071411_RoundStartDate.cs | 39 + .../PostgresServerDbContextModelSnapshot.cs | 8 + .../20231021071407_RoundStartDate.Designer.cs | 1705 ++++++++++++++++ .../Sqlite/20231021071407_RoundStartDate.cs | 39 + .../SqliteServerDbContextModelSnapshot.cs | 8 + Content.Server.Database/Model.cs | 9 + Content.Server/Database/ServerDbBase.cs | 1 + 8 files changed, 3584 insertions(+) create mode 100644 Content.Server.Database/Migrations/Postgres/20231021071411_RoundStartDate.Designer.cs create mode 100644 Content.Server.Database/Migrations/Postgres/20231021071411_RoundStartDate.cs create mode 100644 Content.Server.Database/Migrations/Sqlite/20231021071407_RoundStartDate.Designer.cs create mode 100644 Content.Server.Database/Migrations/Sqlite/20231021071407_RoundStartDate.cs diff --git a/Content.Server.Database/Migrations/Postgres/20231021071411_RoundStartDate.Designer.cs b/Content.Server.Database/Migrations/Postgres/20231021071411_RoundStartDate.Designer.cs new file mode 100644 index 0000000000..bf3600ba39 --- /dev/null +++ b/Content.Server.Database/Migrations/Postgres/20231021071411_RoundStartDate.Designer.cs @@ -0,0 +1,1775 @@ +// +using System; +using System.Net; +using System.Text.Json; +using Content.Server.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Content.Server.Database.Migrations.Postgres +{ + [DbContext(typeof(PostgresServerDbContext))] + [Migration("20231021071411_RoundStartDate")] + partial class RoundStartDate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.4") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Content.Server.Database.Admin", b => + { + b.Property("UserId") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.Property("AdminRankId") + .HasColumnType("integer") + .HasColumnName("admin_rank_id"); + + b.Property("Title") + .HasColumnType("text") + .HasColumnName("title"); + + b.HasKey("UserId") + .HasName("PK_admin"); + + b.HasIndex("AdminRankId") + .HasDatabaseName("IX_admin_admin_rank_id"); + + b.ToTable("admin", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminFlag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("admin_flag_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AdminId") + .HasColumnType("uuid") + .HasColumnName("admin_id"); + + b.Property("Flag") + .IsRequired() + .HasColumnType("text") + .HasColumnName("flag"); + + b.Property("Negative") + .HasColumnType("boolean") + .HasColumnName("negative"); + + b.HasKey("Id") + .HasName("PK_admin_flag"); + + b.HasIndex("AdminId") + .HasDatabaseName("IX_admin_flag_admin_id"); + + b.HasIndex("Flag", "AdminId") + .IsUnique(); + + b.ToTable("admin_flag", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLog", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("admin_log_id"); + + b.Property("RoundId") + .HasColumnType("integer") + .HasColumnName("round_id"); + + b.Property("Date") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.Property("Impact") + .HasColumnType("smallint") + .HasColumnName("impact"); + + b.Property("Json") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("json"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text") + .HasColumnName("message"); + + b.Property("Type") + .HasColumnType("integer") + .HasColumnName("type"); + + b.HasKey("Id", "RoundId") + .HasName("PK_admin_log"); + + b.HasIndex("Date"); + + b.HasIndex("Message") + .HasAnnotation("Npgsql:TsVectorConfig", "english"); + + NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("Message"), "GIN"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_admin_log_round_id"); + + b.HasIndex("Type") + .HasDatabaseName("IX_admin_log_type"); + + b.ToTable("admin_log", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLogEntity", b => + { + b.Property("Uid") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("uid"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Uid")); + + b.Property("AdminLogId") + .HasColumnType("integer") + .HasColumnName("admin_log_id"); + + b.Property("AdminLogRoundId") + .HasColumnType("integer") + .HasColumnName("admin_log_round_id"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Uid") + .HasName("PK_admin_log_entity"); + + b.HasIndex("AdminLogId", "AdminLogRoundId") + .HasDatabaseName("IX_admin_log_entity_admin_log_id_admin_log_round_id"); + + b.ToTable("admin_log_entity", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLogPlayer", b => + { + b.Property("PlayerUserId") + .HasColumnType("uuid") + .HasColumnName("player_user_id"); + + b.Property("LogId") + .HasColumnType("integer") + .HasColumnName("log_id"); + + b.Property("RoundId") + .HasColumnType("integer") + .HasColumnName("round_id"); + + b.HasKey("PlayerUserId", "LogId", "RoundId") + .HasName("PK_admin_log_player"); + + b.HasIndex("LogId", "RoundId"); + + b.ToTable("admin_log_player", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("admin_messages_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("CreatedById") + .HasColumnType("uuid") + .HasColumnName("created_by_id"); + + b.Property("Deleted") + .HasColumnType("boolean") + .HasColumnName("deleted"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("DeletedById") + .HasColumnType("uuid") + .HasColumnName("deleted_by_id"); + + b.Property("ExpirationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiration_time"); + + b.Property("LastEditedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_edited_at"); + + b.Property("LastEditedById") + .HasColumnType("uuid") + .HasColumnName("last_edited_by_id"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("message"); + + b.Property("PlayerUserId") + .HasColumnType("uuid") + .HasColumnName("player_user_id"); + + b.Property("PlaytimeAtNote") + .HasColumnType("interval") + .HasColumnName("playtime_at_note"); + + b.Property("RoundId") + .HasColumnType("integer") + .HasColumnName("round_id"); + + b.Property("Seen") + .HasColumnType("boolean") + .HasColumnName("seen"); + + b.HasKey("Id") + .HasName("PK_admin_messages"); + + b.HasIndex("CreatedById"); + + b.HasIndex("DeletedById"); + + b.HasIndex("LastEditedById"); + + b.HasIndex("PlayerUserId") + .HasDatabaseName("IX_admin_messages_player_user_id"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_admin_messages_round_id"); + + b.ToTable("admin_messages", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminNote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("admin_notes_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("CreatedById") + .HasColumnType("uuid") + .HasColumnName("created_by_id"); + + b.Property("Deleted") + .HasColumnType("boolean") + .HasColumnName("deleted"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("DeletedById") + .HasColumnType("uuid") + .HasColumnName("deleted_by_id"); + + b.Property("ExpirationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiration_time"); + + b.Property("LastEditedAt") + .IsRequired() + .HasColumnType("timestamp with time zone") + .HasColumnName("last_edited_at"); + + b.Property("LastEditedById") + .HasColumnType("uuid") + .HasColumnName("last_edited_by_id"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("message"); + + b.Property("PlayerUserId") + .HasColumnType("uuid") + .HasColumnName("player_user_id"); + + b.Property("PlaytimeAtNote") + .HasColumnType("interval") + .HasColumnName("playtime_at_note"); + + b.Property("RoundId") + .HasColumnType("integer") + .HasColumnName("round_id"); + + b.Property("Secret") + .HasColumnType("boolean") + .HasColumnName("secret"); + + b.Property("Severity") + .HasColumnType("integer") + .HasColumnName("severity"); + + b.HasKey("Id") + .HasName("PK_admin_notes"); + + b.HasIndex("CreatedById"); + + b.HasIndex("DeletedById"); + + b.HasIndex("LastEditedById"); + + b.HasIndex("PlayerUserId") + .HasDatabaseName("IX_admin_notes_player_user_id"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_admin_notes_round_id"); + + b.ToTable("admin_notes", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRank", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("admin_rank_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("PK_admin_rank"); + + b.ToTable("admin_rank", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRankFlag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("admin_rank_flag_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AdminRankId") + .HasColumnType("integer") + .HasColumnName("admin_rank_id"); + + b.Property("Flag") + .IsRequired() + .HasColumnType("text") + .HasColumnName("flag"); + + b.HasKey("Id") + .HasName("PK_admin_rank_flag"); + + b.HasIndex("AdminRankId"); + + b.HasIndex("Flag", "AdminRankId") + .IsUnique(); + + b.ToTable("admin_rank_flag", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminWatchlist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("admin_watchlists_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("CreatedById") + .HasColumnType("uuid") + .HasColumnName("created_by_id"); + + b.Property("Deleted") + .HasColumnType("boolean") + .HasColumnName("deleted"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("DeletedById") + .HasColumnType("uuid") + .HasColumnName("deleted_by_id"); + + b.Property("ExpirationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiration_time"); + + b.Property("LastEditedAt") + .IsRequired() + .HasColumnType("timestamp with time zone") + .HasColumnName("last_edited_at"); + + b.Property("LastEditedById") + .HasColumnType("uuid") + .HasColumnName("last_edited_by_id"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("message"); + + b.Property("PlayerUserId") + .HasColumnType("uuid") + .HasColumnName("player_user_id"); + + b.Property("PlaytimeAtNote") + .HasColumnType("interval") + .HasColumnName("playtime_at_note"); + + b.Property("RoundId") + .HasColumnType("integer") + .HasColumnName("round_id"); + + b.HasKey("Id") + .HasName("PK_admin_watchlists"); + + b.HasIndex("CreatedById"); + + b.HasIndex("DeletedById"); + + b.HasIndex("LastEditedById"); + + b.HasIndex("PlayerUserId") + .HasDatabaseName("IX_admin_watchlists_player_user_id"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_admin_watchlists_round_id"); + + b.ToTable("admin_watchlists", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Antag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("antag_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AntagName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("antag_name"); + + b.Property("ProfileId") + .HasColumnType("integer") + .HasColumnName("profile_id"); + + b.HasKey("Id") + .HasName("PK_antag"); + + b.HasIndex("ProfileId", "AntagName") + .IsUnique(); + + b.ToTable("antag", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AssignedUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("assigned_user_id_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("user_name"); + + b.HasKey("Id") + .HasName("PK_assigned_user_id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.HasIndex("UserName") + .IsUnique(); + + b.ToTable("assigned_user_id", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.ConnectionLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("connection_log_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("inet") + .HasColumnName("address"); + + b.Property("Denied") + .HasColumnType("smallint") + .HasColumnName("denied"); + + b.Property("HWId") + .HasColumnType("bytea") + .HasColumnName("hwid"); + + b.Property("Time") + .HasColumnType("timestamp with time zone") + .HasColumnName("time"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("user_name"); + + b.HasKey("Id") + .HasName("PK_connection_log"); + + b.HasIndex("UserId"); + + b.ToTable("connection_log", null, t => + { + t.HasCheckConstraint("AddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= address"); + }); + }); + + modelBuilder.Entity("Content.Server.Database.Job", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("job_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("JobName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("job_name"); + + b.Property("Priority") + .HasColumnType("integer") + .HasColumnName("priority"); + + b.Property("ProfileId") + .HasColumnType("integer") + .HasColumnName("profile_id"); + + b.HasKey("Id") + .HasName("PK_job"); + + b.HasIndex("ProfileId"); + + b.HasIndex("ProfileId", "JobName") + .IsUnique(); + + b.HasIndex(new[] { "ProfileId" }, "IX_job_one_high_priority") + .IsUnique() + .HasFilter("priority = 3"); + + b.ToTable("job", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.PlayTime", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("play_time_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("PlayerId") + .HasColumnType("uuid") + .HasColumnName("player_id"); + + b.Property("TimeSpent") + .HasColumnType("interval") + .HasColumnName("time_spent"); + + b.Property("Tracker") + .IsRequired() + .HasColumnType("text") + .HasColumnName("tracker"); + + b.HasKey("Id") + .HasName("PK_play_time"); + + b.HasIndex("PlayerId", "Tracker") + .IsUnique(); + + b.ToTable("play_time", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Player", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("player_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FirstSeenTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("first_seen_time"); + + b.Property("LastReadRules") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_read_rules"); + + b.Property("LastSeenAddress") + .IsRequired() + .HasColumnType("inet") + .HasColumnName("last_seen_address"); + + b.Property("LastSeenHWId") + .HasColumnType("bytea") + .HasColumnName("last_seen_hwid"); + + b.Property("LastSeenTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_seen_time"); + + b.Property("LastSeenUserName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("last_seen_user_name"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("PK_player"); + + b.HasAlternateKey("UserId") + .HasName("ak_player_user_id"); + + b.HasIndex("LastSeenUserName"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("player", null, t => + { + t.HasCheckConstraint("LastSeenAddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= last_seen_address"); + }); + }); + + modelBuilder.Entity("Content.Server.Database.Preference", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("preference_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AdminOOCColor") + .IsRequired() + .HasColumnType("text") + .HasColumnName("admin_ooc_color"); + + b.Property("SelectedCharacterSlot") + .HasColumnType("integer") + .HasColumnName("selected_character_slot"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("PK_preference"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("preference", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Profile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("profile_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Age") + .HasColumnType("integer") + .HasColumnName("age"); + + b.Property("Backpack") + .IsRequired() + .HasColumnType("text") + .HasColumnName("backpack"); + + b.Property("CharacterName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("char_name"); + + b.Property("Clothing") + .IsRequired() + .HasColumnType("text") + .HasColumnName("clothing"); + + b.Property("EyeColor") + .IsRequired() + .HasColumnType("text") + .HasColumnName("eye_color"); + + b.Property("FacialHairColor") + .IsRequired() + .HasColumnType("text") + .HasColumnName("facial_hair_color"); + + b.Property("FacialHairName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("facial_hair_name"); + + b.Property("FlavorText") + .IsRequired() + .HasColumnType("text") + .HasColumnName("flavor_text"); + + b.Property("Gender") + .IsRequired() + .HasColumnType("text") + .HasColumnName("gender"); + + b.Property("HairColor") + .IsRequired() + .HasColumnType("text") + .HasColumnName("hair_color"); + + b.Property("HairName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("hair_name"); + + b.Property("Markings") + .HasColumnType("jsonb") + .HasColumnName("markings"); + + b.Property("PreferenceId") + .HasColumnType("integer") + .HasColumnName("preference_id"); + + b.Property("PreferenceUnavailable") + .HasColumnType("integer") + .HasColumnName("pref_unavailable"); + + b.Property("Sex") + .IsRequired() + .HasColumnType("text") + .HasColumnName("sex"); + + b.Property("SkinColor") + .IsRequired() + .HasColumnType("text") + .HasColumnName("skin_color"); + + b.Property("Slot") + .HasColumnType("integer") + .HasColumnName("slot"); + + b.Property("Species") + .IsRequired() + .HasColumnType("text") + .HasColumnName("species"); + + b.HasKey("Id") + .HasName("PK_profile"); + + b.HasIndex("PreferenceId") + .HasDatabaseName("IX_profile_preference_id"); + + b.HasIndex("Slot", "PreferenceId") + .IsUnique(); + + b.ToTable("profile", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Round", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("round_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ServerId") + .HasColumnType("integer") + .HasColumnName("server_id"); + + b.Property("StartDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValue(new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)) + .HasColumnName("start_date"); + + b.HasKey("Id") + .HasName("PK_round"); + + b.HasIndex("ServerId") + .HasDatabaseName("IX_round_server_id"); + + b.HasIndex("StartDate"); + + b.ToTable("round", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Server", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("server_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("PK_server"); + + b.ToTable("server", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("server_ban_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property?>("Address") + .HasColumnType("inet") + .HasColumnName("address"); + + b.Property("AutoDelete") + .HasColumnType("boolean") + .HasColumnName("auto_delete"); + + b.Property("BanTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("ban_time"); + + b.Property("BanningAdmin") + .HasColumnType("uuid") + .HasColumnName("banning_admin"); + + b.Property("ExemptFlags") + .HasColumnType("integer") + .HasColumnName("exempt_flags"); + + b.Property("ExpirationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiration_time"); + + b.Property("HWId") + .HasColumnType("bytea") + .HasColumnName("hwid"); + + b.Property("Hidden") + .HasColumnType("boolean") + .HasColumnName("hidden"); + + b.Property("LastEditedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_edited_at"); + + b.Property("LastEditedById") + .HasColumnType("uuid") + .HasColumnName("last_edited_by_id"); + + b.Property("PlayerUserId") + .HasColumnType("uuid") + .HasColumnName("player_user_id"); + + b.Property("PlaytimeAtNote") + .HasColumnType("interval") + .HasColumnName("playtime_at_note"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("text") + .HasColumnName("reason"); + + b.Property("RoundId") + .HasColumnType("integer") + .HasColumnName("round_id"); + + b.Property("Severity") + .HasColumnType("integer") + .HasColumnName("severity"); + + b.HasKey("Id") + .HasName("PK_server_ban"); + + b.HasIndex("Address"); + + b.HasIndex("BanningAdmin"); + + b.HasIndex("LastEditedById"); + + b.HasIndex("PlayerUserId") + .HasDatabaseName("IX_server_ban_player_user_id"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_server_ban_round_id"); + + b.ToTable("server_ban", null, t => + { + t.HasCheckConstraint("AddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= address"); + + t.HasCheckConstraint("HaveEitherAddressOrUserIdOrHWId", "address IS NOT NULL OR player_user_id IS NOT NULL OR hwid IS NOT NULL"); + }); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBanExemption", b => + { + b.Property("UserId") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.Property("Flags") + .HasColumnType("integer") + .HasColumnName("flags"); + + b.HasKey("UserId") + .HasName("PK_server_ban_exemption"); + + b.ToTable("server_ban_exemption", null, t => + { + t.HasCheckConstraint("FlagsNotZero", "flags != 0"); + }); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBanHit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("server_ban_hit_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BanId") + .HasColumnType("integer") + .HasColumnName("ban_id"); + + b.Property("ConnectionId") + .HasColumnType("integer") + .HasColumnName("connection_id"); + + b.HasKey("Id") + .HasName("PK_server_ban_hit"); + + b.HasIndex("BanId") + .HasDatabaseName("IX_server_ban_hit_ban_id"); + + b.HasIndex("ConnectionId") + .HasDatabaseName("IX_server_ban_hit_connection_id"); + + b.ToTable("server_ban_hit", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.ServerRoleBan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("server_role_ban_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property?>("Address") + .HasColumnType("inet") + .HasColumnName("address"); + + b.Property("BanTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("ban_time"); + + b.Property("BanningAdmin") + .HasColumnType("uuid") + .HasColumnName("banning_admin"); + + b.Property("ExpirationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiration_time"); + + b.Property("HWId") + .HasColumnType("bytea") + .HasColumnName("hwid"); + + b.Property("Hidden") + .HasColumnType("boolean") + .HasColumnName("hidden"); + + b.Property("LastEditedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_edited_at"); + + b.Property("LastEditedById") + .HasColumnType("uuid") + .HasColumnName("last_edited_by_id"); + + b.Property("PlayerUserId") + .HasColumnType("uuid") + .HasColumnName("player_user_id"); + + b.Property("PlaytimeAtNote") + .HasColumnType("interval") + .HasColumnName("playtime_at_note"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("text") + .HasColumnName("reason"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("text") + .HasColumnName("role_id"); + + b.Property("RoundId") + .HasColumnType("integer") + .HasColumnName("round_id"); + + b.Property("Severity") + .HasColumnType("integer") + .HasColumnName("severity"); + + b.HasKey("Id") + .HasName("PK_server_role_ban"); + + b.HasIndex("Address"); + + b.HasIndex("BanningAdmin"); + + b.HasIndex("LastEditedById"); + + b.HasIndex("PlayerUserId") + .HasDatabaseName("IX_server_role_ban_player_user_id"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_server_role_ban_round_id"); + + b.ToTable("server_role_ban", null, t => + { + t.HasCheckConstraint("AddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= address"); + + t.HasCheckConstraint("HaveEitherAddressOrUserIdOrHWId", "address IS NOT NULL OR player_user_id IS NOT NULL OR hwid IS NOT NULL"); + }); + }); + + modelBuilder.Entity("Content.Server.Database.ServerRoleUnban", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("role_unban_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BanId") + .HasColumnType("integer") + .HasColumnName("ban_id"); + + b.Property("UnbanTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("unban_time"); + + b.Property("UnbanningAdmin") + .HasColumnType("uuid") + .HasColumnName("unbanning_admin"); + + b.HasKey("Id") + .HasName("PK_server_role_unban"); + + b.HasIndex("BanId") + .IsUnique(); + + b.ToTable("server_role_unban", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.ServerUnban", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("unban_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BanId") + .HasColumnType("integer") + .HasColumnName("ban_id"); + + b.Property("UnbanTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("unban_time"); + + b.Property("UnbanningAdmin") + .HasColumnType("uuid") + .HasColumnName("unbanning_admin"); + + b.HasKey("Id") + .HasName("PK_server_unban"); + + b.HasIndex("BanId") + .IsUnique(); + + b.ToTable("server_unban", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Trait", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("trait_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ProfileId") + .HasColumnType("integer") + .HasColumnName("profile_id"); + + b.Property("TraitName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("trait_name"); + + b.HasKey("Id") + .HasName("PK_trait"); + + b.HasIndex("ProfileId", "TraitName") + .IsUnique(); + + b.ToTable("trait", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.UploadedResourceLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("uploaded_resource_log_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Data") + .IsRequired() + .HasColumnType("bytea") + .HasColumnName("data"); + + b.Property("Date") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.Property("Path") + .IsRequired() + .HasColumnType("text") + .HasColumnName("path"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("PK_uploaded_resource_log"); + + b.ToTable("uploaded_resource_log", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Whitelist", b => + { + b.Property("UserId") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("UserId") + .HasName("PK_whitelist"); + + b.ToTable("whitelist", (string)null); + }); + + modelBuilder.Entity("PlayerRound", b => + { + b.Property("PlayersId") + .HasColumnType("integer") + .HasColumnName("players_id"); + + b.Property("RoundsId") + .HasColumnType("integer") + .HasColumnName("rounds_id"); + + b.HasKey("PlayersId", "RoundsId") + .HasName("PK_player_round"); + + b.HasIndex("RoundsId") + .HasDatabaseName("IX_player_round_rounds_id"); + + b.ToTable("player_round", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Admin", b => + { + b.HasOne("Content.Server.Database.AdminRank", "AdminRank") + .WithMany("Admins") + .HasForeignKey("AdminRankId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_admin_rank_admin_rank_id"); + + b.Navigation("AdminRank"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminFlag", b => + { + b.HasOne("Content.Server.Database.Admin", "Admin") + .WithMany("Flags") + .HasForeignKey("AdminId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_admin_flag_admin_admin_id"); + + b.Navigation("Admin"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLog", b => + { + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany("AdminLogs") + .HasForeignKey("RoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_admin_log_round_round_id"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLogEntity", b => + { + b.HasOne("Content.Server.Database.AdminLog", null) + .WithMany("Entities") + .HasForeignKey("AdminLogId", "AdminLogRoundId") + .HasConstraintName("FK_admin_log_entity_admin_log_admin_log_id_admin_log_round_id"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLogPlayer", b => + { + b.HasOne("Content.Server.Database.Player", "Player") + .WithMany("AdminLogs") + .HasForeignKey("PlayerUserId") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_admin_log_player_player_player_user_id"); + + b.HasOne("Content.Server.Database.AdminLog", "Log") + .WithMany("Players") + .HasForeignKey("LogId", "RoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_admin_log_player_admin_log_log_id_round_id"); + + b.Navigation("Log"); + + b.Navigation("Player"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminMessage", b => + { + b.HasOne("Content.Server.Database.Player", "CreatedBy") + .WithMany("AdminMessagesCreated") + .HasForeignKey("CreatedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_messages_player_created_by_id"); + + b.HasOne("Content.Server.Database.Player", "DeletedBy") + .WithMany("AdminMessagesDeleted") + .HasForeignKey("DeletedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_messages_player_deleted_by_id"); + + b.HasOne("Content.Server.Database.Player", "LastEditedBy") + .WithMany("AdminMessagesLastEdited") + .HasForeignKey("LastEditedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_messages_player_last_edited_by_id"); + + b.HasOne("Content.Server.Database.Player", "Player") + .WithMany("AdminMessagesReceived") + .HasForeignKey("PlayerUserId") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("FK_admin_messages_player_player_user_id"); + + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany() + .HasForeignKey("RoundId") + .HasConstraintName("FK_admin_messages_round_round_id"); + + b.Navigation("CreatedBy"); + + b.Navigation("DeletedBy"); + + b.Navigation("LastEditedBy"); + + b.Navigation("Player"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminNote", b => + { + b.HasOne("Content.Server.Database.Player", "CreatedBy") + .WithMany("AdminNotesCreated") + .HasForeignKey("CreatedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_notes_player_created_by_id"); + + b.HasOne("Content.Server.Database.Player", "DeletedBy") + .WithMany("AdminNotesDeleted") + .HasForeignKey("DeletedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_notes_player_deleted_by_id"); + + b.HasOne("Content.Server.Database.Player", "LastEditedBy") + .WithMany("AdminNotesLastEdited") + .HasForeignKey("LastEditedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_notes_player_last_edited_by_id"); + + b.HasOne("Content.Server.Database.Player", "Player") + .WithMany("AdminNotesReceived") + .HasForeignKey("PlayerUserId") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("FK_admin_notes_player_player_user_id"); + + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany() + .HasForeignKey("RoundId") + .HasConstraintName("FK_admin_notes_round_round_id"); + + b.Navigation("CreatedBy"); + + b.Navigation("DeletedBy"); + + b.Navigation("LastEditedBy"); + + b.Navigation("Player"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRankFlag", b => + { + b.HasOne("Content.Server.Database.AdminRank", "Rank") + .WithMany("Flags") + .HasForeignKey("AdminRankId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_admin_rank_flag_admin_rank_admin_rank_id"); + + b.Navigation("Rank"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminWatchlist", b => + { + b.HasOne("Content.Server.Database.Player", "CreatedBy") + .WithMany("AdminWatchlistsCreated") + .HasForeignKey("CreatedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_watchlists_player_created_by_id"); + + b.HasOne("Content.Server.Database.Player", "DeletedBy") + .WithMany("AdminWatchlistsDeleted") + .HasForeignKey("DeletedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_watchlists_player_deleted_by_id"); + + b.HasOne("Content.Server.Database.Player", "LastEditedBy") + .WithMany("AdminWatchlistsLastEdited") + .HasForeignKey("LastEditedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_watchlists_player_last_edited_by_id"); + + b.HasOne("Content.Server.Database.Player", "Player") + .WithMany("AdminWatchlistsReceived") + .HasForeignKey("PlayerUserId") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("FK_admin_watchlists_player_player_user_id"); + + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany() + .HasForeignKey("RoundId") + .HasConstraintName("FK_admin_watchlists_round_round_id"); + + b.Navigation("CreatedBy"); + + b.Navigation("DeletedBy"); + + b.Navigation("LastEditedBy"); + + b.Navigation("Player"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.Antag", b => + { + b.HasOne("Content.Server.Database.Profile", "Profile") + .WithMany("Antags") + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_antag_profile_profile_id"); + + b.Navigation("Profile"); + }); + + modelBuilder.Entity("Content.Server.Database.Job", b => + { + b.HasOne("Content.Server.Database.Profile", "Profile") + .WithMany("Jobs") + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_job_profile_profile_id"); + + b.Navigation("Profile"); + }); + + modelBuilder.Entity("Content.Server.Database.Profile", b => + { + b.HasOne("Content.Server.Database.Preference", "Preference") + .WithMany("Profiles") + .HasForeignKey("PreferenceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_profile_preference_preference_id"); + + b.Navigation("Preference"); + }); + + modelBuilder.Entity("Content.Server.Database.Round", b => + { + b.HasOne("Content.Server.Database.Server", "Server") + .WithMany("Rounds") + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_round_server_server_id"); + + b.Navigation("Server"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBan", b => + { + b.HasOne("Content.Server.Database.Player", "CreatedBy") + .WithMany("AdminServerBansCreated") + .HasForeignKey("BanningAdmin") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_server_ban_player_banning_admin"); + + b.HasOne("Content.Server.Database.Player", "LastEditedBy") + .WithMany("AdminServerBansLastEdited") + .HasForeignKey("LastEditedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_server_ban_player_last_edited_by_id"); + + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany() + .HasForeignKey("RoundId") + .HasConstraintName("FK_server_ban_round_round_id"); + + b.Navigation("CreatedBy"); + + b.Navigation("LastEditedBy"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBanHit", b => + { + b.HasOne("Content.Server.Database.ServerBan", "Ban") + .WithMany("BanHits") + .HasForeignKey("BanId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_server_ban_hit_server_ban_ban_id"); + + b.HasOne("Content.Server.Database.ConnectionLog", "Connection") + .WithMany("BanHits") + .HasForeignKey("ConnectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_server_ban_hit_connection_log_connection_id"); + + b.Navigation("Ban"); + + b.Navigation("Connection"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerRoleBan", b => + { + b.HasOne("Content.Server.Database.Player", "CreatedBy") + .WithMany("AdminServerRoleBansCreated") + .HasForeignKey("BanningAdmin") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_server_role_ban_player_banning_admin"); + + b.HasOne("Content.Server.Database.Player", "LastEditedBy") + .WithMany("AdminServerRoleBansLastEdited") + .HasForeignKey("LastEditedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_server_role_ban_player_last_edited_by_id"); + + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany() + .HasForeignKey("RoundId") + .HasConstraintName("FK_server_role_ban_round_round_id"); + + b.Navigation("CreatedBy"); + + b.Navigation("LastEditedBy"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerRoleUnban", b => + { + b.HasOne("Content.Server.Database.ServerRoleBan", "Ban") + .WithOne("Unban") + .HasForeignKey("Content.Server.Database.ServerRoleUnban", "BanId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_server_role_unban_server_role_ban_ban_id"); + + b.Navigation("Ban"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerUnban", b => + { + b.HasOne("Content.Server.Database.ServerBan", "Ban") + .WithOne("Unban") + .HasForeignKey("Content.Server.Database.ServerUnban", "BanId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_server_unban_server_ban_ban_id"); + + b.Navigation("Ban"); + }); + + modelBuilder.Entity("Content.Server.Database.Trait", b => + { + b.HasOne("Content.Server.Database.Profile", "Profile") + .WithMany("Traits") + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_trait_profile_profile_id"); + + b.Navigation("Profile"); + }); + + modelBuilder.Entity("PlayerRound", b => + { + b.HasOne("Content.Server.Database.Player", null) + .WithMany() + .HasForeignKey("PlayersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_player_round_player_players_id"); + + b.HasOne("Content.Server.Database.Round", null) + .WithMany() + .HasForeignKey("RoundsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_player_round_round_rounds_id"); + }); + + modelBuilder.Entity("Content.Server.Database.Admin", b => + { + b.Navigation("Flags"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLog", b => + { + b.Navigation("Entities"); + + b.Navigation("Players"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRank", b => + { + b.Navigation("Admins"); + + b.Navigation("Flags"); + }); + + modelBuilder.Entity("Content.Server.Database.ConnectionLog", b => + { + b.Navigation("BanHits"); + }); + + modelBuilder.Entity("Content.Server.Database.Player", b => + { + b.Navigation("AdminLogs"); + + b.Navigation("AdminMessagesCreated"); + + b.Navigation("AdminMessagesDeleted"); + + b.Navigation("AdminMessagesLastEdited"); + + b.Navigation("AdminMessagesReceived"); + + b.Navigation("AdminNotesCreated"); + + b.Navigation("AdminNotesDeleted"); + + b.Navigation("AdminNotesLastEdited"); + + b.Navigation("AdminNotesReceived"); + + b.Navigation("AdminServerBansCreated"); + + b.Navigation("AdminServerBansLastEdited"); + + b.Navigation("AdminServerRoleBansCreated"); + + b.Navigation("AdminServerRoleBansLastEdited"); + + b.Navigation("AdminWatchlistsCreated"); + + b.Navigation("AdminWatchlistsDeleted"); + + b.Navigation("AdminWatchlistsLastEdited"); + + b.Navigation("AdminWatchlistsReceived"); + }); + + modelBuilder.Entity("Content.Server.Database.Preference", b => + { + b.Navigation("Profiles"); + }); + + modelBuilder.Entity("Content.Server.Database.Profile", b => + { + b.Navigation("Antags"); + + b.Navigation("Jobs"); + + b.Navigation("Traits"); + }); + + modelBuilder.Entity("Content.Server.Database.Round", b => + { + b.Navigation("AdminLogs"); + }); + + modelBuilder.Entity("Content.Server.Database.Server", b => + { + b.Navigation("Rounds"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBan", b => + { + b.Navigation("BanHits"); + + b.Navigation("Unban"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerRoleBan", b => + { + b.Navigation("Unban"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Content.Server.Database/Migrations/Postgres/20231021071411_RoundStartDate.cs b/Content.Server.Database/Migrations/Postgres/20231021071411_RoundStartDate.cs new file mode 100644 index 0000000000..d98b4e45a8 --- /dev/null +++ b/Content.Server.Database/Migrations/Postgres/20231021071411_RoundStartDate.cs @@ -0,0 +1,39 @@ +#nullable disable + +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Content.Server.Database.Migrations.Postgres +{ + /// + public partial class RoundStartDate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "start_date", + table: "round", + type: "timestamp with time zone", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.CreateIndex( + name: "IX_round_start_date", + table: "round", + column: "start_date"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_round_start_date", + table: "round"); + + migrationBuilder.DropColumn( + name: "start_date", + table: "round"); + } + } +} diff --git a/Content.Server.Database/Migrations/Postgres/PostgresServerDbContextModelSnapshot.cs b/Content.Server.Database/Migrations/Postgres/PostgresServerDbContextModelSnapshot.cs index 7d86084261..b7fa1a8843 100644 --- a/Content.Server.Database/Migrations/Postgres/PostgresServerDbContextModelSnapshot.cs +++ b/Content.Server.Database/Migrations/Postgres/PostgresServerDbContextModelSnapshot.cs @@ -856,12 +856,20 @@ namespace Content.Server.Database.Migrations.Postgres .HasColumnType("integer") .HasColumnName("server_id"); + b.Property("StartDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValue(new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)) + .HasColumnName("start_date"); + b.HasKey("Id") .HasName("PK_round"); b.HasIndex("ServerId") .HasDatabaseName("IX_round_server_id"); + b.HasIndex("StartDate"); + b.ToTable("round", (string)null); }); diff --git a/Content.Server.Database/Migrations/Sqlite/20231021071407_RoundStartDate.Designer.cs b/Content.Server.Database/Migrations/Sqlite/20231021071407_RoundStartDate.Designer.cs new file mode 100644 index 0000000000..cf8294e5e8 --- /dev/null +++ b/Content.Server.Database/Migrations/Sqlite/20231021071407_RoundStartDate.Designer.cs @@ -0,0 +1,1705 @@ +// +using System; +using Content.Server.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Content.Server.Database.Migrations.Sqlite +{ + [DbContext(typeof(SqliteServerDbContext))] + [Migration("20231021071407_RoundStartDate")] + partial class RoundStartDate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.4"); + + modelBuilder.Entity("Content.Server.Database.Admin", b => + { + b.Property("UserId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.Property("AdminRankId") + .HasColumnType("INTEGER") + .HasColumnName("admin_rank_id"); + + b.Property("Title") + .HasColumnType("TEXT") + .HasColumnName("title"); + + b.HasKey("UserId") + .HasName("PK_admin"); + + b.HasIndex("AdminRankId") + .HasDatabaseName("IX_admin_admin_rank_id"); + + b.ToTable("admin", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminFlag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("admin_flag_id"); + + b.Property("AdminId") + .HasColumnType("TEXT") + .HasColumnName("admin_id"); + + b.Property("Flag") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("flag"); + + b.Property("Negative") + .HasColumnType("INTEGER") + .HasColumnName("negative"); + + b.HasKey("Id") + .HasName("PK_admin_flag"); + + b.HasIndex("AdminId") + .HasDatabaseName("IX_admin_flag_admin_id"); + + b.HasIndex("Flag", "AdminId") + .IsUnique(); + + b.ToTable("admin_flag", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLog", b => + { + b.Property("Id") + .HasColumnType("INTEGER") + .HasColumnName("admin_log_id"); + + b.Property("RoundId") + .HasColumnType("INTEGER") + .HasColumnName("round_id"); + + b.Property("Date") + .HasColumnType("TEXT") + .HasColumnName("date"); + + b.Property("Impact") + .HasColumnType("INTEGER") + .HasColumnName("impact"); + + b.Property("Json") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("json"); + + b.Property("Message") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("message"); + + b.Property("Type") + .HasColumnType("INTEGER") + .HasColumnName("type"); + + b.HasKey("Id", "RoundId") + .HasName("PK_admin_log"); + + b.HasIndex("Date"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_admin_log_round_id"); + + b.HasIndex("Type") + .HasDatabaseName("IX_admin_log_type"); + + b.ToTable("admin_log", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLogEntity", b => + { + b.Property("Uid") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("uid"); + + b.Property("AdminLogId") + .HasColumnType("INTEGER") + .HasColumnName("admin_log_id"); + + b.Property("AdminLogRoundId") + .HasColumnType("INTEGER") + .HasColumnName("admin_log_round_id"); + + b.Property("Name") + .HasColumnType("TEXT") + .HasColumnName("name"); + + b.HasKey("Uid") + .HasName("PK_admin_log_entity"); + + b.HasIndex("AdminLogId", "AdminLogRoundId") + .HasDatabaseName("IX_admin_log_entity_admin_log_id_admin_log_round_id"); + + b.ToTable("admin_log_entity", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLogPlayer", b => + { + b.Property("PlayerUserId") + .HasColumnType("TEXT") + .HasColumnName("player_user_id"); + + b.Property("LogId") + .HasColumnType("INTEGER") + .HasColumnName("log_id"); + + b.Property("RoundId") + .HasColumnType("INTEGER") + .HasColumnName("round_id"); + + b.HasKey("PlayerUserId", "LogId", "RoundId") + .HasName("PK_admin_log_player"); + + b.HasIndex("LogId", "RoundId"); + + b.ToTable("admin_log_player", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("admin_messages_id"); + + b.Property("CreatedAt") + .HasColumnType("TEXT") + .HasColumnName("created_at"); + + b.Property("CreatedById") + .HasColumnType("TEXT") + .HasColumnName("created_by_id"); + + b.Property("Deleted") + .HasColumnType("INTEGER") + .HasColumnName("deleted"); + + b.Property("DeletedAt") + .HasColumnType("TEXT") + .HasColumnName("deleted_at"); + + b.Property("DeletedById") + .HasColumnType("TEXT") + .HasColumnName("deleted_by_id"); + + b.Property("ExpirationTime") + .HasColumnType("TEXT") + .HasColumnName("expiration_time"); + + b.Property("LastEditedAt") + .HasColumnType("TEXT") + .HasColumnName("last_edited_at"); + + b.Property("LastEditedById") + .HasColumnType("TEXT") + .HasColumnName("last_edited_by_id"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("TEXT") + .HasColumnName("message"); + + b.Property("PlayerUserId") + .HasColumnType("TEXT") + .HasColumnName("player_user_id"); + + b.Property("PlaytimeAtNote") + .HasColumnType("TEXT") + .HasColumnName("playtime_at_note"); + + b.Property("RoundId") + .HasColumnType("INTEGER") + .HasColumnName("round_id"); + + b.Property("Seen") + .HasColumnType("INTEGER") + .HasColumnName("seen"); + + b.HasKey("Id") + .HasName("PK_admin_messages"); + + b.HasIndex("CreatedById"); + + b.HasIndex("DeletedById"); + + b.HasIndex("LastEditedById"); + + b.HasIndex("PlayerUserId") + .HasDatabaseName("IX_admin_messages_player_user_id"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_admin_messages_round_id"); + + b.ToTable("admin_messages", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminNote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("admin_notes_id"); + + b.Property("CreatedAt") + .HasColumnType("TEXT") + .HasColumnName("created_at"); + + b.Property("CreatedById") + .HasColumnType("TEXT") + .HasColumnName("created_by_id"); + + b.Property("Deleted") + .HasColumnType("INTEGER") + .HasColumnName("deleted"); + + b.Property("DeletedAt") + .HasColumnType("TEXT") + .HasColumnName("deleted_at"); + + b.Property("DeletedById") + .HasColumnType("TEXT") + .HasColumnName("deleted_by_id"); + + b.Property("ExpirationTime") + .HasColumnType("TEXT") + .HasColumnName("expiration_time"); + + b.Property("LastEditedAt") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("last_edited_at"); + + b.Property("LastEditedById") + .HasColumnType("TEXT") + .HasColumnName("last_edited_by_id"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("TEXT") + .HasColumnName("message"); + + b.Property("PlayerUserId") + .HasColumnType("TEXT") + .HasColumnName("player_user_id"); + + b.Property("PlaytimeAtNote") + .HasColumnType("TEXT") + .HasColumnName("playtime_at_note"); + + b.Property("RoundId") + .HasColumnType("INTEGER") + .HasColumnName("round_id"); + + b.Property("Secret") + .HasColumnType("INTEGER") + .HasColumnName("secret"); + + b.Property("Severity") + .HasColumnType("INTEGER") + .HasColumnName("severity"); + + b.HasKey("Id") + .HasName("PK_admin_notes"); + + b.HasIndex("CreatedById"); + + b.HasIndex("DeletedById"); + + b.HasIndex("LastEditedById"); + + b.HasIndex("PlayerUserId") + .HasDatabaseName("IX_admin_notes_player_user_id"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_admin_notes_round_id"); + + b.ToTable("admin_notes", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRank", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("admin_rank_id"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("PK_admin_rank"); + + b.ToTable("admin_rank", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRankFlag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("admin_rank_flag_id"); + + b.Property("AdminRankId") + .HasColumnType("INTEGER") + .HasColumnName("admin_rank_id"); + + b.Property("Flag") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("flag"); + + b.HasKey("Id") + .HasName("PK_admin_rank_flag"); + + b.HasIndex("AdminRankId"); + + b.HasIndex("Flag", "AdminRankId") + .IsUnique(); + + b.ToTable("admin_rank_flag", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminWatchlist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("admin_watchlists_id"); + + b.Property("CreatedAt") + .HasColumnType("TEXT") + .HasColumnName("created_at"); + + b.Property("CreatedById") + .HasColumnType("TEXT") + .HasColumnName("created_by_id"); + + b.Property("Deleted") + .HasColumnType("INTEGER") + .HasColumnName("deleted"); + + b.Property("DeletedAt") + .HasColumnType("TEXT") + .HasColumnName("deleted_at"); + + b.Property("DeletedById") + .HasColumnType("TEXT") + .HasColumnName("deleted_by_id"); + + b.Property("ExpirationTime") + .HasColumnType("TEXT") + .HasColumnName("expiration_time"); + + b.Property("LastEditedAt") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("last_edited_at"); + + b.Property("LastEditedById") + .HasColumnType("TEXT") + .HasColumnName("last_edited_by_id"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("TEXT") + .HasColumnName("message"); + + b.Property("PlayerUserId") + .HasColumnType("TEXT") + .HasColumnName("player_user_id"); + + b.Property("PlaytimeAtNote") + .HasColumnType("TEXT") + .HasColumnName("playtime_at_note"); + + b.Property("RoundId") + .HasColumnType("INTEGER") + .HasColumnName("round_id"); + + b.HasKey("Id") + .HasName("PK_admin_watchlists"); + + b.HasIndex("CreatedById"); + + b.HasIndex("DeletedById"); + + b.HasIndex("LastEditedById"); + + b.HasIndex("PlayerUserId") + .HasDatabaseName("IX_admin_watchlists_player_user_id"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_admin_watchlists_round_id"); + + b.ToTable("admin_watchlists", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Antag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("antag_id"); + + b.Property("AntagName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("antag_name"); + + b.Property("ProfileId") + .HasColumnType("INTEGER") + .HasColumnName("profile_id"); + + b.HasKey("Id") + .HasName("PK_antag"); + + b.HasIndex("ProfileId", "AntagName") + .IsUnique(); + + b.ToTable("antag", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AssignedUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("assigned_user_id_id"); + + b.Property("UserId") + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("user_name"); + + b.HasKey("Id") + .HasName("PK_assigned_user_id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.HasIndex("UserName") + .IsUnique(); + + b.ToTable("assigned_user_id", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.ConnectionLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("connection_log_id"); + + b.Property("Address") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("address"); + + b.Property("Denied") + .HasColumnType("INTEGER") + .HasColumnName("denied"); + + b.Property("HWId") + .HasColumnType("BLOB") + .HasColumnName("hwid"); + + b.Property("Time") + .HasColumnType("TEXT") + .HasColumnName("time"); + + b.Property("UserId") + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("user_name"); + + b.HasKey("Id") + .HasName("PK_connection_log"); + + b.HasIndex("UserId"); + + b.ToTable("connection_log", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Job", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("job_id"); + + b.Property("JobName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("job_name"); + + b.Property("Priority") + .HasColumnType("INTEGER") + .HasColumnName("priority"); + + b.Property("ProfileId") + .HasColumnType("INTEGER") + .HasColumnName("profile_id"); + + b.HasKey("Id") + .HasName("PK_job"); + + b.HasIndex("ProfileId"); + + b.HasIndex("ProfileId", "JobName") + .IsUnique(); + + b.HasIndex(new[] { "ProfileId" }, "IX_job_one_high_priority") + .IsUnique() + .HasFilter("priority = 3"); + + b.ToTable("job", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.PlayTime", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("play_time_id"); + + b.Property("PlayerId") + .HasColumnType("TEXT") + .HasColumnName("player_id"); + + b.Property("TimeSpent") + .HasColumnType("TEXT") + .HasColumnName("time_spent"); + + b.Property("Tracker") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("tracker"); + + b.HasKey("Id") + .HasName("PK_play_time"); + + b.HasIndex("PlayerId", "Tracker") + .IsUnique(); + + b.ToTable("play_time", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Player", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("player_id"); + + b.Property("FirstSeenTime") + .HasColumnType("TEXT") + .HasColumnName("first_seen_time"); + + b.Property("LastReadRules") + .HasColumnType("TEXT") + .HasColumnName("last_read_rules"); + + b.Property("LastSeenAddress") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("last_seen_address"); + + b.Property("LastSeenHWId") + .HasColumnType("BLOB") + .HasColumnName("last_seen_hwid"); + + b.Property("LastSeenTime") + .HasColumnType("TEXT") + .HasColumnName("last_seen_time"); + + b.Property("LastSeenUserName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("last_seen_user_name"); + + b.Property("UserId") + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("PK_player"); + + b.HasAlternateKey("UserId") + .HasName("ak_player_user_id"); + + b.HasIndex("LastSeenUserName"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("player", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Preference", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("preference_id"); + + b.Property("AdminOOCColor") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("admin_ooc_color"); + + b.Property("SelectedCharacterSlot") + .HasColumnType("INTEGER") + .HasColumnName("selected_character_slot"); + + b.Property("UserId") + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("PK_preference"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("preference", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Profile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("profile_id"); + + b.Property("Age") + .HasColumnType("INTEGER") + .HasColumnName("age"); + + b.Property("Backpack") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("backpack"); + + b.Property("CharacterName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("char_name"); + + b.Property("Clothing") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("clothing"); + + b.Property("EyeColor") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("eye_color"); + + b.Property("FacialHairColor") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("facial_hair_color"); + + b.Property("FacialHairName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("facial_hair_name"); + + b.Property("FlavorText") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("flavor_text"); + + b.Property("Gender") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("gender"); + + b.Property("HairColor") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("hair_color"); + + b.Property("HairName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("hair_name"); + + b.Property("Markings") + .HasColumnType("jsonb") + .HasColumnName("markings"); + + b.Property("PreferenceId") + .HasColumnType("INTEGER") + .HasColumnName("preference_id"); + + b.Property("PreferenceUnavailable") + .HasColumnType("INTEGER") + .HasColumnName("pref_unavailable"); + + b.Property("Sex") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("sex"); + + b.Property("SkinColor") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("skin_color"); + + b.Property("Slot") + .HasColumnType("INTEGER") + .HasColumnName("slot"); + + b.Property("Species") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("species"); + + b.HasKey("Id") + .HasName("PK_profile"); + + b.HasIndex("PreferenceId") + .HasDatabaseName("IX_profile_preference_id"); + + b.HasIndex("Slot", "PreferenceId") + .IsUnique(); + + b.ToTable("profile", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Round", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("round_id"); + + b.Property("ServerId") + .HasColumnType("INTEGER") + .HasColumnName("server_id"); + + b.Property("StartDate") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasDefaultValue(new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)) + .HasColumnName("start_date"); + + b.HasKey("Id") + .HasName("PK_round"); + + b.HasIndex("ServerId") + .HasDatabaseName("IX_round_server_id"); + + b.HasIndex("StartDate"); + + b.ToTable("round", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Server", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("server_id"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("PK_server"); + + b.ToTable("server", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("server_ban_id"); + + b.Property("Address") + .HasColumnType("TEXT") + .HasColumnName("address"); + + b.Property("AutoDelete") + .HasColumnType("INTEGER") + .HasColumnName("auto_delete"); + + b.Property("BanTime") + .HasColumnType("TEXT") + .HasColumnName("ban_time"); + + b.Property("BanningAdmin") + .HasColumnType("TEXT") + .HasColumnName("banning_admin"); + + b.Property("ExemptFlags") + .HasColumnType("INTEGER") + .HasColumnName("exempt_flags"); + + b.Property("ExpirationTime") + .HasColumnType("TEXT") + .HasColumnName("expiration_time"); + + b.Property("HWId") + .HasColumnType("BLOB") + .HasColumnName("hwid"); + + b.Property("Hidden") + .HasColumnType("INTEGER") + .HasColumnName("hidden"); + + b.Property("LastEditedAt") + .HasColumnType("TEXT") + .HasColumnName("last_edited_at"); + + b.Property("LastEditedById") + .HasColumnType("TEXT") + .HasColumnName("last_edited_by_id"); + + b.Property("PlayerUserId") + .HasColumnType("TEXT") + .HasColumnName("player_user_id"); + + b.Property("PlaytimeAtNote") + .HasColumnType("TEXT") + .HasColumnName("playtime_at_note"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("reason"); + + b.Property("RoundId") + .HasColumnType("INTEGER") + .HasColumnName("round_id"); + + b.Property("Severity") + .HasColumnType("INTEGER") + .HasColumnName("severity"); + + b.HasKey("Id") + .HasName("PK_server_ban"); + + b.HasIndex("Address"); + + b.HasIndex("BanningAdmin"); + + b.HasIndex("LastEditedById"); + + b.HasIndex("PlayerUserId") + .HasDatabaseName("IX_server_ban_player_user_id"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_server_ban_round_id"); + + b.ToTable("server_ban", null, t => + { + t.HasCheckConstraint("HaveEitherAddressOrUserIdOrHWId", "address IS NOT NULL OR player_user_id IS NOT NULL OR hwid IS NOT NULL"); + }); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBanExemption", b => + { + b.Property("UserId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.Property("Flags") + .HasColumnType("INTEGER") + .HasColumnName("flags"); + + b.HasKey("UserId") + .HasName("PK_server_ban_exemption"); + + b.ToTable("server_ban_exemption", null, t => + { + t.HasCheckConstraint("FlagsNotZero", "flags != 0"); + }); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBanHit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("server_ban_hit_id"); + + b.Property("BanId") + .HasColumnType("INTEGER") + .HasColumnName("ban_id"); + + b.Property("ConnectionId") + .HasColumnType("INTEGER") + .HasColumnName("connection_id"); + + b.HasKey("Id") + .HasName("PK_server_ban_hit"); + + b.HasIndex("BanId") + .HasDatabaseName("IX_server_ban_hit_ban_id"); + + b.HasIndex("ConnectionId") + .HasDatabaseName("IX_server_ban_hit_connection_id"); + + b.ToTable("server_ban_hit", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.ServerRoleBan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("server_role_ban_id"); + + b.Property("Address") + .HasColumnType("TEXT") + .HasColumnName("address"); + + b.Property("BanTime") + .HasColumnType("TEXT") + .HasColumnName("ban_time"); + + b.Property("BanningAdmin") + .HasColumnType("TEXT") + .HasColumnName("banning_admin"); + + b.Property("ExpirationTime") + .HasColumnType("TEXT") + .HasColumnName("expiration_time"); + + b.Property("HWId") + .HasColumnType("BLOB") + .HasColumnName("hwid"); + + b.Property("Hidden") + .HasColumnType("INTEGER") + .HasColumnName("hidden"); + + b.Property("LastEditedAt") + .HasColumnType("TEXT") + .HasColumnName("last_edited_at"); + + b.Property("LastEditedById") + .HasColumnType("TEXT") + .HasColumnName("last_edited_by_id"); + + b.Property("PlayerUserId") + .HasColumnType("TEXT") + .HasColumnName("player_user_id"); + + b.Property("PlaytimeAtNote") + .HasColumnType("TEXT") + .HasColumnName("playtime_at_note"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("reason"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("role_id"); + + b.Property("RoundId") + .HasColumnType("INTEGER") + .HasColumnName("round_id"); + + b.Property("Severity") + .HasColumnType("INTEGER") + .HasColumnName("severity"); + + b.HasKey("Id") + .HasName("PK_server_role_ban"); + + b.HasIndex("Address"); + + b.HasIndex("BanningAdmin"); + + b.HasIndex("LastEditedById"); + + b.HasIndex("PlayerUserId") + .HasDatabaseName("IX_server_role_ban_player_user_id"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_server_role_ban_round_id"); + + b.ToTable("server_role_ban", null, t => + { + t.HasCheckConstraint("HaveEitherAddressOrUserIdOrHWId", "address IS NOT NULL OR player_user_id IS NOT NULL OR hwid IS NOT NULL"); + }); + }); + + modelBuilder.Entity("Content.Server.Database.ServerRoleUnban", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("role_unban_id"); + + b.Property("BanId") + .HasColumnType("INTEGER") + .HasColumnName("ban_id"); + + b.Property("UnbanTime") + .HasColumnType("TEXT") + .HasColumnName("unban_time"); + + b.Property("UnbanningAdmin") + .HasColumnType("TEXT") + .HasColumnName("unbanning_admin"); + + b.HasKey("Id") + .HasName("PK_server_role_unban"); + + b.HasIndex("BanId") + .IsUnique(); + + b.ToTable("server_role_unban", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.ServerUnban", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("unban_id"); + + b.Property("BanId") + .HasColumnType("INTEGER") + .HasColumnName("ban_id"); + + b.Property("UnbanTime") + .HasColumnType("TEXT") + .HasColumnName("unban_time"); + + b.Property("UnbanningAdmin") + .HasColumnType("TEXT") + .HasColumnName("unbanning_admin"); + + b.HasKey("Id") + .HasName("PK_server_unban"); + + b.HasIndex("BanId") + .IsUnique(); + + b.ToTable("server_unban", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Trait", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("trait_id"); + + b.Property("ProfileId") + .HasColumnType("INTEGER") + .HasColumnName("profile_id"); + + b.Property("TraitName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("trait_name"); + + b.HasKey("Id") + .HasName("PK_trait"); + + b.HasIndex("ProfileId", "TraitName") + .IsUnique(); + + b.ToTable("trait", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.UploadedResourceLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("uploaded_resource_log_id"); + + b.Property("Data") + .IsRequired() + .HasColumnType("BLOB") + .HasColumnName("data"); + + b.Property("Date") + .HasColumnType("TEXT") + .HasColumnName("date"); + + b.Property("Path") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("path"); + + b.Property("UserId") + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("PK_uploaded_resource_log"); + + b.ToTable("uploaded_resource_log", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Whitelist", b => + { + b.Property("UserId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.HasKey("UserId") + .HasName("PK_whitelist"); + + b.ToTable("whitelist", (string)null); + }); + + modelBuilder.Entity("PlayerRound", b => + { + b.Property("PlayersId") + .HasColumnType("INTEGER") + .HasColumnName("players_id"); + + b.Property("RoundsId") + .HasColumnType("INTEGER") + .HasColumnName("rounds_id"); + + b.HasKey("PlayersId", "RoundsId") + .HasName("PK_player_round"); + + b.HasIndex("RoundsId") + .HasDatabaseName("IX_player_round_rounds_id"); + + b.ToTable("player_round", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Admin", b => + { + b.HasOne("Content.Server.Database.AdminRank", "AdminRank") + .WithMany("Admins") + .HasForeignKey("AdminRankId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_admin_rank_admin_rank_id"); + + b.Navigation("AdminRank"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminFlag", b => + { + b.HasOne("Content.Server.Database.Admin", "Admin") + .WithMany("Flags") + .HasForeignKey("AdminId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_admin_flag_admin_admin_id"); + + b.Navigation("Admin"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLog", b => + { + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany("AdminLogs") + .HasForeignKey("RoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_admin_log_round_round_id"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLogEntity", b => + { + b.HasOne("Content.Server.Database.AdminLog", null) + .WithMany("Entities") + .HasForeignKey("AdminLogId", "AdminLogRoundId") + .HasConstraintName("FK_admin_log_entity_admin_log_admin_log_id_admin_log_round_id"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLogPlayer", b => + { + b.HasOne("Content.Server.Database.Player", "Player") + .WithMany("AdminLogs") + .HasForeignKey("PlayerUserId") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_admin_log_player_player_player_user_id"); + + b.HasOne("Content.Server.Database.AdminLog", "Log") + .WithMany("Players") + .HasForeignKey("LogId", "RoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_admin_log_player_admin_log_log_id_round_id"); + + b.Navigation("Log"); + + b.Navigation("Player"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminMessage", b => + { + b.HasOne("Content.Server.Database.Player", "CreatedBy") + .WithMany("AdminMessagesCreated") + .HasForeignKey("CreatedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_messages_player_created_by_id"); + + b.HasOne("Content.Server.Database.Player", "DeletedBy") + .WithMany("AdminMessagesDeleted") + .HasForeignKey("DeletedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_messages_player_deleted_by_id"); + + b.HasOne("Content.Server.Database.Player", "LastEditedBy") + .WithMany("AdminMessagesLastEdited") + .HasForeignKey("LastEditedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_messages_player_last_edited_by_id"); + + b.HasOne("Content.Server.Database.Player", "Player") + .WithMany("AdminMessagesReceived") + .HasForeignKey("PlayerUserId") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("FK_admin_messages_player_player_user_id"); + + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany() + .HasForeignKey("RoundId") + .HasConstraintName("FK_admin_messages_round_round_id"); + + b.Navigation("CreatedBy"); + + b.Navigation("DeletedBy"); + + b.Navigation("LastEditedBy"); + + b.Navigation("Player"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminNote", b => + { + b.HasOne("Content.Server.Database.Player", "CreatedBy") + .WithMany("AdminNotesCreated") + .HasForeignKey("CreatedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_notes_player_created_by_id"); + + b.HasOne("Content.Server.Database.Player", "DeletedBy") + .WithMany("AdminNotesDeleted") + .HasForeignKey("DeletedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_notes_player_deleted_by_id"); + + b.HasOne("Content.Server.Database.Player", "LastEditedBy") + .WithMany("AdminNotesLastEdited") + .HasForeignKey("LastEditedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_notes_player_last_edited_by_id"); + + b.HasOne("Content.Server.Database.Player", "Player") + .WithMany("AdminNotesReceived") + .HasForeignKey("PlayerUserId") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("FK_admin_notes_player_player_user_id"); + + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany() + .HasForeignKey("RoundId") + .HasConstraintName("FK_admin_notes_round_round_id"); + + b.Navigation("CreatedBy"); + + b.Navigation("DeletedBy"); + + b.Navigation("LastEditedBy"); + + b.Navigation("Player"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRankFlag", b => + { + b.HasOne("Content.Server.Database.AdminRank", "Rank") + .WithMany("Flags") + .HasForeignKey("AdminRankId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_admin_rank_flag_admin_rank_admin_rank_id"); + + b.Navigation("Rank"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminWatchlist", b => + { + b.HasOne("Content.Server.Database.Player", "CreatedBy") + .WithMany("AdminWatchlistsCreated") + .HasForeignKey("CreatedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_watchlists_player_created_by_id"); + + b.HasOne("Content.Server.Database.Player", "DeletedBy") + .WithMany("AdminWatchlistsDeleted") + .HasForeignKey("DeletedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_watchlists_player_deleted_by_id"); + + b.HasOne("Content.Server.Database.Player", "LastEditedBy") + .WithMany("AdminWatchlistsLastEdited") + .HasForeignKey("LastEditedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_watchlists_player_last_edited_by_id"); + + b.HasOne("Content.Server.Database.Player", "Player") + .WithMany("AdminWatchlistsReceived") + .HasForeignKey("PlayerUserId") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("FK_admin_watchlists_player_player_user_id"); + + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany() + .HasForeignKey("RoundId") + .HasConstraintName("FK_admin_watchlists_round_round_id"); + + b.Navigation("CreatedBy"); + + b.Navigation("DeletedBy"); + + b.Navigation("LastEditedBy"); + + b.Navigation("Player"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.Antag", b => + { + b.HasOne("Content.Server.Database.Profile", "Profile") + .WithMany("Antags") + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_antag_profile_profile_id"); + + b.Navigation("Profile"); + }); + + modelBuilder.Entity("Content.Server.Database.Job", b => + { + b.HasOne("Content.Server.Database.Profile", "Profile") + .WithMany("Jobs") + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_job_profile_profile_id"); + + b.Navigation("Profile"); + }); + + modelBuilder.Entity("Content.Server.Database.Profile", b => + { + b.HasOne("Content.Server.Database.Preference", "Preference") + .WithMany("Profiles") + .HasForeignKey("PreferenceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_profile_preference_preference_id"); + + b.Navigation("Preference"); + }); + + modelBuilder.Entity("Content.Server.Database.Round", b => + { + b.HasOne("Content.Server.Database.Server", "Server") + .WithMany("Rounds") + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_round_server_server_id"); + + b.Navigation("Server"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBan", b => + { + b.HasOne("Content.Server.Database.Player", "CreatedBy") + .WithMany("AdminServerBansCreated") + .HasForeignKey("BanningAdmin") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_server_ban_player_banning_admin"); + + b.HasOne("Content.Server.Database.Player", "LastEditedBy") + .WithMany("AdminServerBansLastEdited") + .HasForeignKey("LastEditedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_server_ban_player_last_edited_by_id"); + + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany() + .HasForeignKey("RoundId") + .HasConstraintName("FK_server_ban_round_round_id"); + + b.Navigation("CreatedBy"); + + b.Navigation("LastEditedBy"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBanHit", b => + { + b.HasOne("Content.Server.Database.ServerBan", "Ban") + .WithMany("BanHits") + .HasForeignKey("BanId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_server_ban_hit_server_ban_ban_id"); + + b.HasOne("Content.Server.Database.ConnectionLog", "Connection") + .WithMany("BanHits") + .HasForeignKey("ConnectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_server_ban_hit_connection_log_connection_id"); + + b.Navigation("Ban"); + + b.Navigation("Connection"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerRoleBan", b => + { + b.HasOne("Content.Server.Database.Player", "CreatedBy") + .WithMany("AdminServerRoleBansCreated") + .HasForeignKey("BanningAdmin") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_server_role_ban_player_banning_admin"); + + b.HasOne("Content.Server.Database.Player", "LastEditedBy") + .WithMany("AdminServerRoleBansLastEdited") + .HasForeignKey("LastEditedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_server_role_ban_player_last_edited_by_id"); + + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany() + .HasForeignKey("RoundId") + .HasConstraintName("FK_server_role_ban_round_round_id"); + + b.Navigation("CreatedBy"); + + b.Navigation("LastEditedBy"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerRoleUnban", b => + { + b.HasOne("Content.Server.Database.ServerRoleBan", "Ban") + .WithOne("Unban") + .HasForeignKey("Content.Server.Database.ServerRoleUnban", "BanId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_server_role_unban_server_role_ban_ban_id"); + + b.Navigation("Ban"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerUnban", b => + { + b.HasOne("Content.Server.Database.ServerBan", "Ban") + .WithOne("Unban") + .HasForeignKey("Content.Server.Database.ServerUnban", "BanId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_server_unban_server_ban_ban_id"); + + b.Navigation("Ban"); + }); + + modelBuilder.Entity("Content.Server.Database.Trait", b => + { + b.HasOne("Content.Server.Database.Profile", "Profile") + .WithMany("Traits") + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_trait_profile_profile_id"); + + b.Navigation("Profile"); + }); + + modelBuilder.Entity("PlayerRound", b => + { + b.HasOne("Content.Server.Database.Player", null) + .WithMany() + .HasForeignKey("PlayersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_player_round_player_players_id"); + + b.HasOne("Content.Server.Database.Round", null) + .WithMany() + .HasForeignKey("RoundsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_player_round_round_rounds_id"); + }); + + modelBuilder.Entity("Content.Server.Database.Admin", b => + { + b.Navigation("Flags"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLog", b => + { + b.Navigation("Entities"); + + b.Navigation("Players"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRank", b => + { + b.Navigation("Admins"); + + b.Navigation("Flags"); + }); + + modelBuilder.Entity("Content.Server.Database.ConnectionLog", b => + { + b.Navigation("BanHits"); + }); + + modelBuilder.Entity("Content.Server.Database.Player", b => + { + b.Navigation("AdminLogs"); + + b.Navigation("AdminMessagesCreated"); + + b.Navigation("AdminMessagesDeleted"); + + b.Navigation("AdminMessagesLastEdited"); + + b.Navigation("AdminMessagesReceived"); + + b.Navigation("AdminNotesCreated"); + + b.Navigation("AdminNotesDeleted"); + + b.Navigation("AdminNotesLastEdited"); + + b.Navigation("AdminNotesReceived"); + + b.Navigation("AdminServerBansCreated"); + + b.Navigation("AdminServerBansLastEdited"); + + b.Navigation("AdminServerRoleBansCreated"); + + b.Navigation("AdminServerRoleBansLastEdited"); + + b.Navigation("AdminWatchlistsCreated"); + + b.Navigation("AdminWatchlistsDeleted"); + + b.Navigation("AdminWatchlistsLastEdited"); + + b.Navigation("AdminWatchlistsReceived"); + }); + + modelBuilder.Entity("Content.Server.Database.Preference", b => + { + b.Navigation("Profiles"); + }); + + modelBuilder.Entity("Content.Server.Database.Profile", b => + { + b.Navigation("Antags"); + + b.Navigation("Jobs"); + + b.Navigation("Traits"); + }); + + modelBuilder.Entity("Content.Server.Database.Round", b => + { + b.Navigation("AdminLogs"); + }); + + modelBuilder.Entity("Content.Server.Database.Server", b => + { + b.Navigation("Rounds"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBan", b => + { + b.Navigation("BanHits"); + + b.Navigation("Unban"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerRoleBan", b => + { + b.Navigation("Unban"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Content.Server.Database/Migrations/Sqlite/20231021071407_RoundStartDate.cs b/Content.Server.Database/Migrations/Sqlite/20231021071407_RoundStartDate.cs new file mode 100644 index 0000000000..0948bd99f1 --- /dev/null +++ b/Content.Server.Database/Migrations/Sqlite/20231021071407_RoundStartDate.cs @@ -0,0 +1,39 @@ +#nullable disable + +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Content.Server.Database.Migrations.Sqlite +{ + /// + public partial class RoundStartDate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "start_date", + table: "round", + type: "TEXT", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.CreateIndex( + name: "IX_round_start_date", + table: "round", + column: "start_date"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_round_start_date", + table: "round"); + + migrationBuilder.DropColumn( + name: "start_date", + table: "round"); + } + } +} diff --git a/Content.Server.Database/Migrations/Sqlite/SqliteServerDbContextModelSnapshot.cs b/Content.Server.Database/Migrations/Sqlite/SqliteServerDbContextModelSnapshot.cs index 87b8de7fda..c20743b94d 100644 --- a/Content.Server.Database/Migrations/Sqlite/SqliteServerDbContextModelSnapshot.cs +++ b/Content.Server.Database/Migrations/Sqlite/SqliteServerDbContextModelSnapshot.cs @@ -806,12 +806,20 @@ namespace Content.Server.Database.Migrations.Sqlite .HasColumnType("INTEGER") .HasColumnName("server_id"); + b.Property("StartDate") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasDefaultValue(new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)) + .HasColumnName("start_date"); + b.HasKey("Id") .HasName("PK_round"); b.HasIndex("ServerId") .HasDatabaseName("IX_round_server_id"); + b.HasIndex("StartDate"); + b.ToTable("round", (string)null); }); diff --git a/Content.Server.Database/Model.cs b/Content.Server.Database/Model.cs index 489ce5d831..c2d2ea98dc 100644 --- a/Content.Server.Database/Model.cs +++ b/Content.Server.Database/Model.cs @@ -111,6 +111,13 @@ namespace Content.Server.Database .HasForeignKey(player => player.PlayerUserId) .HasPrincipalKey(player => player.UserId); + modelBuilder.Entity() + .HasIndex(round => round.StartDate); + + modelBuilder.Entity() + .Property(round => round.StartDate) + .HasDefaultValue(default(DateTime)); + modelBuilder.Entity() .HasKey(logPlayer => new {logPlayer.PlayerUserId, logPlayer.LogId, logPlayer.RoundId}); @@ -468,6 +475,8 @@ namespace Content.Server.Database [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } + public DateTime StartDate { get; set; } + public List Players { get; set; } = default!; public List AdminLogs { get; set; } = default!; diff --git a/Content.Server/Database/ServerDbBase.cs b/Content.Server/Database/ServerDbBase.cs index aeebc64f07..235072603e 100644 --- a/Content.Server/Database/ServerDbBase.cs +++ b/Content.Server/Database/ServerDbBase.cs @@ -677,6 +677,7 @@ namespace Content.Server.Database var round = new Round { + StartDate = DateTime.UtcNow, Players = players, ServerId = server.Id }; From 52e1d64ee2720f7226117e37ef1cb4a4488efd49 Mon Sep 17 00:00:00 2001 From: DrSmugleaf Date: Sun, 22 Oct 2023 21:24:03 -0700 Subject: [PATCH 003/102] Stop all reads/writes to the admin_log_entity table (#21186) --- Content.Server.Database/Model.cs | 2 ++ .../Logs/AdminLogManager.Json.cs | 20 +++---------------- .../Administration/Logs/AdminLogManager.cs | 9 ++++----- 3 files changed, 9 insertions(+), 22 deletions(-) diff --git a/Content.Server.Database/Model.cs b/Content.Server.Database/Model.cs index c2d2ea98dc..298f849b47 100644 --- a/Content.Server.Database/Model.cs +++ b/Content.Server.Database/Model.cs @@ -517,6 +517,7 @@ namespace Content.Server.Database public List Players { get; set; } = default!; + // Unused public List Entities { get; set; } = default!; } @@ -530,6 +531,7 @@ namespace Content.Server.Database [ForeignKey("LogId,RoundId")] public AdminLog Log { get; set; } = default!; } + // Unused public class AdminLogEntity { [Required, Key] public int Uid { get; set; } diff --git a/Content.Server/Administration/Logs/AdminLogManager.Json.cs b/Content.Server/Administration/Logs/AdminLogManager.Json.cs index 43a1e0b8b5..63f30c7a66 100644 --- a/Content.Server/Administration/Logs/AdminLogManager.Json.cs +++ b/Content.Server/Administration/Logs/AdminLogManager.Json.cs @@ -2,7 +2,6 @@ using System.Text.Json; using System.Text.Json.Serialization; using Content.Server.Administration.Logs.Converters; -using Content.Server.Database; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Map; @@ -34,10 +33,9 @@ public sealed partial class AdminLogManager _sawmill.Debug($"Admin log converters found: {string.Join(" ", converterNames)}"); } - private (JsonDocument Json, HashSet Players, List Entities) ToJson( + private (JsonDocument Json, HashSet Players) ToJson( Dictionary properties) { - var entities = new Dictionary(); var players = new HashSet(); var parsed = new Dictionary(); @@ -63,24 +61,12 @@ public sealed partial class AdminLogManager _ => null }; - if (entityId is not { } uid) - { - continue; - } - - var entityName = _entityManager.TryGetComponent(uid, out MetaDataComponent? metadata) - ? metadata.EntityName - : null; - - // TODO set the id too whenever we feel like running a migration for 10 hours - entities.TryAdd(uid, new AdminLogEntity { Name = entityName }); - - if (_entityManager.TryGetComponent(uid, out ActorComponent? actor)) + if (_entityManager.TryGetComponent(entityId, out ActorComponent? actor)) { players.Add(actor.PlayerSession.UserId.UserId); } } - return (JsonSerializer.SerializeToDocument(parsed, _jsonOptions), players, entities.Values.ToList()); + return (JsonSerializer.SerializeToDocument(parsed, _jsonOptions), players); } } diff --git a/Content.Server/Administration/Logs/AdminLogManager.cs b/Content.Server/Administration/Logs/AdminLogManager.cs index 06f58f10b2..e869d089da 100644 --- a/Content.Server/Administration/Logs/AdminLogManager.cs +++ b/Content.Server/Administration/Logs/AdminLogManager.cs @@ -278,7 +278,7 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa } } - private void Add(LogType type, LogImpact impact, string message, JsonDocument json, HashSet players, List entities) + private void Add(LogType type, LogImpact impact, string message, JsonDocument json, HashSet players) { var preRound = _runLevel == GameRunLevel.PreRoundLobby; var count = preRound ? _preRoundLogQueue.Count : _logQueue.Count; @@ -297,8 +297,7 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa Date = DateTime.UtcNow, Message = message, Json = json, - Players = new List(players.Count), - Entities = entities + Players = new List(players.Count) }; foreach (var id in players) @@ -331,10 +330,10 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa return; } - var (json, players, entities) = ToJson(handler.Values); + var (json, players) = ToJson(handler.Values); var message = handler.ToStringAndClear(); - Add(type, impact, message, json, players, entities); + Add(type, impact, message, json, players); } public override void Add(LogType type, ref LogStringHandler handler) From 33935c5ce893c18622bedcdf9ab8ba6e85754092 Mon Sep 17 00:00:00 2001 From: Nairod <110078045+Nairodian@users.noreply.github.com> Date: Mon, 23 Oct 2023 08:09:53 -0500 Subject: [PATCH 004/102] Increase Ninja Suit Weight (#21188) --- Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml index 0a729ca0e2..16bef8c7b2 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml @@ -92,7 +92,7 @@ - type: GroupExamine - type: entity - parent: ClothingOuterBase + parent: ClothingOuterBaseLarge id: ClothingOuterSuitSpaceNinja name: space ninja suit description: This black technologically advanced, cybernetically-enhanced suit provides many abilities like invisibility or teleportation. From 46a3076ecb89359d7c642bed635af42350a44cd5 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Tue, 24 Oct 2023 00:20:33 +1100 Subject: [PATCH 005/102] Predict tile-prying (#21167) --- Content.Client/Tools/ToolSystem.cs | 1 + .../Commands/VariantizeCommand.cs | 12 ++-- .../Atmos/EntitySystems/AtmosphereSystem.cs | 1 + .../Construction/ConstructionSystem.cs | 1 + Content.Server/Construction/RefiningSystem.cs | 1 + Content.Server/Decals/DecalSystem.cs | 4 +- .../DeviceLinking/Systems/LogicGateSystem.cs | 1 + Content.Server/Interaction/TilePryCommand.cs | 3 +- Content.Server/Medical/CryoPodSystem.cs | 1 + .../Power/EntitySystems/CableSystem.cs | 2 + Content.Server/Repairable/RepairableSystem.cs | 1 + .../EntitySystems/RevenantSystem.Abilities.cs | 1 + Content.Server/Toilet/ToiletSystem.cs | 1 + .../Tools/Components/TilePryingComponent.cs | 25 --------- .../Tools/ToolSystem.LatticeCutting.cs | 6 +- Content.Server/Tools/ToolSystem.cs | 3 +- Content.Server/Wires/WiresSystem.cs | 1 + .../Debris/BlobFloorPlanBuilderSystem.cs | 5 +- .../Debris/DebrisFeaturePlacerSystem.cs | 2 +- .../EntitySystems/AnchorableSystem.cs | 1 + Content.Shared/Decals/SharedDecalSystem.cs | 13 +++++ .../Maps/TileSystem.cs | 56 ++++++++++++++----- Content.Shared/Maps/TurfHelpers.cs | 24 -------- .../EntitySystems/EncryptionKeySystem.cs | 1 + .../Tools/Components/TilePryingComponent.cs | 26 +++++++++ .../Systems/SharedToolSystem.MultipleTool.cs | 4 +- .../Systems/SharedToolSystem.TilePrying.cs | 36 ++++++------ .../Tools/Systems/SharedToolSystem.cs | 23 ++++++-- 28 files changed, 154 insertions(+), 102 deletions(-) delete mode 100644 Content.Server/Tools/Components/TilePryingComponent.cs rename {Content.Server => Content.Shared}/Maps/TileSystem.cs (68%) create mode 100644 Content.Shared/Tools/Components/TilePryingComponent.cs rename Content.Server/Tools/ToolSystem.TilePrying.cs => Content.Shared/Tools/Systems/SharedToolSystem.TilePrying.cs (66%) diff --git a/Content.Client/Tools/ToolSystem.cs b/Content.Client/Tools/ToolSystem.cs index f4dc480b41..966f37146e 100644 --- a/Content.Client/Tools/ToolSystem.cs +++ b/Content.Client/Tools/ToolSystem.cs @@ -5,6 +5,7 @@ using Content.Shared.Tools; using Content.Shared.Tools.Components; using Robust.Client.GameObjects; using Robust.Shared.GameStates; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Client.Tools { diff --git a/Content.Server/Administration/Commands/VariantizeCommand.cs b/Content.Server/Administration/Commands/VariantizeCommand.cs index 1b5cbbd4d5..7aabd76335 100644 --- a/Content.Server/Administration/Commands/VariantizeCommand.cs +++ b/Content.Server/Administration/Commands/VariantizeCommand.cs @@ -12,6 +12,7 @@ public sealed class VariantizeCommand : IConsoleCommand { [Dependency] private readonly IEntityManager _entManager = default!; [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly ITileDefinitionManager _tileDefManager = default!; public string Command => "variantize"; @@ -39,11 +40,14 @@ public sealed class VariantizeCommand : IConsoleCommand return; } - foreach (var tile in gridComp.GetAllTiles()) + var mapsSystem = _entManager.System(); + var tileSystem = _entManager.System(); + + foreach (var tile in mapsSystem.GetAllTiles(euid.Value, gridComp)) { - var def = tile.GetContentTileDefinition(); - var newTile = new Tile(tile.Tile.TypeId, tile.Tile.Flags, def.PickVariant(_random)); - gridComp.SetTile(tile.GridIndices, newTile); + var def = tile.GetContentTileDefinition(_tileDefManager); + var newTile = new Tile(tile.Tile.TypeId, tile.Tile.Flags, tileSystem.PickVariant(def)); + mapsSystem.SetTile(euid.Value, gridComp, tile.GridIndices, newTile); } } } diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs index 91634de8d7..d8364b652b 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs @@ -4,6 +4,7 @@ using Content.Server.Body.Systems; using Content.Server.Maps; using Content.Server.NodeContainer.EntitySystems; using Content.Shared.Atmos.EntitySystems; +using Content.Shared.Maps; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Shared.Containers; diff --git a/Content.Server/Construction/ConstructionSystem.cs b/Content.Server/Construction/ConstructionSystem.cs index 76d37432cb..6e40b7b856 100644 --- a/Content.Server/Construction/ConstructionSystem.cs +++ b/Content.Server/Construction/ConstructionSystem.cs @@ -7,6 +7,7 @@ using JetBrains.Annotations; using Robust.Server.Containers; using Robust.Shared.Prototypes; using Robust.Shared.Random; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Server.Construction { diff --git a/Content.Server/Construction/RefiningSystem.cs b/Content.Server/Construction/RefiningSystem.cs index 40f69c51f8..b9d80c7170 100644 --- a/Content.Server/Construction/RefiningSystem.cs +++ b/Content.Server/Construction/RefiningSystem.cs @@ -6,6 +6,7 @@ using Content.Shared.Interaction; using Content.Shared.Stacks; using Content.Shared.Tools; using Robust.Shared.Serialization; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Server.Construction { diff --git a/Content.Server/Decals/DecalSystem.cs b/Content.Server/Decals/DecalSystem.cs index d5a5bf9aff..ed281e05ba 100644 --- a/Content.Server/Decals/DecalSystem.cs +++ b/Content.Server/Decals/DecalSystem.cs @@ -305,10 +305,10 @@ namespace Content.Server.Decals return true; } - public bool RemoveDecal(EntityUid gridId, uint decalId, DecalGridComponent? component = null) + public override bool RemoveDecal(EntityUid gridId, uint decalId, DecalGridComponent? component = null) => RemoveDecalInternal(gridId, decalId, out _, component); - public HashSet<(uint Index, Decal Decal)> GetDecalsInRange(EntityUid gridId, Vector2 position, float distance = 0.75f, Func? validDelegate = null) + public override HashSet<(uint Index, Decal Decal)> GetDecalsInRange(EntityUid gridId, Vector2 position, float distance = 0.75f, Func? validDelegate = null) { var decalIds = new HashSet<(uint, Decal)>(); var chunkCollection = ChunkCollection(gridId); diff --git a/Content.Server/DeviceLinking/Systems/LogicGateSystem.cs b/Content.Server/DeviceLinking/Systems/LogicGateSystem.cs index 360f86eebe..5641b0b4ae 100644 --- a/Content.Server/DeviceLinking/Systems/LogicGateSystem.cs +++ b/Content.Server/DeviceLinking/Systems/LogicGateSystem.cs @@ -5,6 +5,7 @@ using Content.Shared.Examine; using Content.Shared.Interaction; using Content.Shared.Tools; using Content.Shared.Popups; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; using SignalReceivedEvent = Content.Server.DeviceLinking.Events.SignalReceivedEvent; namespace Content.Server.DeviceLinking.Systems; diff --git a/Content.Server/Interaction/TilePryCommand.cs b/Content.Server/Interaction/TilePryCommand.cs index 157fa2cc80..4fe3599df9 100644 --- a/Content.Server/Interaction/TilePryCommand.cs +++ b/Content.Server/Interaction/TilePryCommand.cs @@ -3,6 +3,7 @@ using Content.Server.Administration; using Content.Server.Tools.Components; using Content.Shared.Administration; using Content.Shared.Maps; +using Content.Shared.Tools.Components; using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; @@ -10,7 +11,7 @@ using Robust.Shared.Map; namespace Content.Server.Interaction { /// - /// + /// /// [AdminCommand(AdminFlags.Debug)] sealed class TilePryCommand : IConsoleCommand diff --git a/Content.Server/Medical/CryoPodSystem.cs b/Content.Server/Medical/CryoPodSystem.cs index b94d6de6de..82f7b9cb0a 100644 --- a/Content.Server/Medical/CryoPodSystem.cs +++ b/Content.Server/Medical/CryoPodSystem.cs @@ -32,6 +32,7 @@ using Content.Shared.Tools; using Content.Shared.Verbs; using Robust.Server.GameObjects; using Robust.Shared.Timing; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Server.Medical; diff --git a/Content.Server/Power/EntitySystems/CableSystem.cs b/Content.Server/Power/EntitySystems/CableSystem.cs index 8dd09fab35..a5c9591d9a 100644 --- a/Content.Server/Power/EntitySystems/CableSystem.cs +++ b/Content.Server/Power/EntitySystems/CableSystem.cs @@ -8,6 +8,8 @@ using Content.Shared.Interaction; using Content.Shared.Tools; using Content.Shared.Tools.Components; using Robust.Shared.Map; +using CableCuttingFinishedEvent = Content.Shared.Tools.Systems.CableCuttingFinishedEvent; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Server.Power.EntitySystems; diff --git a/Content.Server/Repairable/RepairableSystem.cs b/Content.Server/Repairable/RepairableSystem.cs index 486ac756e3..5bd580756d 100644 --- a/Content.Server/Repairable/RepairableSystem.cs +++ b/Content.Server/Repairable/RepairableSystem.cs @@ -5,6 +5,7 @@ using Content.Shared.Interaction; using Content.Shared.Popups; using Content.Shared.Repairable; using Content.Shared.Tools; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Server.Repairable { diff --git a/Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs b/Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs index b3caced0da..cb20a1b868 100644 --- a/Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs +++ b/Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs @@ -21,6 +21,7 @@ using Content.Shared.DoAfter; using Content.Shared.Emag.Systems; using Content.Shared.FixedPoint; using Content.Shared.Humanoid; +using Content.Shared.Maps; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; diff --git a/Content.Server/Toilet/ToiletSystem.cs b/Content.Server/Toilet/ToiletSystem.cs index 57467397c6..b10feae453 100644 --- a/Content.Server/Toilet/ToiletSystem.cs +++ b/Content.Server/Toilet/ToiletSystem.cs @@ -19,6 +19,7 @@ using Content.Shared.Verbs; using Robust.Shared.Audio; using Robust.Shared.Player; using Robust.Shared.Random; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Server.Toilet { diff --git a/Content.Server/Tools/Components/TilePryingComponent.cs b/Content.Server/Tools/Components/TilePryingComponent.cs deleted file mode 100644 index 99d7144b68..0000000000 --- a/Content.Server/Tools/Components/TilePryingComponent.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Threading; -using Content.Shared.Tools; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; - -namespace Content.Server.Tools.Components -{ - [RegisterComponent] - public sealed partial class TilePryingComponent : Component - { - [DataField("toolComponentNeeded")] - public bool ToolComponentNeeded = true; - - [DataField("qualityNeeded", customTypeSerializer:typeof(PrototypeIdSerializer))] - public string QualityNeeded = "Prying"; - - /// - /// Whether this tool can pry tiles with CanAxe. - /// - [DataField("advanced")] - public bool Advanced = false; - - [DataField("delay")] - public float Delay = 1f; - } -} diff --git a/Content.Server/Tools/ToolSystem.LatticeCutting.cs b/Content.Server/Tools/ToolSystem.LatticeCutting.cs index 674a810239..ab289c1ae2 100644 --- a/Content.Server/Tools/ToolSystem.LatticeCutting.cs +++ b/Content.Server/Tools/ToolSystem.LatticeCutting.cs @@ -62,14 +62,14 @@ public sealed partial class ToolSystem var coordinates = mapGrid.GridTileToLocal(tile.GridIndices); - if (!_interactionSystem.InRangeUnobstructed(user, coordinates, popup: false)) + if (!InteractionSystem.InRangeUnobstructed(user, coordinates, popup: false)) return false; if (_tileDefinitionManager[tile.Tile.TypeId] is not ContentTileDefinition tileDef || !tileDef.CanWirecutter || string.IsNullOrEmpty(tileDef.BaseTurf) - || _tileDefinitionManager[tileDef.BaseTurf] is not ContentTileDefinition newDef - || tile.IsBlockedTurf(true)) + || _tileDefinitionManager[tileDef.BaseTurf] is not ContentTileDefinition || + tile.IsBlockedTurf(true)) { return false; } diff --git a/Content.Server/Tools/ToolSystem.cs b/Content.Server/Tools/ToolSystem.cs index 63642338f3..88a96dc1e8 100644 --- a/Content.Server/Tools/ToolSystem.cs +++ b/Content.Server/Tools/ToolSystem.cs @@ -6,6 +6,7 @@ using Content.Shared.Maps; using Content.Shared.Tools; using Robust.Server.GameObjects; using Robust.Shared.Map; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Server.Tools { @@ -21,13 +22,11 @@ namespace Content.Server.Tools [Dependency] private readonly SharedPointLightSystem _light = default!; [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!; [Dependency] private readonly TransformSystem _transformSystem = default!; - [Dependency] private readonly TurfSystem _turf = default!; public override void Initialize() { base.Initialize(); - InitializeTilePrying(); InitializeLatticeCutting(); InitializeWelders(); } diff --git a/Content.Server/Wires/WiresSystem.cs b/Content.Server/Wires/WiresSystem.cs index df61e89d4d..e75ad0a9ef 100644 --- a/Content.Server/Wires/WiresSystem.cs +++ b/Content.Server/Wires/WiresSystem.cs @@ -19,6 +19,7 @@ using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Server.Wires; diff --git a/Content.Server/Worldgen/Systems/Debris/BlobFloorPlanBuilderSystem.cs b/Content.Server/Worldgen/Systems/Debris/BlobFloorPlanBuilderSystem.cs index a90faef995..a09416e593 100644 --- a/Content.Server/Worldgen/Systems/Debris/BlobFloorPlanBuilderSystem.cs +++ b/Content.Server/Worldgen/Systems/Debris/BlobFloorPlanBuilderSystem.cs @@ -14,6 +14,7 @@ public sealed class BlobFloorPlanBuilderSystem : BaseWorldSystem { [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly ITileDefinitionManager _tileDefinition = default!; + [Dependency] private readonly TileSystem _tiles = default!; /// public override void Initialize() @@ -30,6 +31,8 @@ public sealed class BlobFloorPlanBuilderSystem : BaseWorldSystem private void PlaceFloorplanTiles(BlobFloorPlanBuilderComponent comp, MapGridComponent grid) { // NO MORE THAN TWO ALLOCATIONS THANK YOU VERY MUCH. + // TODO: Just put these on a field instead then? + // Also the end of the method has a big LINQ which is gonna blow this out the water. var spawnPoints = new HashSet(comp.FloorPlacements * 6); var taken = new Dictionary(comp.FloorPlacements * 5); @@ -56,7 +59,7 @@ public sealed class BlobFloorPlanBuilderSystem : BaseWorldSystem spawnPoints.Add(west); var tileDef = _tileDefinition[_random.Pick(comp.FloorTileset)]; - taken.Add(point, new Tile(tileDef.TileId, 0, ((ContentTileDefinition)tileDef).PickVariant(_random))); + taken.Add(point, new Tile(tileDef.TileId, 0, _tiles.PickVariant((ContentTileDefinition) tileDef))); } PlaceTile(Vector2i.Zero); diff --git a/Content.Server/Worldgen/Systems/Debris/DebrisFeaturePlacerSystem.cs b/Content.Server/Worldgen/Systems/Debris/DebrisFeaturePlacerSystem.cs index b2d8df4de9..65af0b68cb 100644 --- a/Content.Server/Worldgen/Systems/Debris/DebrisFeaturePlacerSystem.cs +++ b/Content.Server/Worldgen/Systems/Debris/DebrisFeaturePlacerSystem.cs @@ -46,7 +46,7 @@ public sealed class DebrisFeaturePlacerSystem : BaseWorldSystem return; // Redundant logic, prolly needs it's own handler for your custom system. var placer = Comp(component.OwningController); - var xform = Transform(uid); + var xform = args.Component; var ownerXform = Transform(component.OwningController); if (xform.MapUid is null || ownerXform.MapUid is null) return; // not our problem diff --git a/Content.Shared/Construction/EntitySystems/AnchorableSystem.cs b/Content.Shared/Construction/EntitySystems/AnchorableSystem.cs index 3e1cf5584c..b40c049562 100644 --- a/Content.Shared/Construction/EntitySystems/AnchorableSystem.cs +++ b/Content.Shared/Construction/EntitySystems/AnchorableSystem.cs @@ -18,6 +18,7 @@ using Content.Shared.Tag; using Robust.Shared.Player; using Robust.Shared.Serialization; using Robust.Shared.Utility; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Shared.Construction.EntitySystems; diff --git a/Content.Shared/Decals/SharedDecalSystem.cs b/Content.Shared/Decals/SharedDecalSystem.cs index 79bf826eed..02f73bdacb 100644 --- a/Content.Shared/Decals/SharedDecalSystem.cs +++ b/Content.Shared/Decals/SharedDecalSystem.cs @@ -1,3 +1,4 @@ +using System.Collections; using System.Diagnostics.CodeAnalysis; using System.Numerics; using Robust.Shared.GameStates; @@ -107,6 +108,18 @@ namespace Content.Shared.Decals { // used by client-side overlay code } + + public virtual HashSet<(uint Index, Decal Decal)> GetDecalsInRange(EntityUid gridId, Vector2 position, float distance = 0.75f, Func? validDelegate = null) + { + // NOOP on client atm. + return new HashSet<(uint Index, Decal Decal)>(); + } + + public virtual bool RemoveDecal(EntityUid gridId, uint decalId, DecalGridComponent? component = null) + { + // NOOP on client atm. + return true; + } } // TODO: Pretty sure paul was moving this somewhere but just so people know diff --git a/Content.Server/Maps/TileSystem.cs b/Content.Shared/Maps/TileSystem.cs similarity index 68% rename from Content.Server/Maps/TileSystem.cs rename to Content.Shared/Maps/TileSystem.cs index 1423f76d97..2c09375d59 100644 --- a/Content.Server/Maps/TileSystem.cs +++ b/Content.Shared/Maps/TileSystem.cs @@ -1,13 +1,13 @@ +using System.Linq; using System.Numerics; -using Content.Server.Decals; using Content.Shared.Coordinates.Helpers; using Content.Shared.Decals; -using Content.Shared.Maps; using Robust.Shared.Map; using Robust.Shared.Map.Components; using Robust.Shared.Random; +using Robust.Shared.Utility; -namespace Content.Server.Maps; +namespace Content.Shared.Maps; /// /// Handles server-side tile manipulation like prying/deconstructing tiles. @@ -15,15 +15,39 @@ namespace Content.Server.Maps; public sealed class TileSystem : EntitySystem { [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!; [Dependency] private readonly IRobustRandom _robustRandom = default!; - [Dependency] private readonly DecalSystem _decal = default!; + [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!; + [Dependency] private readonly SharedDecalSystem _decal = default!; + [Dependency] private readonly SharedMapSystem _maps = default!; [Dependency] private readonly TurfSystem _turf = default!; + /// + /// Returns a weighted pick of a tile variant. + /// + public byte PickVariant(ContentTileDefinition tile) + { + var variants = tile.PlacementVariants; + + var sum = variants.Sum(); + var accumulated = 0f; + var rand = _robustRandom.NextFloat() * sum; + + for (byte i = 0; i < variants.Length; ++i) + { + accumulated += variants[i]; + + if (accumulated >= rand) + return i; + } + + // Shouldn't happen + throw new InvalidOperationException($"Invalid weighted variantize tile pick for {tile.ID}!"); + } + public bool PryTile(Vector2i indices, EntityUid gridId) { - var grid = _mapManager.GetGrid(gridId); - var tileRef = grid.GetTileRef(indices); + var grid = Comp(gridId); + var tileRef = _maps.GetTileRef(gridId, grid, indices); return PryTile(tileRef); } @@ -71,16 +95,20 @@ public sealed class TileSystem : EntitySystem public bool ReplaceTile(TileRef tileref, ContentTileDefinition replacementTile, EntityUid grid, MapGridComponent? component = null) { + DebugTools.Assert(tileref.GridUid == grid); + if (!Resolve(grid, ref component)) return false; - var variant = replacementTile.PickVariant(); + + var variant = PickVariant(replacementTile); var decals = _decal.GetDecalsInRange(tileref.GridUid, _turf.GetTileCenter(tileref).Position, 0.5f); foreach (var (id, _) in decals) { _decal.RemoveDecal(tileref.GridUid, id); } - component.SetTile(tileref.GridIndices, new Tile(replacementTile.TileId, 0, variant)); + + _maps.SetTile(grid, component, tileref.GridIndices, new Tile(replacementTile.TileId, 0, variant)); return true; } @@ -94,12 +122,13 @@ public sealed class TileSystem : EntitySystem if (string.IsNullOrEmpty(tileDef.BaseTurf)) return false; - var mapGrid = _mapManager.GetGrid(tileRef.GridUid); + var gridUid = tileRef.GridUid; + var mapGrid = Comp(gridUid); const float margin = 0.1f; var bounds = mapGrid.TileSize - margin * 2; var indices = tileRef.GridIndices; - var coordinates = mapGrid.GridTileToLocal(indices) + var coordinates = _maps.GridTileToLocal(gridUid, mapGrid, indices) .Offset(new Vector2( (_robustRandom.NextFloat() - 0.5f) * bounds, (_robustRandom.NextFloat() - 0.5f) * bounds)); @@ -109,15 +138,14 @@ public sealed class TileSystem : EntitySystem Transform(tileItem).LocalRotation = _robustRandom.NextDouble() * Math.Tau; // Destroy any decals on the tile - var decals = _decal.GetDecalsInRange(tileRef.GridUid, coordinates.SnapToGrid(EntityManager, _mapManager).Position, 0.5f); + var decals = _decal.GetDecalsInRange(gridUid, coordinates.SnapToGrid(EntityManager, _mapManager).Position, 0.5f); foreach (var (id, _) in decals) { _decal.RemoveDecal(tileRef.GridUid, id); } var plating = _tileDefinitionManager[tileDef.BaseTurf]; - - mapGrid.SetTile(tileRef.GridIndices, new Tile(plating.TileId)); + _maps.SetTile(gridUid, mapGrid, tileRef.GridIndices, new Tile(plating.TileId)); return true; } diff --git a/Content.Shared/Maps/TurfHelpers.cs b/Content.Shared/Maps/TurfHelpers.cs index 857244d658..a87b8c97d1 100644 --- a/Content.Shared/Maps/TurfHelpers.cs +++ b/Content.Shared/Maps/TurfHelpers.cs @@ -86,30 +86,6 @@ namespace Content.Shared.Maps return tile.Tile.IsSpace(tileDefinitionManager); } - /// - /// Returns a weighted pick of a tile variant. - /// - public static byte PickVariant(this ContentTileDefinition tile, IRobustRandom? random = null) - { - IoCManager.Resolve(ref random); - var variants = tile.PlacementVariants; - - var sum = variants.Sum(); - var accumulated = 0f; - var rand = random.NextFloat() * sum; - - for (byte i = 0; i < variants.Length; ++i) - { - accumulated += variants[i]; - - if (accumulated >= rand) - return i; - } - - // Shouldn't happen - throw new InvalidOperationException($"Invalid weighted variantize tile pick for {tile.ID}!"); - } - /// /// Helper that returns all entities in a turf. /// diff --git a/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs b/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs index 3d2ce2fd00..eb97fe4113 100644 --- a/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs +++ b/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs @@ -14,6 +14,7 @@ using Robust.Shared.Network; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; using Robust.Shared.Timing; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Shared.Radio.EntitySystems; diff --git a/Content.Shared/Tools/Components/TilePryingComponent.cs b/Content.Shared/Tools/Components/TilePryingComponent.cs new file mode 100644 index 0000000000..4c123ca1ed --- /dev/null +++ b/Content.Shared/Tools/Components/TilePryingComponent.cs @@ -0,0 +1,26 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Shared.Tools.Components; + +/// +/// Allows prying tiles up on a grid. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class TilePryingComponent : Component +{ + [DataField("toolComponentNeeded"), AutoNetworkedField] + public bool ToolComponentNeeded = true; + + [DataField("qualityNeeded", customTypeSerializer:typeof(PrototypeIdSerializer)), AutoNetworkedField] + public string QualityNeeded = "Prying"; + + /// + /// Whether this tool can pry tiles with CanAxe. + /// + [DataField("advanced"), AutoNetworkedField] + public bool Advanced = false; + + [DataField("delay"), AutoNetworkedField] + public float Delay = 1f; +} diff --git a/Content.Shared/Tools/Systems/SharedToolSystem.MultipleTool.cs b/Content.Shared/Tools/Systems/SharedToolSystem.MultipleTool.cs index 39a1dc50f3..cb8830060a 100644 --- a/Content.Shared/Tools/Systems/SharedToolSystem.MultipleTool.cs +++ b/Content.Shared/Tools/Systems/SharedToolSystem.MultipleTool.cs @@ -1,9 +1,9 @@ using System.Linq; using Content.Shared.Interaction; -using Content.Shared.Tools.Components; using Content.Shared.Prying.Components; +using Content.Shared.Tools.Components; -namespace Content.Shared.Tools; +namespace Content.Shared.Tools.Systems; public abstract partial class SharedToolSystem : EntitySystem { diff --git a/Content.Server/Tools/ToolSystem.TilePrying.cs b/Content.Shared/Tools/Systems/SharedToolSystem.TilePrying.cs similarity index 66% rename from Content.Server/Tools/ToolSystem.TilePrying.cs rename to Content.Shared/Tools/Systems/SharedToolSystem.TilePrying.cs index faaed6abb8..81592f5a98 100644 --- a/Content.Server/Tools/ToolSystem.TilePrying.cs +++ b/Content.Shared/Tools/Systems/SharedToolSystem.TilePrying.cs @@ -1,17 +1,15 @@ -using Content.Server.Tools.Components; using Content.Shared.Database; using Content.Shared.Fluids.Components; using Content.Shared.Interaction; using Content.Shared.Maps; using Content.Shared.Tools.Components; using Robust.Shared.Map; +using Robust.Shared.Map.Components; -namespace Content.Server.Tools; +namespace Content.Shared.Tools.Systems; -public sealed partial class ToolSystem +public abstract partial class SharedToolSystem { - [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; - private void InitializeTilePrying() { SubscribeLocalEvent(OnTilePryingAfterInteract); @@ -20,7 +18,8 @@ public sealed partial class ToolSystem private void OnTilePryingAfterInteract(EntityUid uid, TilePryingComponent component, AfterInteractEvent args) { - if (args.Handled || !args.CanReach || (args.Target != null && !HasComp(args.Target))) return; + if (args.Handled || !args.CanReach || args.Target != null && !HasComp(args.Target)) + return; if (TryPryTile(uid, args.User, component, args.ClickLocation)) args.Handled = true; @@ -33,26 +32,28 @@ public sealed partial class ToolSystem var coords = GetCoordinates(args.Coordinates); var gridUid = coords.GetGridUid(EntityManager); - if (!_mapManager.TryGetGrid(gridUid, out var grid)) + if (!TryComp(gridUid, out MapGridComponent? grid)) { Log.Error("Attempted to pry from a non-existent grid?"); return; } - var tile = grid.GetTileRef(coords); - var center = _turf.GetTileCenter(tile); + var tile = _maps.GetTileRef(gridUid.Value, grid, coords); + var center = _turfs.GetTileCenter(tile); + if (args.Used != null) { _adminLogger.Add(LogType.Tile, LogImpact.Low, - $"{ToPrettyString(args.User):actor} used {ToPrettyString(args.Used.Value):tool} to pry {_tileDefinitionManager[tile.Tile.TypeId].Name} at {center}"); + $"{ToPrettyString(args.User):actor} used {ToPrettyString(args.Used.Value):tool} to pry {_tileDefManager[tile.Tile.TypeId].Name} at {center}"); } else { _adminLogger.Add(LogType.Tile, LogImpact.Low, - $"{ToPrettyString(args.User):actor} pried {_tileDefinitionManager[tile.Tile.TypeId].Name} at {center}"); + $"{ToPrettyString(args.User):actor} pried {_tileDefManager[tile.Tile.TypeId].Name} at {center}"); } - _tile.PryTile(tile, component.Advanced); + if (_netManager.IsServer) + _tiles.PryTile(tile, component.Advanced); } private bool TryPryTile(EntityUid toolEntity, EntityUid user, TilePryingComponent component, EntityCoordinates clickLocation) @@ -60,17 +61,16 @@ public sealed partial class ToolSystem if (!TryComp(toolEntity, out var tool) && component.ToolComponentNeeded) return false; - if (!_mapManager.TryFindGridAt(clickLocation.ToMap(EntityManager, _transformSystem), out _, out var mapGrid)) + if (!_mapManager.TryFindGridAt(clickLocation.ToMap(EntityManager, _transformSystem), out var gridUid, out var mapGrid)) return false; - var tile = mapGrid.GetTileRef(clickLocation); + var tile = _maps.GetTileRef(gridUid, mapGrid, clickLocation); + var coordinates = _maps.GridTileToLocal(gridUid, mapGrid, tile.GridIndices); - var coordinates = mapGrid.GridTileToLocal(tile.GridIndices); - - if (!_interactionSystem.InRangeUnobstructed(user, coordinates, popup: false)) + if (!InteractionSystem.InRangeUnobstructed(user, coordinates, popup: false)) return false; - var tileDef = (ContentTileDefinition)_tileDefinitionManager[tile.Tile.TypeId]; + var tileDef = (ContentTileDefinition) _tileDefManager[tile.Tile.TypeId]; if (!tileDef.CanCrowbar && !(tileDef.CanAxe && component.Advanced)) return false; diff --git a/Content.Shared/Tools/Systems/SharedToolSystem.cs b/Content.Shared/Tools/Systems/SharedToolSystem.cs index 716a9332d0..c1a2bdc2dd 100644 --- a/Content.Shared/Tools/Systems/SharedToolSystem.cs +++ b/Content.Shared/Tools/Systems/SharedToolSystem.cs @@ -1,22 +1,35 @@ +using Content.Shared.Administration.Logs; using Content.Shared.DoAfter; +using Content.Shared.Interaction; +using Content.Shared.Maps; using Content.Shared.Tools.Components; using Robust.Shared.Map; +using Robust.Shared.Network; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; -using Robust.Shared.Timing; using Robust.Shared.Utility; -namespace Content.Shared.Tools; +namespace Content.Shared.Tools.Systems; public abstract partial class SharedToolSystem : EntitySystem { - [Dependency] private readonly IPrototypeManager _protoMan = default!; - [Dependency] private readonly SharedAudioSystem _audioSystem = default!; - [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; + [Dependency] private readonly IMapManager _mapManager = default!; + [Dependency] private readonly INetManager _netManager = default!; + [Dependency] private readonly IPrototypeManager _protoMan = default!; + [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; + [Dependency] private readonly ITileDefinitionManager _tileDefManager = default!; + [Dependency] private readonly SharedAudioSystem _audioSystem = default!; + [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; + [Dependency] protected readonly SharedInteractionSystem InteractionSystem = default!; + [Dependency] private readonly SharedMapSystem _maps = default!; + [Dependency] private readonly SharedTransformSystem _transformSystem = default!; + [Dependency] private readonly TileSystem _tiles = default!; + [Dependency] private readonly TurfSystem _turfs = default!; public override void Initialize() { InitializeMultipleTool(); + InitializeTilePrying(); SubscribeLocalEvent(OnDoAfter); } From eae349d15e74c1107d5593a52aebb6b53f7dc245 Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 23 Oct 2023 09:21:38 -0400 Subject: [PATCH 006/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 5f4b71deaa..199580f9bc 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,10 +1,4 @@ Entries: -- author: onoira - changes: - - {message: Spare pieces have been added to checkerboards allowing for more playable - variants., type: Tweak} - id: 4543 - time: '2023-08-13T07:10:10.0000000+00:00' - author: Doru991 changes: - {message: Composting high-potency plants refills tray nutrients much more effectively., @@ -2909,3 +2903,8 @@ Entries: - {message: Replaced wielding do_after with an interaction cooldown., type: Tweak} id: 5042 time: '2023-10-22T13:53:14.0000000+00:00' +- author: metalgearsloth + changes: + - {message: Tile-prying do_after is now predicted., type: Tweak} + id: 5043 + time: '2023-10-23T13:20:33.0000000+00:00' From 7073b292c0c407894fe7fe15fc0a86ef2b6c82cd Mon Sep 17 00:00:00 2001 From: Tryded <139474617+Tryded@users.noreply.github.com> Date: Mon, 23 Oct 2023 09:35:32 -0500 Subject: [PATCH 007/102] Buffs Double bladed energy swords (#21131) --- Resources/Locale/en-US/store/uplink-catalog.ftl | 2 +- Resources/Prototypes/Catalog/uplink_catalog.yml | 2 +- .../Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Resources/Locale/en-US/store/uplink-catalog.ftl b/Resources/Locale/en-US/store/uplink-catalog.ftl index a957c298ba..9254a2a8ad 100644 --- a/Resources/Locale/en-US/store/uplink-catalog.ftl +++ b/Resources/Locale/en-US/store/uplink-catalog.ftl @@ -15,7 +15,7 @@ uplink-esword-name = Energy Sword uplink-esword-desc = A very dangerous energy sword that can reflect shots. Can be stored in pockets when turned off. Makes a lot of noise when used or turned on. uplink-esword-double-name = Double Bladed Energy Sword -uplink-esword-double-desc = A much more expensive counter part to the normal energy sword: with a much higher reflection chance, larger attack angle, higher structural damage, and faster swing, all at the cost of lower heat and slash damage. Makes a lot of noise when used or turned on. +uplink-esword-double-desc = A much more expensive counter part to the normal energy sword: with a much higher reflection chance, larger attack angle, higher structural damage, and faster swing. Makes a lot of noise when used or turned on. uplink-edagger-name = Energy Dagger uplink-edagger-desc = A small energy blade conveniently disguised in the form of a pen. diff --git a/Resources/Prototypes/Catalog/uplink_catalog.yml b/Resources/Prototypes/Catalog/uplink_catalog.yml index cc42a90062..d1be4e4d1b 100644 --- a/Resources/Prototypes/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Catalog/uplink_catalog.yml @@ -92,7 +92,7 @@ icon: { sprite: /Textures/Objects/Weapons/Melee/e_sword_double.rsi, state: icon } productEntity: EnergySwordDouble cost: - Telecrystal: 16 + Telecrystal: 20 #(Originally 16) categories: - UplinkWeapons conditions: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml index 0dd5d7c47c..47dfea9d86 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml @@ -174,8 +174,8 @@ - type: EnergySword litDamageBonus: types: - Slash: 9 - Heat: 9 + Slash: 17 + Heat: 17 Structural: 20 Blunt: -4.5 litDisarmMalus: 0.7 From 60092e8b8a9f943c6d94a634648c8f0c981b5b16 Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 23 Oct 2023 10:36:36 -0400 Subject: [PATCH 008/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 199580f9bc..653c12af92 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,10 +1,4 @@ Entries: -- author: Doru991 - changes: - - {message: Composting high-potency plants refills tray nutrients much more effectively., - type: Tweak} - id: 4544 - time: '2023-08-13T07:10:22.0000000+00:00' - author: Nimfar11 changes: - {message: Adds a Secret Door for construction, type: Add} @@ -2908,3 +2902,10 @@ Entries: - {message: Tile-prying do_after is now predicted., type: Tweak} id: 5043 time: '2023-10-23T13:20:33.0000000+00:00' +- author: Tryded + changes: + - {message: Changed the damage of the double bladed energy sword to 17 heat + 17 + Slash (The Double Bladed energy sword use to deal as much damage as an energy + dagger.), type: Tweak} + id: 5044 + time: '2023-10-23T14:35:33.0000000+00:00' From 472381c0db6cd3088fe757975d96a70ac652f584 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Tue, 24 Oct 2023 11:53:27 +1100 Subject: [PATCH 009/102] Add GrantContainedActions() (#21206) --- Content.Shared/Actions/SharedActionsSystem.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Content.Shared/Actions/SharedActionsSystem.cs b/Content.Shared/Actions/SharedActionsSystem.cs index 9ad155081a..00a17ace25 100644 --- a/Content.Shared/Actions/SharedActionsSystem.cs +++ b/Content.Shared/Actions/SharedActionsSystem.cs @@ -494,6 +494,9 @@ public abstract class SharedActionsSystem : EntitySystem (TryComp(action.Container, out ActionsContainerComponent? containerComp) && containerComp.Container.Contains(actionId))); + if (action.AttachedEntity != null) + RemoveAction(action.AttachedEntity.Value, actionId, action: action); + DebugTools.AssertOwner(performer, comp); comp ??= EnsureComp(performer); action.AttachedEntity = performer; @@ -532,6 +535,26 @@ public abstract class SharedActionsSystem : EntitySystem } } + /// + /// Grants all actions currently contained in some action-container. If the target entity has no action + /// component, this will give them one. + /// + /// Entity to receive the actions + /// The entity that contains thee actions. + public void GrantContainedActions(Entity performer, Entity container) + { + if (!Resolve(container, ref container.Comp)) + return; + + performer.Comp ??= EnsureComp(performer); + + foreach (var actionId in container.Comp.Container.ContainedEntities) + { + if (TryGetActionData(actionId, out var action)) + AddActionDirect(performer, actionId, performer.Comp, action); + } + } + public IEnumerable<(EntityUid Id, BaseActionComponent Comp)> GetActions(EntityUid holderId, ActionsComponent? actions = null) { if (!Resolve(holderId, ref actions, false)) From 0e0ac5fcc52d4c01dfc7f1707aff872de8ded3e6 Mon Sep 17 00:00:00 2001 From: DrSmugleaf Date: Mon, 23 Oct 2023 22:08:20 -0700 Subject: [PATCH 010/102] Drop admin log entity db table (#21216) --- ...31024041204_DropAdminLogEntity.Designer.cs | 1735 +++++++++++++++++ .../20231024041204_DropAdminLogEntity.cs | 47 + .../PostgresServerDbContextModelSnapshot.cs | 40 - ...31024041159_DropAdminLogEntity.Designer.cs | 1667 ++++++++++++++++ .../20231024041159_DropAdminLogEntity.cs | 46 + .../SqliteServerDbContextModelSnapshot.cs | 38 - Content.Server.Database/Model.cs | 10 - 7 files changed, 3495 insertions(+), 88 deletions(-) create mode 100644 Content.Server.Database/Migrations/Postgres/20231024041204_DropAdminLogEntity.Designer.cs create mode 100644 Content.Server.Database/Migrations/Postgres/20231024041204_DropAdminLogEntity.cs create mode 100644 Content.Server.Database/Migrations/Sqlite/20231024041159_DropAdminLogEntity.Designer.cs create mode 100644 Content.Server.Database/Migrations/Sqlite/20231024041159_DropAdminLogEntity.cs diff --git a/Content.Server.Database/Migrations/Postgres/20231024041204_DropAdminLogEntity.Designer.cs b/Content.Server.Database/Migrations/Postgres/20231024041204_DropAdminLogEntity.Designer.cs new file mode 100644 index 0000000000..5c81f0468d --- /dev/null +++ b/Content.Server.Database/Migrations/Postgres/20231024041204_DropAdminLogEntity.Designer.cs @@ -0,0 +1,1735 @@ +// +using System; +using System.Net; +using System.Text.Json; +using Content.Server.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Content.Server.Database.Migrations.Postgres +{ + [DbContext(typeof(PostgresServerDbContext))] + [Migration("20231024041204_DropAdminLogEntity")] + partial class DropAdminLogEntity + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.4") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Content.Server.Database.Admin", b => + { + b.Property("UserId") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.Property("AdminRankId") + .HasColumnType("integer") + .HasColumnName("admin_rank_id"); + + b.Property("Title") + .HasColumnType("text") + .HasColumnName("title"); + + b.HasKey("UserId") + .HasName("PK_admin"); + + b.HasIndex("AdminRankId") + .HasDatabaseName("IX_admin_admin_rank_id"); + + b.ToTable("admin", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminFlag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("admin_flag_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AdminId") + .HasColumnType("uuid") + .HasColumnName("admin_id"); + + b.Property("Flag") + .IsRequired() + .HasColumnType("text") + .HasColumnName("flag"); + + b.Property("Negative") + .HasColumnType("boolean") + .HasColumnName("negative"); + + b.HasKey("Id") + .HasName("PK_admin_flag"); + + b.HasIndex("AdminId") + .HasDatabaseName("IX_admin_flag_admin_id"); + + b.HasIndex("Flag", "AdminId") + .IsUnique(); + + b.ToTable("admin_flag", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLog", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("admin_log_id"); + + b.Property("RoundId") + .HasColumnType("integer") + .HasColumnName("round_id"); + + b.Property("Date") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.Property("Impact") + .HasColumnType("smallint") + .HasColumnName("impact"); + + b.Property("Json") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("json"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text") + .HasColumnName("message"); + + b.Property("Type") + .HasColumnType("integer") + .HasColumnName("type"); + + b.HasKey("Id", "RoundId") + .HasName("PK_admin_log"); + + b.HasIndex("Date"); + + b.HasIndex("Message") + .HasAnnotation("Npgsql:TsVectorConfig", "english"); + + NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("Message"), "GIN"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_admin_log_round_id"); + + b.HasIndex("Type") + .HasDatabaseName("IX_admin_log_type"); + + b.ToTable("admin_log", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLogPlayer", b => + { + b.Property("PlayerUserId") + .HasColumnType("uuid") + .HasColumnName("player_user_id"); + + b.Property("LogId") + .HasColumnType("integer") + .HasColumnName("log_id"); + + b.Property("RoundId") + .HasColumnType("integer") + .HasColumnName("round_id"); + + b.HasKey("PlayerUserId", "LogId", "RoundId") + .HasName("PK_admin_log_player"); + + b.HasIndex("LogId", "RoundId"); + + b.ToTable("admin_log_player", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("admin_messages_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("CreatedById") + .HasColumnType("uuid") + .HasColumnName("created_by_id"); + + b.Property("Deleted") + .HasColumnType("boolean") + .HasColumnName("deleted"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("DeletedById") + .HasColumnType("uuid") + .HasColumnName("deleted_by_id"); + + b.Property("ExpirationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiration_time"); + + b.Property("LastEditedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_edited_at"); + + b.Property("LastEditedById") + .HasColumnType("uuid") + .HasColumnName("last_edited_by_id"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("message"); + + b.Property("PlayerUserId") + .HasColumnType("uuid") + .HasColumnName("player_user_id"); + + b.Property("PlaytimeAtNote") + .HasColumnType("interval") + .HasColumnName("playtime_at_note"); + + b.Property("RoundId") + .HasColumnType("integer") + .HasColumnName("round_id"); + + b.Property("Seen") + .HasColumnType("boolean") + .HasColumnName("seen"); + + b.HasKey("Id") + .HasName("PK_admin_messages"); + + b.HasIndex("CreatedById"); + + b.HasIndex("DeletedById"); + + b.HasIndex("LastEditedById"); + + b.HasIndex("PlayerUserId") + .HasDatabaseName("IX_admin_messages_player_user_id"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_admin_messages_round_id"); + + b.ToTable("admin_messages", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminNote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("admin_notes_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("CreatedById") + .HasColumnType("uuid") + .HasColumnName("created_by_id"); + + b.Property("Deleted") + .HasColumnType("boolean") + .HasColumnName("deleted"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("DeletedById") + .HasColumnType("uuid") + .HasColumnName("deleted_by_id"); + + b.Property("ExpirationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiration_time"); + + b.Property("LastEditedAt") + .IsRequired() + .HasColumnType("timestamp with time zone") + .HasColumnName("last_edited_at"); + + b.Property("LastEditedById") + .HasColumnType("uuid") + .HasColumnName("last_edited_by_id"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("message"); + + b.Property("PlayerUserId") + .HasColumnType("uuid") + .HasColumnName("player_user_id"); + + b.Property("PlaytimeAtNote") + .HasColumnType("interval") + .HasColumnName("playtime_at_note"); + + b.Property("RoundId") + .HasColumnType("integer") + .HasColumnName("round_id"); + + b.Property("Secret") + .HasColumnType("boolean") + .HasColumnName("secret"); + + b.Property("Severity") + .HasColumnType("integer") + .HasColumnName("severity"); + + b.HasKey("Id") + .HasName("PK_admin_notes"); + + b.HasIndex("CreatedById"); + + b.HasIndex("DeletedById"); + + b.HasIndex("LastEditedById"); + + b.HasIndex("PlayerUserId") + .HasDatabaseName("IX_admin_notes_player_user_id"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_admin_notes_round_id"); + + b.ToTable("admin_notes", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRank", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("admin_rank_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("PK_admin_rank"); + + b.ToTable("admin_rank", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRankFlag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("admin_rank_flag_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AdminRankId") + .HasColumnType("integer") + .HasColumnName("admin_rank_id"); + + b.Property("Flag") + .IsRequired() + .HasColumnType("text") + .HasColumnName("flag"); + + b.HasKey("Id") + .HasName("PK_admin_rank_flag"); + + b.HasIndex("AdminRankId"); + + b.HasIndex("Flag", "AdminRankId") + .IsUnique(); + + b.ToTable("admin_rank_flag", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminWatchlist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("admin_watchlists_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("CreatedById") + .HasColumnType("uuid") + .HasColumnName("created_by_id"); + + b.Property("Deleted") + .HasColumnType("boolean") + .HasColumnName("deleted"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted_at"); + + b.Property("DeletedById") + .HasColumnType("uuid") + .HasColumnName("deleted_by_id"); + + b.Property("ExpirationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiration_time"); + + b.Property("LastEditedAt") + .IsRequired() + .HasColumnType("timestamp with time zone") + .HasColumnName("last_edited_at"); + + b.Property("LastEditedById") + .HasColumnType("uuid") + .HasColumnName("last_edited_by_id"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("message"); + + b.Property("PlayerUserId") + .HasColumnType("uuid") + .HasColumnName("player_user_id"); + + b.Property("PlaytimeAtNote") + .HasColumnType("interval") + .HasColumnName("playtime_at_note"); + + b.Property("RoundId") + .HasColumnType("integer") + .HasColumnName("round_id"); + + b.HasKey("Id") + .HasName("PK_admin_watchlists"); + + b.HasIndex("CreatedById"); + + b.HasIndex("DeletedById"); + + b.HasIndex("LastEditedById"); + + b.HasIndex("PlayerUserId") + .HasDatabaseName("IX_admin_watchlists_player_user_id"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_admin_watchlists_round_id"); + + b.ToTable("admin_watchlists", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Antag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("antag_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AntagName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("antag_name"); + + b.Property("ProfileId") + .HasColumnType("integer") + .HasColumnName("profile_id"); + + b.HasKey("Id") + .HasName("PK_antag"); + + b.HasIndex("ProfileId", "AntagName") + .IsUnique(); + + b.ToTable("antag", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AssignedUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("assigned_user_id_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("user_name"); + + b.HasKey("Id") + .HasName("PK_assigned_user_id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.HasIndex("UserName") + .IsUnique(); + + b.ToTable("assigned_user_id", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.ConnectionLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("connection_log_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("inet") + .HasColumnName("address"); + + b.Property("Denied") + .HasColumnType("smallint") + .HasColumnName("denied"); + + b.Property("HWId") + .HasColumnType("bytea") + .HasColumnName("hwid"); + + b.Property("Time") + .HasColumnType("timestamp with time zone") + .HasColumnName("time"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("user_name"); + + b.HasKey("Id") + .HasName("PK_connection_log"); + + b.HasIndex("UserId"); + + b.ToTable("connection_log", null, t => + { + t.HasCheckConstraint("AddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= address"); + }); + }); + + modelBuilder.Entity("Content.Server.Database.Job", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("job_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("JobName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("job_name"); + + b.Property("Priority") + .HasColumnType("integer") + .HasColumnName("priority"); + + b.Property("ProfileId") + .HasColumnType("integer") + .HasColumnName("profile_id"); + + b.HasKey("Id") + .HasName("PK_job"); + + b.HasIndex("ProfileId"); + + b.HasIndex("ProfileId", "JobName") + .IsUnique(); + + b.HasIndex(new[] { "ProfileId" }, "IX_job_one_high_priority") + .IsUnique() + .HasFilter("priority = 3"); + + b.ToTable("job", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.PlayTime", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("play_time_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("PlayerId") + .HasColumnType("uuid") + .HasColumnName("player_id"); + + b.Property("TimeSpent") + .HasColumnType("interval") + .HasColumnName("time_spent"); + + b.Property("Tracker") + .IsRequired() + .HasColumnType("text") + .HasColumnName("tracker"); + + b.HasKey("Id") + .HasName("PK_play_time"); + + b.HasIndex("PlayerId", "Tracker") + .IsUnique(); + + b.ToTable("play_time", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Player", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("player_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FirstSeenTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("first_seen_time"); + + b.Property("LastReadRules") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_read_rules"); + + b.Property("LastSeenAddress") + .IsRequired() + .HasColumnType("inet") + .HasColumnName("last_seen_address"); + + b.Property("LastSeenHWId") + .HasColumnType("bytea") + .HasColumnName("last_seen_hwid"); + + b.Property("LastSeenTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_seen_time"); + + b.Property("LastSeenUserName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("last_seen_user_name"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("PK_player"); + + b.HasAlternateKey("UserId") + .HasName("ak_player_user_id"); + + b.HasIndex("LastSeenUserName"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("player", null, t => + { + t.HasCheckConstraint("LastSeenAddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= last_seen_address"); + }); + }); + + modelBuilder.Entity("Content.Server.Database.Preference", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("preference_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AdminOOCColor") + .IsRequired() + .HasColumnType("text") + .HasColumnName("admin_ooc_color"); + + b.Property("SelectedCharacterSlot") + .HasColumnType("integer") + .HasColumnName("selected_character_slot"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("PK_preference"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("preference", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Profile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("profile_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Age") + .HasColumnType("integer") + .HasColumnName("age"); + + b.Property("Backpack") + .IsRequired() + .HasColumnType("text") + .HasColumnName("backpack"); + + b.Property("CharacterName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("char_name"); + + b.Property("Clothing") + .IsRequired() + .HasColumnType("text") + .HasColumnName("clothing"); + + b.Property("EyeColor") + .IsRequired() + .HasColumnType("text") + .HasColumnName("eye_color"); + + b.Property("FacialHairColor") + .IsRequired() + .HasColumnType("text") + .HasColumnName("facial_hair_color"); + + b.Property("FacialHairName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("facial_hair_name"); + + b.Property("FlavorText") + .IsRequired() + .HasColumnType("text") + .HasColumnName("flavor_text"); + + b.Property("Gender") + .IsRequired() + .HasColumnType("text") + .HasColumnName("gender"); + + b.Property("HairColor") + .IsRequired() + .HasColumnType("text") + .HasColumnName("hair_color"); + + b.Property("HairName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("hair_name"); + + b.Property("Markings") + .HasColumnType("jsonb") + .HasColumnName("markings"); + + b.Property("PreferenceId") + .HasColumnType("integer") + .HasColumnName("preference_id"); + + b.Property("PreferenceUnavailable") + .HasColumnType("integer") + .HasColumnName("pref_unavailable"); + + b.Property("Sex") + .IsRequired() + .HasColumnType("text") + .HasColumnName("sex"); + + b.Property("SkinColor") + .IsRequired() + .HasColumnType("text") + .HasColumnName("skin_color"); + + b.Property("Slot") + .HasColumnType("integer") + .HasColumnName("slot"); + + b.Property("Species") + .IsRequired() + .HasColumnType("text") + .HasColumnName("species"); + + b.HasKey("Id") + .HasName("PK_profile"); + + b.HasIndex("PreferenceId") + .HasDatabaseName("IX_profile_preference_id"); + + b.HasIndex("Slot", "PreferenceId") + .IsUnique(); + + b.ToTable("profile", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Round", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("round_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ServerId") + .HasColumnType("integer") + .HasColumnName("server_id"); + + b.Property("StartDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValue(new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)) + .HasColumnName("start_date"); + + b.HasKey("Id") + .HasName("PK_round"); + + b.HasIndex("ServerId") + .HasDatabaseName("IX_round_server_id"); + + b.HasIndex("StartDate"); + + b.ToTable("round", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Server", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("server_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("PK_server"); + + b.ToTable("server", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("server_ban_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property?>("Address") + .HasColumnType("inet") + .HasColumnName("address"); + + b.Property("AutoDelete") + .HasColumnType("boolean") + .HasColumnName("auto_delete"); + + b.Property("BanTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("ban_time"); + + b.Property("BanningAdmin") + .HasColumnType("uuid") + .HasColumnName("banning_admin"); + + b.Property("ExemptFlags") + .HasColumnType("integer") + .HasColumnName("exempt_flags"); + + b.Property("ExpirationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiration_time"); + + b.Property("HWId") + .HasColumnType("bytea") + .HasColumnName("hwid"); + + b.Property("Hidden") + .HasColumnType("boolean") + .HasColumnName("hidden"); + + b.Property("LastEditedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_edited_at"); + + b.Property("LastEditedById") + .HasColumnType("uuid") + .HasColumnName("last_edited_by_id"); + + b.Property("PlayerUserId") + .HasColumnType("uuid") + .HasColumnName("player_user_id"); + + b.Property("PlaytimeAtNote") + .HasColumnType("interval") + .HasColumnName("playtime_at_note"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("text") + .HasColumnName("reason"); + + b.Property("RoundId") + .HasColumnType("integer") + .HasColumnName("round_id"); + + b.Property("Severity") + .HasColumnType("integer") + .HasColumnName("severity"); + + b.HasKey("Id") + .HasName("PK_server_ban"); + + b.HasIndex("Address"); + + b.HasIndex("BanningAdmin"); + + b.HasIndex("LastEditedById"); + + b.HasIndex("PlayerUserId") + .HasDatabaseName("IX_server_ban_player_user_id"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_server_ban_round_id"); + + b.ToTable("server_ban", null, t => + { + t.HasCheckConstraint("AddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= address"); + + t.HasCheckConstraint("HaveEitherAddressOrUserIdOrHWId", "address IS NOT NULL OR player_user_id IS NOT NULL OR hwid IS NOT NULL"); + }); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBanExemption", b => + { + b.Property("UserId") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.Property("Flags") + .HasColumnType("integer") + .HasColumnName("flags"); + + b.HasKey("UserId") + .HasName("PK_server_ban_exemption"); + + b.ToTable("server_ban_exemption", null, t => + { + t.HasCheckConstraint("FlagsNotZero", "flags != 0"); + }); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBanHit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("server_ban_hit_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BanId") + .HasColumnType("integer") + .HasColumnName("ban_id"); + + b.Property("ConnectionId") + .HasColumnType("integer") + .HasColumnName("connection_id"); + + b.HasKey("Id") + .HasName("PK_server_ban_hit"); + + b.HasIndex("BanId") + .HasDatabaseName("IX_server_ban_hit_ban_id"); + + b.HasIndex("ConnectionId") + .HasDatabaseName("IX_server_ban_hit_connection_id"); + + b.ToTable("server_ban_hit", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.ServerRoleBan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("server_role_ban_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property?>("Address") + .HasColumnType("inet") + .HasColumnName("address"); + + b.Property("BanTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("ban_time"); + + b.Property("BanningAdmin") + .HasColumnType("uuid") + .HasColumnName("banning_admin"); + + b.Property("ExpirationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiration_time"); + + b.Property("HWId") + .HasColumnType("bytea") + .HasColumnName("hwid"); + + b.Property("Hidden") + .HasColumnType("boolean") + .HasColumnName("hidden"); + + b.Property("LastEditedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_edited_at"); + + b.Property("LastEditedById") + .HasColumnType("uuid") + .HasColumnName("last_edited_by_id"); + + b.Property("PlayerUserId") + .HasColumnType("uuid") + .HasColumnName("player_user_id"); + + b.Property("PlaytimeAtNote") + .HasColumnType("interval") + .HasColumnName("playtime_at_note"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("text") + .HasColumnName("reason"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("text") + .HasColumnName("role_id"); + + b.Property("RoundId") + .HasColumnType("integer") + .HasColumnName("round_id"); + + b.Property("Severity") + .HasColumnType("integer") + .HasColumnName("severity"); + + b.HasKey("Id") + .HasName("PK_server_role_ban"); + + b.HasIndex("Address"); + + b.HasIndex("BanningAdmin"); + + b.HasIndex("LastEditedById"); + + b.HasIndex("PlayerUserId") + .HasDatabaseName("IX_server_role_ban_player_user_id"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_server_role_ban_round_id"); + + b.ToTable("server_role_ban", null, t => + { + t.HasCheckConstraint("AddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= address"); + + t.HasCheckConstraint("HaveEitherAddressOrUserIdOrHWId", "address IS NOT NULL OR player_user_id IS NOT NULL OR hwid IS NOT NULL"); + }); + }); + + modelBuilder.Entity("Content.Server.Database.ServerRoleUnban", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("role_unban_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BanId") + .HasColumnType("integer") + .HasColumnName("ban_id"); + + b.Property("UnbanTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("unban_time"); + + b.Property("UnbanningAdmin") + .HasColumnType("uuid") + .HasColumnName("unbanning_admin"); + + b.HasKey("Id") + .HasName("PK_server_role_unban"); + + b.HasIndex("BanId") + .IsUnique(); + + b.ToTable("server_role_unban", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.ServerUnban", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("unban_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BanId") + .HasColumnType("integer") + .HasColumnName("ban_id"); + + b.Property("UnbanTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("unban_time"); + + b.Property("UnbanningAdmin") + .HasColumnType("uuid") + .HasColumnName("unbanning_admin"); + + b.HasKey("Id") + .HasName("PK_server_unban"); + + b.HasIndex("BanId") + .IsUnique(); + + b.ToTable("server_unban", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Trait", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("trait_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ProfileId") + .HasColumnType("integer") + .HasColumnName("profile_id"); + + b.Property("TraitName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("trait_name"); + + b.HasKey("Id") + .HasName("PK_trait"); + + b.HasIndex("ProfileId", "TraitName") + .IsUnique(); + + b.ToTable("trait", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.UploadedResourceLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("uploaded_resource_log_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Data") + .IsRequired() + .HasColumnType("bytea") + .HasColumnName("data"); + + b.Property("Date") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.Property("Path") + .IsRequired() + .HasColumnType("text") + .HasColumnName("path"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("PK_uploaded_resource_log"); + + b.ToTable("uploaded_resource_log", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Whitelist", b => + { + b.Property("UserId") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("UserId") + .HasName("PK_whitelist"); + + b.ToTable("whitelist", (string)null); + }); + + modelBuilder.Entity("PlayerRound", b => + { + b.Property("PlayersId") + .HasColumnType("integer") + .HasColumnName("players_id"); + + b.Property("RoundsId") + .HasColumnType("integer") + .HasColumnName("rounds_id"); + + b.HasKey("PlayersId", "RoundsId") + .HasName("PK_player_round"); + + b.HasIndex("RoundsId") + .HasDatabaseName("IX_player_round_rounds_id"); + + b.ToTable("player_round", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Admin", b => + { + b.HasOne("Content.Server.Database.AdminRank", "AdminRank") + .WithMany("Admins") + .HasForeignKey("AdminRankId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_admin_rank_admin_rank_id"); + + b.Navigation("AdminRank"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminFlag", b => + { + b.HasOne("Content.Server.Database.Admin", "Admin") + .WithMany("Flags") + .HasForeignKey("AdminId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_admin_flag_admin_admin_id"); + + b.Navigation("Admin"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLog", b => + { + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany("AdminLogs") + .HasForeignKey("RoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_admin_log_round_round_id"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLogPlayer", b => + { + b.HasOne("Content.Server.Database.Player", "Player") + .WithMany("AdminLogs") + .HasForeignKey("PlayerUserId") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_admin_log_player_player_player_user_id"); + + b.HasOne("Content.Server.Database.AdminLog", "Log") + .WithMany("Players") + .HasForeignKey("LogId", "RoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_admin_log_player_admin_log_log_id_round_id"); + + b.Navigation("Log"); + + b.Navigation("Player"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminMessage", b => + { + b.HasOne("Content.Server.Database.Player", "CreatedBy") + .WithMany("AdminMessagesCreated") + .HasForeignKey("CreatedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_messages_player_created_by_id"); + + b.HasOne("Content.Server.Database.Player", "DeletedBy") + .WithMany("AdminMessagesDeleted") + .HasForeignKey("DeletedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_messages_player_deleted_by_id"); + + b.HasOne("Content.Server.Database.Player", "LastEditedBy") + .WithMany("AdminMessagesLastEdited") + .HasForeignKey("LastEditedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_messages_player_last_edited_by_id"); + + b.HasOne("Content.Server.Database.Player", "Player") + .WithMany("AdminMessagesReceived") + .HasForeignKey("PlayerUserId") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("FK_admin_messages_player_player_user_id"); + + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany() + .HasForeignKey("RoundId") + .HasConstraintName("FK_admin_messages_round_round_id"); + + b.Navigation("CreatedBy"); + + b.Navigation("DeletedBy"); + + b.Navigation("LastEditedBy"); + + b.Navigation("Player"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminNote", b => + { + b.HasOne("Content.Server.Database.Player", "CreatedBy") + .WithMany("AdminNotesCreated") + .HasForeignKey("CreatedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_notes_player_created_by_id"); + + b.HasOne("Content.Server.Database.Player", "DeletedBy") + .WithMany("AdminNotesDeleted") + .HasForeignKey("DeletedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_notes_player_deleted_by_id"); + + b.HasOne("Content.Server.Database.Player", "LastEditedBy") + .WithMany("AdminNotesLastEdited") + .HasForeignKey("LastEditedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_notes_player_last_edited_by_id"); + + b.HasOne("Content.Server.Database.Player", "Player") + .WithMany("AdminNotesReceived") + .HasForeignKey("PlayerUserId") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("FK_admin_notes_player_player_user_id"); + + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany() + .HasForeignKey("RoundId") + .HasConstraintName("FK_admin_notes_round_round_id"); + + b.Navigation("CreatedBy"); + + b.Navigation("DeletedBy"); + + b.Navigation("LastEditedBy"); + + b.Navigation("Player"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRankFlag", b => + { + b.HasOne("Content.Server.Database.AdminRank", "Rank") + .WithMany("Flags") + .HasForeignKey("AdminRankId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_admin_rank_flag_admin_rank_admin_rank_id"); + + b.Navigation("Rank"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminWatchlist", b => + { + b.HasOne("Content.Server.Database.Player", "CreatedBy") + .WithMany("AdminWatchlistsCreated") + .HasForeignKey("CreatedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_watchlists_player_created_by_id"); + + b.HasOne("Content.Server.Database.Player", "DeletedBy") + .WithMany("AdminWatchlistsDeleted") + .HasForeignKey("DeletedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_watchlists_player_deleted_by_id"); + + b.HasOne("Content.Server.Database.Player", "LastEditedBy") + .WithMany("AdminWatchlistsLastEdited") + .HasForeignKey("LastEditedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_watchlists_player_last_edited_by_id"); + + b.HasOne("Content.Server.Database.Player", "Player") + .WithMany("AdminWatchlistsReceived") + .HasForeignKey("PlayerUserId") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("FK_admin_watchlists_player_player_user_id"); + + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany() + .HasForeignKey("RoundId") + .HasConstraintName("FK_admin_watchlists_round_round_id"); + + b.Navigation("CreatedBy"); + + b.Navigation("DeletedBy"); + + b.Navigation("LastEditedBy"); + + b.Navigation("Player"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.Antag", b => + { + b.HasOne("Content.Server.Database.Profile", "Profile") + .WithMany("Antags") + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_antag_profile_profile_id"); + + b.Navigation("Profile"); + }); + + modelBuilder.Entity("Content.Server.Database.Job", b => + { + b.HasOne("Content.Server.Database.Profile", "Profile") + .WithMany("Jobs") + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_job_profile_profile_id"); + + b.Navigation("Profile"); + }); + + modelBuilder.Entity("Content.Server.Database.Profile", b => + { + b.HasOne("Content.Server.Database.Preference", "Preference") + .WithMany("Profiles") + .HasForeignKey("PreferenceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_profile_preference_preference_id"); + + b.Navigation("Preference"); + }); + + modelBuilder.Entity("Content.Server.Database.Round", b => + { + b.HasOne("Content.Server.Database.Server", "Server") + .WithMany("Rounds") + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_round_server_server_id"); + + b.Navigation("Server"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBan", b => + { + b.HasOne("Content.Server.Database.Player", "CreatedBy") + .WithMany("AdminServerBansCreated") + .HasForeignKey("BanningAdmin") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_server_ban_player_banning_admin"); + + b.HasOne("Content.Server.Database.Player", "LastEditedBy") + .WithMany("AdminServerBansLastEdited") + .HasForeignKey("LastEditedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_server_ban_player_last_edited_by_id"); + + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany() + .HasForeignKey("RoundId") + .HasConstraintName("FK_server_ban_round_round_id"); + + b.Navigation("CreatedBy"); + + b.Navigation("LastEditedBy"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBanHit", b => + { + b.HasOne("Content.Server.Database.ServerBan", "Ban") + .WithMany("BanHits") + .HasForeignKey("BanId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_server_ban_hit_server_ban_ban_id"); + + b.HasOne("Content.Server.Database.ConnectionLog", "Connection") + .WithMany("BanHits") + .HasForeignKey("ConnectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_server_ban_hit_connection_log_connection_id"); + + b.Navigation("Ban"); + + b.Navigation("Connection"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerRoleBan", b => + { + b.HasOne("Content.Server.Database.Player", "CreatedBy") + .WithMany("AdminServerRoleBansCreated") + .HasForeignKey("BanningAdmin") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_server_role_ban_player_banning_admin"); + + b.HasOne("Content.Server.Database.Player", "LastEditedBy") + .WithMany("AdminServerRoleBansLastEdited") + .HasForeignKey("LastEditedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_server_role_ban_player_last_edited_by_id"); + + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany() + .HasForeignKey("RoundId") + .HasConstraintName("FK_server_role_ban_round_round_id"); + + b.Navigation("CreatedBy"); + + b.Navigation("LastEditedBy"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerRoleUnban", b => + { + b.HasOne("Content.Server.Database.ServerRoleBan", "Ban") + .WithOne("Unban") + .HasForeignKey("Content.Server.Database.ServerRoleUnban", "BanId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_server_role_unban_server_role_ban_ban_id"); + + b.Navigation("Ban"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerUnban", b => + { + b.HasOne("Content.Server.Database.ServerBan", "Ban") + .WithOne("Unban") + .HasForeignKey("Content.Server.Database.ServerUnban", "BanId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_server_unban_server_ban_ban_id"); + + b.Navigation("Ban"); + }); + + modelBuilder.Entity("Content.Server.Database.Trait", b => + { + b.HasOne("Content.Server.Database.Profile", "Profile") + .WithMany("Traits") + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_trait_profile_profile_id"); + + b.Navigation("Profile"); + }); + + modelBuilder.Entity("PlayerRound", b => + { + b.HasOne("Content.Server.Database.Player", null) + .WithMany() + .HasForeignKey("PlayersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_player_round_player_players_id"); + + b.HasOne("Content.Server.Database.Round", null) + .WithMany() + .HasForeignKey("RoundsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_player_round_round_rounds_id"); + }); + + modelBuilder.Entity("Content.Server.Database.Admin", b => + { + b.Navigation("Flags"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLog", b => + { + b.Navigation("Players"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRank", b => + { + b.Navigation("Admins"); + + b.Navigation("Flags"); + }); + + modelBuilder.Entity("Content.Server.Database.ConnectionLog", b => + { + b.Navigation("BanHits"); + }); + + modelBuilder.Entity("Content.Server.Database.Player", b => + { + b.Navigation("AdminLogs"); + + b.Navigation("AdminMessagesCreated"); + + b.Navigation("AdminMessagesDeleted"); + + b.Navigation("AdminMessagesLastEdited"); + + b.Navigation("AdminMessagesReceived"); + + b.Navigation("AdminNotesCreated"); + + b.Navigation("AdminNotesDeleted"); + + b.Navigation("AdminNotesLastEdited"); + + b.Navigation("AdminNotesReceived"); + + b.Navigation("AdminServerBansCreated"); + + b.Navigation("AdminServerBansLastEdited"); + + b.Navigation("AdminServerRoleBansCreated"); + + b.Navigation("AdminServerRoleBansLastEdited"); + + b.Navigation("AdminWatchlistsCreated"); + + b.Navigation("AdminWatchlistsDeleted"); + + b.Navigation("AdminWatchlistsLastEdited"); + + b.Navigation("AdminWatchlistsReceived"); + }); + + modelBuilder.Entity("Content.Server.Database.Preference", b => + { + b.Navigation("Profiles"); + }); + + modelBuilder.Entity("Content.Server.Database.Profile", b => + { + b.Navigation("Antags"); + + b.Navigation("Jobs"); + + b.Navigation("Traits"); + }); + + modelBuilder.Entity("Content.Server.Database.Round", b => + { + b.Navigation("AdminLogs"); + }); + + modelBuilder.Entity("Content.Server.Database.Server", b => + { + b.Navigation("Rounds"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBan", b => + { + b.Navigation("BanHits"); + + b.Navigation("Unban"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerRoleBan", b => + { + b.Navigation("Unban"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Content.Server.Database/Migrations/Postgres/20231024041204_DropAdminLogEntity.cs b/Content.Server.Database/Migrations/Postgres/20231024041204_DropAdminLogEntity.cs new file mode 100644 index 0000000000..ec9c2e9a6c --- /dev/null +++ b/Content.Server.Database/Migrations/Postgres/20231024041204_DropAdminLogEntity.cs @@ -0,0 +1,47 @@ +#nullable disable + +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Content.Server.Database.Migrations.Postgres +{ + /// + public partial class DropAdminLogEntity : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "admin_log_entity"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "admin_log_entity", + columns: table => new + { + uid = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + admin_log_id = table.Column(type: "integer", nullable: true), + admin_log_round_id = table.Column(type: "integer", nullable: true), + name = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_admin_log_entity", x => x.uid); + table.ForeignKey( + name: "FK_admin_log_entity_admin_log_admin_log_id_admin_log_round_id", + columns: x => new { x.admin_log_id, x.admin_log_round_id }, + principalTable: "admin_log", + principalColumns: new[] { "admin_log_id", "round_id" }); + }); + + migrationBuilder.CreateIndex( + name: "IX_admin_log_entity_admin_log_id_admin_log_round_id", + table: "admin_log_entity", + columns: new[] { "admin_log_id", "admin_log_round_id" }); + } + } +} diff --git a/Content.Server.Database/Migrations/Postgres/PostgresServerDbContextModelSnapshot.cs b/Content.Server.Database/Migrations/Postgres/PostgresServerDbContextModelSnapshot.cs index b7fa1a8843..e26527be9d 100644 --- a/Content.Server.Database/Migrations/Postgres/PostgresServerDbContextModelSnapshot.cs +++ b/Content.Server.Database/Migrations/Postgres/PostgresServerDbContextModelSnapshot.cs @@ -133,36 +133,6 @@ namespace Content.Server.Database.Migrations.Postgres b.ToTable("admin_log", (string)null); }); - modelBuilder.Entity("Content.Server.Database.AdminLogEntity", b => - { - b.Property("Uid") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasColumnName("uid"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Uid")); - - b.Property("AdminLogId") - .HasColumnType("integer") - .HasColumnName("admin_log_id"); - - b.Property("AdminLogRoundId") - .HasColumnType("integer") - .HasColumnName("admin_log_round_id"); - - b.Property("Name") - .HasColumnType("text") - .HasColumnName("name"); - - b.HasKey("Uid") - .HasName("PK_admin_log_entity"); - - b.HasIndex("AdminLogId", "AdminLogRoundId") - .HasDatabaseName("IX_admin_log_entity_admin_log_id_admin_log_round_id"); - - b.ToTable("admin_log_entity", (string)null); - }); - modelBuilder.Entity("Content.Server.Database.AdminLogPlayer", b => { b.Property("PlayerUserId") @@ -1312,14 +1282,6 @@ namespace Content.Server.Database.Migrations.Postgres b.Navigation("Round"); }); - modelBuilder.Entity("Content.Server.Database.AdminLogEntity", b => - { - b.HasOne("Content.Server.Database.AdminLog", null) - .WithMany("Entities") - .HasForeignKey("AdminLogId", "AdminLogRoundId") - .HasConstraintName("FK_admin_log_entity_admin_log_admin_log_id_admin_log_round_id"); - }); - modelBuilder.Entity("Content.Server.Database.AdminLogPlayer", b => { b.HasOne("Content.Server.Database.Player", "Player") @@ -1677,8 +1639,6 @@ namespace Content.Server.Database.Migrations.Postgres modelBuilder.Entity("Content.Server.Database.AdminLog", b => { - b.Navigation("Entities"); - b.Navigation("Players"); }); diff --git a/Content.Server.Database/Migrations/Sqlite/20231024041159_DropAdminLogEntity.Designer.cs b/Content.Server.Database/Migrations/Sqlite/20231024041159_DropAdminLogEntity.Designer.cs new file mode 100644 index 0000000000..887e157ec3 --- /dev/null +++ b/Content.Server.Database/Migrations/Sqlite/20231024041159_DropAdminLogEntity.Designer.cs @@ -0,0 +1,1667 @@ +// +using System; +using Content.Server.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Content.Server.Database.Migrations.Sqlite +{ + [DbContext(typeof(SqliteServerDbContext))] + [Migration("20231024041159_DropAdminLogEntity")] + partial class DropAdminLogEntity + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.4"); + + modelBuilder.Entity("Content.Server.Database.Admin", b => + { + b.Property("UserId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.Property("AdminRankId") + .HasColumnType("INTEGER") + .HasColumnName("admin_rank_id"); + + b.Property("Title") + .HasColumnType("TEXT") + .HasColumnName("title"); + + b.HasKey("UserId") + .HasName("PK_admin"); + + b.HasIndex("AdminRankId") + .HasDatabaseName("IX_admin_admin_rank_id"); + + b.ToTable("admin", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminFlag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("admin_flag_id"); + + b.Property("AdminId") + .HasColumnType("TEXT") + .HasColumnName("admin_id"); + + b.Property("Flag") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("flag"); + + b.Property("Negative") + .HasColumnType("INTEGER") + .HasColumnName("negative"); + + b.HasKey("Id") + .HasName("PK_admin_flag"); + + b.HasIndex("AdminId") + .HasDatabaseName("IX_admin_flag_admin_id"); + + b.HasIndex("Flag", "AdminId") + .IsUnique(); + + b.ToTable("admin_flag", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLog", b => + { + b.Property("Id") + .HasColumnType("INTEGER") + .HasColumnName("admin_log_id"); + + b.Property("RoundId") + .HasColumnType("INTEGER") + .HasColumnName("round_id"); + + b.Property("Date") + .HasColumnType("TEXT") + .HasColumnName("date"); + + b.Property("Impact") + .HasColumnType("INTEGER") + .HasColumnName("impact"); + + b.Property("Json") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("json"); + + b.Property("Message") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("message"); + + b.Property("Type") + .HasColumnType("INTEGER") + .HasColumnName("type"); + + b.HasKey("Id", "RoundId") + .HasName("PK_admin_log"); + + b.HasIndex("Date"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_admin_log_round_id"); + + b.HasIndex("Type") + .HasDatabaseName("IX_admin_log_type"); + + b.ToTable("admin_log", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLogPlayer", b => + { + b.Property("PlayerUserId") + .HasColumnType("TEXT") + .HasColumnName("player_user_id"); + + b.Property("LogId") + .HasColumnType("INTEGER") + .HasColumnName("log_id"); + + b.Property("RoundId") + .HasColumnType("INTEGER") + .HasColumnName("round_id"); + + b.HasKey("PlayerUserId", "LogId", "RoundId") + .HasName("PK_admin_log_player"); + + b.HasIndex("LogId", "RoundId"); + + b.ToTable("admin_log_player", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("admin_messages_id"); + + b.Property("CreatedAt") + .HasColumnType("TEXT") + .HasColumnName("created_at"); + + b.Property("CreatedById") + .HasColumnType("TEXT") + .HasColumnName("created_by_id"); + + b.Property("Deleted") + .HasColumnType("INTEGER") + .HasColumnName("deleted"); + + b.Property("DeletedAt") + .HasColumnType("TEXT") + .HasColumnName("deleted_at"); + + b.Property("DeletedById") + .HasColumnType("TEXT") + .HasColumnName("deleted_by_id"); + + b.Property("ExpirationTime") + .HasColumnType("TEXT") + .HasColumnName("expiration_time"); + + b.Property("LastEditedAt") + .HasColumnType("TEXT") + .HasColumnName("last_edited_at"); + + b.Property("LastEditedById") + .HasColumnType("TEXT") + .HasColumnName("last_edited_by_id"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("TEXT") + .HasColumnName("message"); + + b.Property("PlayerUserId") + .HasColumnType("TEXT") + .HasColumnName("player_user_id"); + + b.Property("PlaytimeAtNote") + .HasColumnType("TEXT") + .HasColumnName("playtime_at_note"); + + b.Property("RoundId") + .HasColumnType("INTEGER") + .HasColumnName("round_id"); + + b.Property("Seen") + .HasColumnType("INTEGER") + .HasColumnName("seen"); + + b.HasKey("Id") + .HasName("PK_admin_messages"); + + b.HasIndex("CreatedById"); + + b.HasIndex("DeletedById"); + + b.HasIndex("LastEditedById"); + + b.HasIndex("PlayerUserId") + .HasDatabaseName("IX_admin_messages_player_user_id"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_admin_messages_round_id"); + + b.ToTable("admin_messages", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminNote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("admin_notes_id"); + + b.Property("CreatedAt") + .HasColumnType("TEXT") + .HasColumnName("created_at"); + + b.Property("CreatedById") + .HasColumnType("TEXT") + .HasColumnName("created_by_id"); + + b.Property("Deleted") + .HasColumnType("INTEGER") + .HasColumnName("deleted"); + + b.Property("DeletedAt") + .HasColumnType("TEXT") + .HasColumnName("deleted_at"); + + b.Property("DeletedById") + .HasColumnType("TEXT") + .HasColumnName("deleted_by_id"); + + b.Property("ExpirationTime") + .HasColumnType("TEXT") + .HasColumnName("expiration_time"); + + b.Property("LastEditedAt") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("last_edited_at"); + + b.Property("LastEditedById") + .HasColumnType("TEXT") + .HasColumnName("last_edited_by_id"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("TEXT") + .HasColumnName("message"); + + b.Property("PlayerUserId") + .HasColumnType("TEXT") + .HasColumnName("player_user_id"); + + b.Property("PlaytimeAtNote") + .HasColumnType("TEXT") + .HasColumnName("playtime_at_note"); + + b.Property("RoundId") + .HasColumnType("INTEGER") + .HasColumnName("round_id"); + + b.Property("Secret") + .HasColumnType("INTEGER") + .HasColumnName("secret"); + + b.Property("Severity") + .HasColumnType("INTEGER") + .HasColumnName("severity"); + + b.HasKey("Id") + .HasName("PK_admin_notes"); + + b.HasIndex("CreatedById"); + + b.HasIndex("DeletedById"); + + b.HasIndex("LastEditedById"); + + b.HasIndex("PlayerUserId") + .HasDatabaseName("IX_admin_notes_player_user_id"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_admin_notes_round_id"); + + b.ToTable("admin_notes", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRank", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("admin_rank_id"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("PK_admin_rank"); + + b.ToTable("admin_rank", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRankFlag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("admin_rank_flag_id"); + + b.Property("AdminRankId") + .HasColumnType("INTEGER") + .HasColumnName("admin_rank_id"); + + b.Property("Flag") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("flag"); + + b.HasKey("Id") + .HasName("PK_admin_rank_flag"); + + b.HasIndex("AdminRankId"); + + b.HasIndex("Flag", "AdminRankId") + .IsUnique(); + + b.ToTable("admin_rank_flag", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AdminWatchlist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("admin_watchlists_id"); + + b.Property("CreatedAt") + .HasColumnType("TEXT") + .HasColumnName("created_at"); + + b.Property("CreatedById") + .HasColumnType("TEXT") + .HasColumnName("created_by_id"); + + b.Property("Deleted") + .HasColumnType("INTEGER") + .HasColumnName("deleted"); + + b.Property("DeletedAt") + .HasColumnType("TEXT") + .HasColumnName("deleted_at"); + + b.Property("DeletedById") + .HasColumnType("TEXT") + .HasColumnName("deleted_by_id"); + + b.Property("ExpirationTime") + .HasColumnType("TEXT") + .HasColumnName("expiration_time"); + + b.Property("LastEditedAt") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("last_edited_at"); + + b.Property("LastEditedById") + .HasColumnType("TEXT") + .HasColumnName("last_edited_by_id"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("TEXT") + .HasColumnName("message"); + + b.Property("PlayerUserId") + .HasColumnType("TEXT") + .HasColumnName("player_user_id"); + + b.Property("PlaytimeAtNote") + .HasColumnType("TEXT") + .HasColumnName("playtime_at_note"); + + b.Property("RoundId") + .HasColumnType("INTEGER") + .HasColumnName("round_id"); + + b.HasKey("Id") + .HasName("PK_admin_watchlists"); + + b.HasIndex("CreatedById"); + + b.HasIndex("DeletedById"); + + b.HasIndex("LastEditedById"); + + b.HasIndex("PlayerUserId") + .HasDatabaseName("IX_admin_watchlists_player_user_id"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_admin_watchlists_round_id"); + + b.ToTable("admin_watchlists", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Antag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("antag_id"); + + b.Property("AntagName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("antag_name"); + + b.Property("ProfileId") + .HasColumnType("INTEGER") + .HasColumnName("profile_id"); + + b.HasKey("Id") + .HasName("PK_antag"); + + b.HasIndex("ProfileId", "AntagName") + .IsUnique(); + + b.ToTable("antag", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.AssignedUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("assigned_user_id_id"); + + b.Property("UserId") + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("user_name"); + + b.HasKey("Id") + .HasName("PK_assigned_user_id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.HasIndex("UserName") + .IsUnique(); + + b.ToTable("assigned_user_id", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.ConnectionLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("connection_log_id"); + + b.Property("Address") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("address"); + + b.Property("Denied") + .HasColumnType("INTEGER") + .HasColumnName("denied"); + + b.Property("HWId") + .HasColumnType("BLOB") + .HasColumnName("hwid"); + + b.Property("Time") + .HasColumnType("TEXT") + .HasColumnName("time"); + + b.Property("UserId") + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("user_name"); + + b.HasKey("Id") + .HasName("PK_connection_log"); + + b.HasIndex("UserId"); + + b.ToTable("connection_log", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Job", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("job_id"); + + b.Property("JobName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("job_name"); + + b.Property("Priority") + .HasColumnType("INTEGER") + .HasColumnName("priority"); + + b.Property("ProfileId") + .HasColumnType("INTEGER") + .HasColumnName("profile_id"); + + b.HasKey("Id") + .HasName("PK_job"); + + b.HasIndex("ProfileId"); + + b.HasIndex("ProfileId", "JobName") + .IsUnique(); + + b.HasIndex(new[] { "ProfileId" }, "IX_job_one_high_priority") + .IsUnique() + .HasFilter("priority = 3"); + + b.ToTable("job", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.PlayTime", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("play_time_id"); + + b.Property("PlayerId") + .HasColumnType("TEXT") + .HasColumnName("player_id"); + + b.Property("TimeSpent") + .HasColumnType("TEXT") + .HasColumnName("time_spent"); + + b.Property("Tracker") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("tracker"); + + b.HasKey("Id") + .HasName("PK_play_time"); + + b.HasIndex("PlayerId", "Tracker") + .IsUnique(); + + b.ToTable("play_time", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Player", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("player_id"); + + b.Property("FirstSeenTime") + .HasColumnType("TEXT") + .HasColumnName("first_seen_time"); + + b.Property("LastReadRules") + .HasColumnType("TEXT") + .HasColumnName("last_read_rules"); + + b.Property("LastSeenAddress") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("last_seen_address"); + + b.Property("LastSeenHWId") + .HasColumnType("BLOB") + .HasColumnName("last_seen_hwid"); + + b.Property("LastSeenTime") + .HasColumnType("TEXT") + .HasColumnName("last_seen_time"); + + b.Property("LastSeenUserName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("last_seen_user_name"); + + b.Property("UserId") + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("PK_player"); + + b.HasAlternateKey("UserId") + .HasName("ak_player_user_id"); + + b.HasIndex("LastSeenUserName"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("player", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Preference", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("preference_id"); + + b.Property("AdminOOCColor") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("admin_ooc_color"); + + b.Property("SelectedCharacterSlot") + .HasColumnType("INTEGER") + .HasColumnName("selected_character_slot"); + + b.Property("UserId") + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("PK_preference"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("preference", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Profile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("profile_id"); + + b.Property("Age") + .HasColumnType("INTEGER") + .HasColumnName("age"); + + b.Property("Backpack") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("backpack"); + + b.Property("CharacterName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("char_name"); + + b.Property("Clothing") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("clothing"); + + b.Property("EyeColor") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("eye_color"); + + b.Property("FacialHairColor") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("facial_hair_color"); + + b.Property("FacialHairName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("facial_hair_name"); + + b.Property("FlavorText") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("flavor_text"); + + b.Property("Gender") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("gender"); + + b.Property("HairColor") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("hair_color"); + + b.Property("HairName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("hair_name"); + + b.Property("Markings") + .HasColumnType("jsonb") + .HasColumnName("markings"); + + b.Property("PreferenceId") + .HasColumnType("INTEGER") + .HasColumnName("preference_id"); + + b.Property("PreferenceUnavailable") + .HasColumnType("INTEGER") + .HasColumnName("pref_unavailable"); + + b.Property("Sex") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("sex"); + + b.Property("SkinColor") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("skin_color"); + + b.Property("Slot") + .HasColumnType("INTEGER") + .HasColumnName("slot"); + + b.Property("Species") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("species"); + + b.HasKey("Id") + .HasName("PK_profile"); + + b.HasIndex("PreferenceId") + .HasDatabaseName("IX_profile_preference_id"); + + b.HasIndex("Slot", "PreferenceId") + .IsUnique(); + + b.ToTable("profile", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Round", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("round_id"); + + b.Property("ServerId") + .HasColumnType("INTEGER") + .HasColumnName("server_id"); + + b.Property("StartDate") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasDefaultValue(new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)) + .HasColumnName("start_date"); + + b.HasKey("Id") + .HasName("PK_round"); + + b.HasIndex("ServerId") + .HasDatabaseName("IX_round_server_id"); + + b.HasIndex("StartDate"); + + b.ToTable("round", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Server", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("server_id"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("PK_server"); + + b.ToTable("server", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("server_ban_id"); + + b.Property("Address") + .HasColumnType("TEXT") + .HasColumnName("address"); + + b.Property("AutoDelete") + .HasColumnType("INTEGER") + .HasColumnName("auto_delete"); + + b.Property("BanTime") + .HasColumnType("TEXT") + .HasColumnName("ban_time"); + + b.Property("BanningAdmin") + .HasColumnType("TEXT") + .HasColumnName("banning_admin"); + + b.Property("ExemptFlags") + .HasColumnType("INTEGER") + .HasColumnName("exempt_flags"); + + b.Property("ExpirationTime") + .HasColumnType("TEXT") + .HasColumnName("expiration_time"); + + b.Property("HWId") + .HasColumnType("BLOB") + .HasColumnName("hwid"); + + b.Property("Hidden") + .HasColumnType("INTEGER") + .HasColumnName("hidden"); + + b.Property("LastEditedAt") + .HasColumnType("TEXT") + .HasColumnName("last_edited_at"); + + b.Property("LastEditedById") + .HasColumnType("TEXT") + .HasColumnName("last_edited_by_id"); + + b.Property("PlayerUserId") + .HasColumnType("TEXT") + .HasColumnName("player_user_id"); + + b.Property("PlaytimeAtNote") + .HasColumnType("TEXT") + .HasColumnName("playtime_at_note"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("reason"); + + b.Property("RoundId") + .HasColumnType("INTEGER") + .HasColumnName("round_id"); + + b.Property("Severity") + .HasColumnType("INTEGER") + .HasColumnName("severity"); + + b.HasKey("Id") + .HasName("PK_server_ban"); + + b.HasIndex("Address"); + + b.HasIndex("BanningAdmin"); + + b.HasIndex("LastEditedById"); + + b.HasIndex("PlayerUserId") + .HasDatabaseName("IX_server_ban_player_user_id"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_server_ban_round_id"); + + b.ToTable("server_ban", null, t => + { + t.HasCheckConstraint("HaveEitherAddressOrUserIdOrHWId", "address IS NOT NULL OR player_user_id IS NOT NULL OR hwid IS NOT NULL"); + }); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBanExemption", b => + { + b.Property("UserId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.Property("Flags") + .HasColumnType("INTEGER") + .HasColumnName("flags"); + + b.HasKey("UserId") + .HasName("PK_server_ban_exemption"); + + b.ToTable("server_ban_exemption", null, t => + { + t.HasCheckConstraint("FlagsNotZero", "flags != 0"); + }); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBanHit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("server_ban_hit_id"); + + b.Property("BanId") + .HasColumnType("INTEGER") + .HasColumnName("ban_id"); + + b.Property("ConnectionId") + .HasColumnType("INTEGER") + .HasColumnName("connection_id"); + + b.HasKey("Id") + .HasName("PK_server_ban_hit"); + + b.HasIndex("BanId") + .HasDatabaseName("IX_server_ban_hit_ban_id"); + + b.HasIndex("ConnectionId") + .HasDatabaseName("IX_server_ban_hit_connection_id"); + + b.ToTable("server_ban_hit", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.ServerRoleBan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("server_role_ban_id"); + + b.Property("Address") + .HasColumnType("TEXT") + .HasColumnName("address"); + + b.Property("BanTime") + .HasColumnType("TEXT") + .HasColumnName("ban_time"); + + b.Property("BanningAdmin") + .HasColumnType("TEXT") + .HasColumnName("banning_admin"); + + b.Property("ExpirationTime") + .HasColumnType("TEXT") + .HasColumnName("expiration_time"); + + b.Property("HWId") + .HasColumnType("BLOB") + .HasColumnName("hwid"); + + b.Property("Hidden") + .HasColumnType("INTEGER") + .HasColumnName("hidden"); + + b.Property("LastEditedAt") + .HasColumnType("TEXT") + .HasColumnName("last_edited_at"); + + b.Property("LastEditedById") + .HasColumnType("TEXT") + .HasColumnName("last_edited_by_id"); + + b.Property("PlayerUserId") + .HasColumnType("TEXT") + .HasColumnName("player_user_id"); + + b.Property("PlaytimeAtNote") + .HasColumnType("TEXT") + .HasColumnName("playtime_at_note"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("reason"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("role_id"); + + b.Property("RoundId") + .HasColumnType("INTEGER") + .HasColumnName("round_id"); + + b.Property("Severity") + .HasColumnType("INTEGER") + .HasColumnName("severity"); + + b.HasKey("Id") + .HasName("PK_server_role_ban"); + + b.HasIndex("Address"); + + b.HasIndex("BanningAdmin"); + + b.HasIndex("LastEditedById"); + + b.HasIndex("PlayerUserId") + .HasDatabaseName("IX_server_role_ban_player_user_id"); + + b.HasIndex("RoundId") + .HasDatabaseName("IX_server_role_ban_round_id"); + + b.ToTable("server_role_ban", null, t => + { + t.HasCheckConstraint("HaveEitherAddressOrUserIdOrHWId", "address IS NOT NULL OR player_user_id IS NOT NULL OR hwid IS NOT NULL"); + }); + }); + + modelBuilder.Entity("Content.Server.Database.ServerRoleUnban", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("role_unban_id"); + + b.Property("BanId") + .HasColumnType("INTEGER") + .HasColumnName("ban_id"); + + b.Property("UnbanTime") + .HasColumnType("TEXT") + .HasColumnName("unban_time"); + + b.Property("UnbanningAdmin") + .HasColumnType("TEXT") + .HasColumnName("unbanning_admin"); + + b.HasKey("Id") + .HasName("PK_server_role_unban"); + + b.HasIndex("BanId") + .IsUnique(); + + b.ToTable("server_role_unban", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.ServerUnban", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("unban_id"); + + b.Property("BanId") + .HasColumnType("INTEGER") + .HasColumnName("ban_id"); + + b.Property("UnbanTime") + .HasColumnType("TEXT") + .HasColumnName("unban_time"); + + b.Property("UnbanningAdmin") + .HasColumnType("TEXT") + .HasColumnName("unbanning_admin"); + + b.HasKey("Id") + .HasName("PK_server_unban"); + + b.HasIndex("BanId") + .IsUnique(); + + b.ToTable("server_unban", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Trait", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("trait_id"); + + b.Property("ProfileId") + .HasColumnType("INTEGER") + .HasColumnName("profile_id"); + + b.Property("TraitName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("trait_name"); + + b.HasKey("Id") + .HasName("PK_trait"); + + b.HasIndex("ProfileId", "TraitName") + .IsUnique(); + + b.ToTable("trait", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.UploadedResourceLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("uploaded_resource_log_id"); + + b.Property("Data") + .IsRequired() + .HasColumnType("BLOB") + .HasColumnName("data"); + + b.Property("Date") + .HasColumnType("TEXT") + .HasColumnName("date"); + + b.Property("Path") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("path"); + + b.Property("UserId") + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("PK_uploaded_resource_log"); + + b.ToTable("uploaded_resource_log", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Whitelist", b => + { + b.Property("UserId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.HasKey("UserId") + .HasName("PK_whitelist"); + + b.ToTable("whitelist", (string)null); + }); + + modelBuilder.Entity("PlayerRound", b => + { + b.Property("PlayersId") + .HasColumnType("INTEGER") + .HasColumnName("players_id"); + + b.Property("RoundsId") + .HasColumnType("INTEGER") + .HasColumnName("rounds_id"); + + b.HasKey("PlayersId", "RoundsId") + .HasName("PK_player_round"); + + b.HasIndex("RoundsId") + .HasDatabaseName("IX_player_round_rounds_id"); + + b.ToTable("player_round", (string)null); + }); + + modelBuilder.Entity("Content.Server.Database.Admin", b => + { + b.HasOne("Content.Server.Database.AdminRank", "AdminRank") + .WithMany("Admins") + .HasForeignKey("AdminRankId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_admin_rank_admin_rank_id"); + + b.Navigation("AdminRank"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminFlag", b => + { + b.HasOne("Content.Server.Database.Admin", "Admin") + .WithMany("Flags") + .HasForeignKey("AdminId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_admin_flag_admin_admin_id"); + + b.Navigation("Admin"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLog", b => + { + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany("AdminLogs") + .HasForeignKey("RoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_admin_log_round_round_id"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLogPlayer", b => + { + b.HasOne("Content.Server.Database.Player", "Player") + .WithMany("AdminLogs") + .HasForeignKey("PlayerUserId") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_admin_log_player_player_player_user_id"); + + b.HasOne("Content.Server.Database.AdminLog", "Log") + .WithMany("Players") + .HasForeignKey("LogId", "RoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_admin_log_player_admin_log_log_id_round_id"); + + b.Navigation("Log"); + + b.Navigation("Player"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminMessage", b => + { + b.HasOne("Content.Server.Database.Player", "CreatedBy") + .WithMany("AdminMessagesCreated") + .HasForeignKey("CreatedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_messages_player_created_by_id"); + + b.HasOne("Content.Server.Database.Player", "DeletedBy") + .WithMany("AdminMessagesDeleted") + .HasForeignKey("DeletedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_messages_player_deleted_by_id"); + + b.HasOne("Content.Server.Database.Player", "LastEditedBy") + .WithMany("AdminMessagesLastEdited") + .HasForeignKey("LastEditedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_messages_player_last_edited_by_id"); + + b.HasOne("Content.Server.Database.Player", "Player") + .WithMany("AdminMessagesReceived") + .HasForeignKey("PlayerUserId") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("FK_admin_messages_player_player_user_id"); + + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany() + .HasForeignKey("RoundId") + .HasConstraintName("FK_admin_messages_round_round_id"); + + b.Navigation("CreatedBy"); + + b.Navigation("DeletedBy"); + + b.Navigation("LastEditedBy"); + + b.Navigation("Player"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminNote", b => + { + b.HasOne("Content.Server.Database.Player", "CreatedBy") + .WithMany("AdminNotesCreated") + .HasForeignKey("CreatedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_notes_player_created_by_id"); + + b.HasOne("Content.Server.Database.Player", "DeletedBy") + .WithMany("AdminNotesDeleted") + .HasForeignKey("DeletedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_notes_player_deleted_by_id"); + + b.HasOne("Content.Server.Database.Player", "LastEditedBy") + .WithMany("AdminNotesLastEdited") + .HasForeignKey("LastEditedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_notes_player_last_edited_by_id"); + + b.HasOne("Content.Server.Database.Player", "Player") + .WithMany("AdminNotesReceived") + .HasForeignKey("PlayerUserId") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("FK_admin_notes_player_player_user_id"); + + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany() + .HasForeignKey("RoundId") + .HasConstraintName("FK_admin_notes_round_round_id"); + + b.Navigation("CreatedBy"); + + b.Navigation("DeletedBy"); + + b.Navigation("LastEditedBy"); + + b.Navigation("Player"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRankFlag", b => + { + b.HasOne("Content.Server.Database.AdminRank", "Rank") + .WithMany("Flags") + .HasForeignKey("AdminRankId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_admin_rank_flag_admin_rank_admin_rank_id"); + + b.Navigation("Rank"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminWatchlist", b => + { + b.HasOne("Content.Server.Database.Player", "CreatedBy") + .WithMany("AdminWatchlistsCreated") + .HasForeignKey("CreatedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_watchlists_player_created_by_id"); + + b.HasOne("Content.Server.Database.Player", "DeletedBy") + .WithMany("AdminWatchlistsDeleted") + .HasForeignKey("DeletedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_watchlists_player_deleted_by_id"); + + b.HasOne("Content.Server.Database.Player", "LastEditedBy") + .WithMany("AdminWatchlistsLastEdited") + .HasForeignKey("LastEditedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_admin_watchlists_player_last_edited_by_id"); + + b.HasOne("Content.Server.Database.Player", "Player") + .WithMany("AdminWatchlistsReceived") + .HasForeignKey("PlayerUserId") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("FK_admin_watchlists_player_player_user_id"); + + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany() + .HasForeignKey("RoundId") + .HasConstraintName("FK_admin_watchlists_round_round_id"); + + b.Navigation("CreatedBy"); + + b.Navigation("DeletedBy"); + + b.Navigation("LastEditedBy"); + + b.Navigation("Player"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.Antag", b => + { + b.HasOne("Content.Server.Database.Profile", "Profile") + .WithMany("Antags") + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_antag_profile_profile_id"); + + b.Navigation("Profile"); + }); + + modelBuilder.Entity("Content.Server.Database.Job", b => + { + b.HasOne("Content.Server.Database.Profile", "Profile") + .WithMany("Jobs") + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_job_profile_profile_id"); + + b.Navigation("Profile"); + }); + + modelBuilder.Entity("Content.Server.Database.Profile", b => + { + b.HasOne("Content.Server.Database.Preference", "Preference") + .WithMany("Profiles") + .HasForeignKey("PreferenceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_profile_preference_preference_id"); + + b.Navigation("Preference"); + }); + + modelBuilder.Entity("Content.Server.Database.Round", b => + { + b.HasOne("Content.Server.Database.Server", "Server") + .WithMany("Rounds") + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_round_server_server_id"); + + b.Navigation("Server"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBan", b => + { + b.HasOne("Content.Server.Database.Player", "CreatedBy") + .WithMany("AdminServerBansCreated") + .HasForeignKey("BanningAdmin") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_server_ban_player_banning_admin"); + + b.HasOne("Content.Server.Database.Player", "LastEditedBy") + .WithMany("AdminServerBansLastEdited") + .HasForeignKey("LastEditedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_server_ban_player_last_edited_by_id"); + + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany() + .HasForeignKey("RoundId") + .HasConstraintName("FK_server_ban_round_round_id"); + + b.Navigation("CreatedBy"); + + b.Navigation("LastEditedBy"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBanHit", b => + { + b.HasOne("Content.Server.Database.ServerBan", "Ban") + .WithMany("BanHits") + .HasForeignKey("BanId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_server_ban_hit_server_ban_ban_id"); + + b.HasOne("Content.Server.Database.ConnectionLog", "Connection") + .WithMany("BanHits") + .HasForeignKey("ConnectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_server_ban_hit_connection_log_connection_id"); + + b.Navigation("Ban"); + + b.Navigation("Connection"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerRoleBan", b => + { + b.HasOne("Content.Server.Database.Player", "CreatedBy") + .WithMany("AdminServerRoleBansCreated") + .HasForeignKey("BanningAdmin") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_server_role_ban_player_banning_admin"); + + b.HasOne("Content.Server.Database.Player", "LastEditedBy") + .WithMany("AdminServerRoleBansLastEdited") + .HasForeignKey("LastEditedById") + .HasPrincipalKey("UserId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("FK_server_role_ban_player_last_edited_by_id"); + + b.HasOne("Content.Server.Database.Round", "Round") + .WithMany() + .HasForeignKey("RoundId") + .HasConstraintName("FK_server_role_ban_round_round_id"); + + b.Navigation("CreatedBy"); + + b.Navigation("LastEditedBy"); + + b.Navigation("Round"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerRoleUnban", b => + { + b.HasOne("Content.Server.Database.ServerRoleBan", "Ban") + .WithOne("Unban") + .HasForeignKey("Content.Server.Database.ServerRoleUnban", "BanId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_server_role_unban_server_role_ban_ban_id"); + + b.Navigation("Ban"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerUnban", b => + { + b.HasOne("Content.Server.Database.ServerBan", "Ban") + .WithOne("Unban") + .HasForeignKey("Content.Server.Database.ServerUnban", "BanId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_server_unban_server_ban_ban_id"); + + b.Navigation("Ban"); + }); + + modelBuilder.Entity("Content.Server.Database.Trait", b => + { + b.HasOne("Content.Server.Database.Profile", "Profile") + .WithMany("Traits") + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_trait_profile_profile_id"); + + b.Navigation("Profile"); + }); + + modelBuilder.Entity("PlayerRound", b => + { + b.HasOne("Content.Server.Database.Player", null) + .WithMany() + .HasForeignKey("PlayersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_player_round_player_players_id"); + + b.HasOne("Content.Server.Database.Round", null) + .WithMany() + .HasForeignKey("RoundsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_player_round_round_rounds_id"); + }); + + modelBuilder.Entity("Content.Server.Database.Admin", b => + { + b.Navigation("Flags"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminLog", b => + { + b.Navigation("Players"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRank", b => + { + b.Navigation("Admins"); + + b.Navigation("Flags"); + }); + + modelBuilder.Entity("Content.Server.Database.ConnectionLog", b => + { + b.Navigation("BanHits"); + }); + + modelBuilder.Entity("Content.Server.Database.Player", b => + { + b.Navigation("AdminLogs"); + + b.Navigation("AdminMessagesCreated"); + + b.Navigation("AdminMessagesDeleted"); + + b.Navigation("AdminMessagesLastEdited"); + + b.Navigation("AdminMessagesReceived"); + + b.Navigation("AdminNotesCreated"); + + b.Navigation("AdminNotesDeleted"); + + b.Navigation("AdminNotesLastEdited"); + + b.Navigation("AdminNotesReceived"); + + b.Navigation("AdminServerBansCreated"); + + b.Navigation("AdminServerBansLastEdited"); + + b.Navigation("AdminServerRoleBansCreated"); + + b.Navigation("AdminServerRoleBansLastEdited"); + + b.Navigation("AdminWatchlistsCreated"); + + b.Navigation("AdminWatchlistsDeleted"); + + b.Navigation("AdminWatchlistsLastEdited"); + + b.Navigation("AdminWatchlistsReceived"); + }); + + modelBuilder.Entity("Content.Server.Database.Preference", b => + { + b.Navigation("Profiles"); + }); + + modelBuilder.Entity("Content.Server.Database.Profile", b => + { + b.Navigation("Antags"); + + b.Navigation("Jobs"); + + b.Navigation("Traits"); + }); + + modelBuilder.Entity("Content.Server.Database.Round", b => + { + b.Navigation("AdminLogs"); + }); + + modelBuilder.Entity("Content.Server.Database.Server", b => + { + b.Navigation("Rounds"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerBan", b => + { + b.Navigation("BanHits"); + + b.Navigation("Unban"); + }); + + modelBuilder.Entity("Content.Server.Database.ServerRoleBan", b => + { + b.Navigation("Unban"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Content.Server.Database/Migrations/Sqlite/20231024041159_DropAdminLogEntity.cs b/Content.Server.Database/Migrations/Sqlite/20231024041159_DropAdminLogEntity.cs new file mode 100644 index 0000000000..59e9efce4e --- /dev/null +++ b/Content.Server.Database/Migrations/Sqlite/20231024041159_DropAdminLogEntity.cs @@ -0,0 +1,46 @@ +#nullable disable + +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Content.Server.Database.Migrations.Sqlite +{ + /// + public partial class DropAdminLogEntity : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "admin_log_entity"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "admin_log_entity", + columns: table => new + { + uid = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + admin_log_id = table.Column(type: "INTEGER", nullable: true), + admin_log_round_id = table.Column(type: "INTEGER", nullable: true), + name = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_admin_log_entity", x => x.uid); + table.ForeignKey( + name: "FK_admin_log_entity_admin_log_admin_log_id_admin_log_round_id", + columns: x => new { x.admin_log_id, x.admin_log_round_id }, + principalTable: "admin_log", + principalColumns: new[] { "admin_log_id", "round_id" }); + }); + + migrationBuilder.CreateIndex( + name: "IX_admin_log_entity_admin_log_id_admin_log_round_id", + table: "admin_log_entity", + columns: new[] { "admin_log_id", "admin_log_round_id" }); + } + } +} diff --git a/Content.Server.Database/Migrations/Sqlite/SqliteServerDbContextModelSnapshot.cs b/Content.Server.Database/Migrations/Sqlite/SqliteServerDbContextModelSnapshot.cs index c20743b94d..5afea5b58f 100644 --- a/Content.Server.Database/Migrations/Sqlite/SqliteServerDbContextModelSnapshot.cs +++ b/Content.Server.Database/Migrations/Sqlite/SqliteServerDbContextModelSnapshot.cs @@ -119,34 +119,6 @@ namespace Content.Server.Database.Migrations.Sqlite b.ToTable("admin_log", (string)null); }); - modelBuilder.Entity("Content.Server.Database.AdminLogEntity", b => - { - b.Property("Uid") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER") - .HasColumnName("uid"); - - b.Property("AdminLogId") - .HasColumnType("INTEGER") - .HasColumnName("admin_log_id"); - - b.Property("AdminLogRoundId") - .HasColumnType("INTEGER") - .HasColumnName("admin_log_round_id"); - - b.Property("Name") - .HasColumnType("TEXT") - .HasColumnName("name"); - - b.HasKey("Uid") - .HasName("PK_admin_log_entity"); - - b.HasIndex("AdminLogId", "AdminLogRoundId") - .HasDatabaseName("IX_admin_log_entity_admin_log_id_admin_log_round_id"); - - b.ToTable("admin_log_entity", (string)null); - }); - modelBuilder.Entity("Content.Server.Database.AdminLogPlayer", b => { b.Property("PlayerUserId") @@ -1242,14 +1214,6 @@ namespace Content.Server.Database.Migrations.Sqlite b.Navigation("Round"); }); - modelBuilder.Entity("Content.Server.Database.AdminLogEntity", b => - { - b.HasOne("Content.Server.Database.AdminLog", null) - .WithMany("Entities") - .HasForeignKey("AdminLogId", "AdminLogRoundId") - .HasConstraintName("FK_admin_log_entity_admin_log_admin_log_id_admin_log_round_id"); - }); - modelBuilder.Entity("Content.Server.Database.AdminLogPlayer", b => { b.HasOne("Content.Server.Database.Player", "Player") @@ -1607,8 +1571,6 @@ namespace Content.Server.Database.Migrations.Sqlite modelBuilder.Entity("Content.Server.Database.AdminLog", b => { - b.Navigation("Entities"); - b.Navigation("Players"); }); diff --git a/Content.Server.Database/Model.cs b/Content.Server.Database/Model.cs index 298f849b47..c59d2d9255 100644 --- a/Content.Server.Database/Model.cs +++ b/Content.Server.Database/Model.cs @@ -516,9 +516,6 @@ namespace Content.Server.Database [Required, Column(TypeName = "jsonb")] public JsonDocument Json { get; set; } = default!; public List Players { get; set; } = default!; - - // Unused - public List Entities { get; set; } = default!; } public class AdminLogPlayer @@ -531,13 +528,6 @@ namespace Content.Server.Database [ForeignKey("LogId,RoundId")] public AdminLog Log { get; set; } = default!; } - // Unused - public class AdminLogEntity - { - [Required, Key] public int Uid { get; set; } - public string? Name { get; set; } = default!; - } - // Used by SS14.Admin public interface IBanCommon where TUnban : IUnbanCommon { From ddf1fd98ff4acfc433d5bc4f2cd2a917446782f3 Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Tue, 24 Oct 2023 02:18:46 -0400 Subject: [PATCH 011/102] fix magnet trigger for artifacts (#21213) --- .../Triggers/Systems/ArtifactMagnetTriggerSystem.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/Triggers/Systems/ArtifactMagnetTriggerSystem.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/Triggers/Systems/ArtifactMagnetTriggerSystem.cs index 0220c2ce1a..f51d617df8 100644 --- a/Content.Server/Xenoarchaeology/XenoArtifacts/Triggers/Systems/ArtifactMagnetTriggerSystem.cs +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/Triggers/Systems/ArtifactMagnetTriggerSystem.cs @@ -6,7 +6,7 @@ using Content.Shared.Clothing; namespace Content.Server.Xenoarchaeology.XenoArtifacts.Triggers.Systems; /// -/// This handles... +/// This handles artifacts that are activated by magnets, both salvage and magboots. /// public sealed class ArtifactMagnetTriggerSystem : EntitySystem { @@ -22,20 +22,20 @@ public sealed class ArtifactMagnetTriggerSystem : EntitySystem { base.Update(frameTime); - var artifactQuery = EntityQuery().ToHashSet(); - if (!artifactQuery.Any()) + if (!EntityQuery().Any()) return; List toActivate = new(); //assume that there's more instruments than artifacts var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out var magboot, out var magXform)) + while (query.MoveNext(out _, out var magboot, out var magXform)) { if (!magboot.On) continue; - foreach (var (trigger, xform) in artifactQuery) + var artiQuery = EntityQueryEnumerator(); + while (artiQuery.MoveNext(out var artifactUid, out var trigger, out var xform)) { if (!magXform.Coordinates.TryDistance(EntityManager, xform.Coordinates, out var distance)) continue; @@ -43,7 +43,7 @@ public sealed class ArtifactMagnetTriggerSystem : EntitySystem if (distance > trigger.Range) continue; - toActivate.Add(uid); + toActivate.Add(artifactUid); } } From 51885f4b4aefd877d743d31fbf5d5a037f10493c Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 24 Oct 2023 02:19:50 -0400 Subject: [PATCH 012/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 653c12af92..f1e19bf919 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,9 +1,4 @@ Entries: -- author: Nimfar11 - changes: - - {message: Adds a Secret Door for construction, type: Add} - id: 4545 - time: '2023-08-13T07:10:46.0000000+00:00' - author: Errant changes: - {message: Bolas are now easier to make and more durable., type: Tweak} @@ -2909,3 +2904,8 @@ Entries: dagger.), type: Tweak} id: 5044 time: '2023-10-23T14:35:33.0000000+00:00' +- author: EmoGarbage404 + changes: + - {message: Fixed activating artifacts with magboots., type: Fix} + id: 5045 + time: '2023-10-24T06:18:46.0000000+00:00' From 4bb355ab76e96ea64560beba65060327f1c2654b Mon Sep 17 00:00:00 2001 From: Stray-Pyramid Date: Tue, 24 Oct 2023 19:20:46 +1300 Subject: [PATCH 013/102] Fix ore bag not picking up artifact fragments (#21195) --- .../Storage/Components/MagnetPickupComponent.cs | 14 -------------- .../Storage/EntitySystems/MagnetPickupSystem.cs | 2 +- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/Content.Shared/Storage/Components/MagnetPickupComponent.cs b/Content.Shared/Storage/Components/MagnetPickupComponent.cs index 300055a62a..c57b7c4e85 100644 --- a/Content.Shared/Storage/Components/MagnetPickupComponent.cs +++ b/Content.Shared/Storage/Components/MagnetPickupComponent.cs @@ -1,6 +1,4 @@ using Content.Shared.Inventory; -using Content.Shared.Tag; -using Content.Shared.Whitelist; namespace Content.Server.Storage.Components; @@ -21,16 +19,4 @@ public sealed partial class MagnetPickupComponent : Component [ViewVariables(VVAccess.ReadWrite), DataField("range")] public float Range = 1f; - - [ValidatePrototypeId] - private const string DefaultTag = "Ore"; - - [ViewVariables(VVAccess.ReadWrite), DataField("whitelist")] - public EntityWhitelist? Whitelist = new() - { - Tags = new List() - { - DefaultTag, - } - }; } diff --git a/Content.Shared/Storage/EntitySystems/MagnetPickupSystem.cs b/Content.Shared/Storage/EntitySystems/MagnetPickupSystem.cs index 3bbc75732e..16657bdae4 100644 --- a/Content.Shared/Storage/EntitySystems/MagnetPickupSystem.cs +++ b/Content.Shared/Storage/EntitySystems/MagnetPickupSystem.cs @@ -72,7 +72,7 @@ public sealed class MagnetPickupSystem : EntitySystem foreach (var near in _lookup.GetEntitiesInRange(uid, comp.Range, LookupFlags.Dynamic | LookupFlags.Sundries)) { - if (comp.Whitelist?.IsValid(near, EntityManager) == false) + if (storage.Whitelist?.IsValid(near, EntityManager) == false) continue; if (!_physicsQuery.TryGetComponent(near, out var physics) || physics.BodyStatus != BodyStatus.OnGround) From 29889f5ba75efab9f1e11592863c66a19014fdb9 Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 24 Oct 2023 02:21:50 -0400 Subject: [PATCH 014/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index f1e19bf919..2d00c7a9ee 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,9 +1,4 @@ Entries: -- author: Errant - changes: - - {message: Bolas are now easier to make and more durable., type: Tweak} - id: 4546 - time: '2023-08-13T07:11:11.0000000+00:00' - author: Doru991 changes: - {message: 'Wheelchairs, unicycles and similar vehicles no longer act as a magical @@ -2909,3 +2904,8 @@ Entries: - {message: Fixed activating artifacts with magboots., type: Fix} id: 5045 time: '2023-10-24T06:18:46.0000000+00:00' +- author: Stray-Pyramid + changes: + - {message: Ore bags now pickup artifact fragments as well as ores, type: Fix} + id: 5046 + time: '2023-10-24T06:20:46.0000000+00:00' From 4e7bdc66582fa0a4418a7c4759d9b2f7062f6805 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Tue, 24 Oct 2023 17:22:05 +1100 Subject: [PATCH 015/102] Fix electrocution resolve error log (#21179) --- Content.Server/Electrocution/ElectrocutionSystem.cs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/Content.Server/Electrocution/ElectrocutionSystem.cs b/Content.Server/Electrocution/ElectrocutionSystem.cs index 6c96266740..8ddc8540c0 100644 --- a/Content.Server/Electrocution/ElectrocutionSystem.cs +++ b/Content.Server/Electrocution/ElectrocutionSystem.cs @@ -192,18 +192,13 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem private void OnLightAttacked(EntityUid uid, PoweredLightComponent component, AttackedEvent args) { + if (!component.CurrentLit || args.Used != args.User) + return; if (!_meleeWeapon.GetDamage(args.Used, args.User).Any()) return; - if (args.Used != args.User) - return; - - if (component.CurrentLit == false) - return; - DoCommonElectrocution(args.User, uid, component.UnarmedHitShock, component.UnarmedHitStun, false, 1); - } private void OnElectrifiedInteractUsing(EntityUid uid, ElectrifiedComponent electrified, InteractUsingEvent args) @@ -498,7 +493,7 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem private void PlayElectrocutionSound(EntityUid targetUid, EntityUid sourceUid, ElectrifiedComponent? electrified = null) { - if (!Resolve(sourceUid, ref electrified) || !electrified.PlaySoundOnShock) + if (!Resolve(sourceUid, ref electrified, false) || !electrified.PlaySoundOnShock) { return; } From 94796ddeee5a228f3398719dbee968e32a56ec8d Mon Sep 17 00:00:00 2001 From: Vasilis Date: Tue, 24 Oct 2023 09:47:53 +0200 Subject: [PATCH 016/102] Slightly better locale for revs (#21168) --- .../en-US/game-ticking/game-presets/preset-revolutionary.ftl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Resources/Locale/en-US/game-ticking/game-presets/preset-revolutionary.ftl b/Resources/Locale/en-US/game-ticking/game-presets/preset-revolutionary.ftl index 8958802161..c6e925d0c4 100644 --- a/Resources/Locale/en-US/game-ticking/game-presets/preset-revolutionary.ftl +++ b/Resources/Locale/en-US/game-ticking/game-presets/preset-revolutionary.ftl @@ -54,8 +54,8 @@ rev-won = The Head Revs survived and killed all of Command. rev-lost = Command survived and killed all of the Head Revs. -rev-stalemate = All of the Head Revs died and so did all of Command. We'll call it a draw. +rev-stalemate = All of the Head Revs and Command died. It's a draw. -rev-reverse-stalemate = I think the Head Revs and Command forgot to fight because they are both still alive. +rev-reverse-stalemate = Both Command and Head Revs survived. From fe3bcda7f2f08f458a918854d119a9f22de3e20b Mon Sep 17 00:00:00 2001 From: Whisper <121047731+QuietlyWhisper@users.noreply.github.com> Date: Tue, 24 Oct 2023 03:52:57 -0400 Subject: [PATCH 017/102] Remove noRot from asteroids (#21219) --- Resources/Prototypes/Entities/Structures/Walls/asteroid.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml index e64af7cbae..b36ba51ee0 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml @@ -18,7 +18,6 @@ - type: SmoothEdge - type: Sprite sprite: Structures/Walls/rock.rsi - noRot: true layers: - state: rock_asteroid - map: [ "enum.EdgeLayer.South" ] @@ -77,7 +76,6 @@ components: - type: Sprite sprite: Structures/Walls/rock.rsi - noRot: true layers: - state: rock_asteroid_ore - map: [ "enum.EdgeLayer.South" ] @@ -98,7 +96,6 @@ components: - type: Sprite sprite: Structures/Walls/rock.rsi - noRot: true layers: - state: rock_asteroid_ore1 - map: [ "enum.EdgeLayer.South" ] From 47b244b191f5e0dcea2ef63c0ff273ac81c379aa Mon Sep 17 00:00:00 2001 From: Morb <14136326+Morb0@users.noreply.github.com> Date: Tue, 24 Oct 2023 10:55:46 +0300 Subject: [PATCH 018/102] Hijack shuttle objective (#19621) Co-authored-by: DrSmugleaf --- .../Components/HijackShuttleComponent.cs | 8 ++ .../Systems/HijackShuttleConditionSystem.cs | 104 ++++++++++++++++++ .../Systems/EmergencyShuttleSystem.Console.cs | 8 ++ .../conditions/hijack-shuttle-condition.ftl | 2 + .../Prototypes/Objectives/objectiveGroups.yml | 1 + 5 files changed, 123 insertions(+) create mode 100644 Content.Server/Objectives/Components/HijackShuttleComponent.cs create mode 100644 Content.Server/Objectives/Systems/HijackShuttleConditionSystem.cs create mode 100644 Resources/Locale/en-US/objectives/conditions/hijack-shuttle-condition.ftl diff --git a/Content.Server/Objectives/Components/HijackShuttleComponent.cs b/Content.Server/Objectives/Components/HijackShuttleComponent.cs new file mode 100644 index 0000000000..010f6f1407 --- /dev/null +++ b/Content.Server/Objectives/Components/HijackShuttleComponent.cs @@ -0,0 +1,8 @@ +using Content.Server.Objectives.Systems; + +namespace Content.Server.Objectives.Components; + +[RegisterComponent, Access(typeof(HijackShuttleConditionSystem))] +public sealed partial class HijackShuttleComponent : Component +{ +} diff --git a/Content.Server/Objectives/Systems/HijackShuttleConditionSystem.cs b/Content.Server/Objectives/Systems/HijackShuttleConditionSystem.cs new file mode 100644 index 0000000000..5ea560297c --- /dev/null +++ b/Content.Server/Objectives/Systems/HijackShuttleConditionSystem.cs @@ -0,0 +1,104 @@ +using Content.Server.Objectives.Components; +using Content.Server.Shuttles.Components; +using Content.Server.Shuttles.Systems; +using Content.Shared.Cuffs.Components; +using Content.Shared.Humanoid; +using Content.Shared.Mind; +using Content.Shared.Mobs.Components; +using Content.Shared.Mobs.Systems; +using Content.Shared.Objectives.Components; +using Content.Shared.Roles; +using Robust.Shared.Player; + +namespace Content.Server.Objectives.Systems; + +public sealed class HijackShuttleConditionSystem : EntitySystem +{ + [Dependency] private readonly EmergencyShuttleSystem _emergencyShuttle = default!; + [Dependency] private readonly SharedMindSystem _mind = default!; + [Dependency] private readonly SharedRoleSystem _role = default!; + [Dependency] private readonly MobStateSystem _mobState = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnGetProgress); + } + + private void OnGetProgress(EntityUid uid, HijackShuttleComponent comp, ref ObjectiveGetProgressEvent args) + { + args.Progress = GetProgress(args.MindId, args.Mind); + } + + private float GetProgress(EntityUid mindId, MindComponent mind) + { + // not escaping alive if you're deleted/dead + if (mind.OwnedEntity == null || _mind.IsCharacterDeadIc(mind)) + return 0f; + + // You're not escaping if you're restrained! + if (TryComp(mind.OwnedEntity, out var cuffed) && cuffed.CuffedHandCount > 0) + return 0f; + + // There no emergency shuttles + if (!_emergencyShuttle.EmergencyShuttleArrived) + return 0f; + + // Check hijack for each emergency shuttle + foreach (var stationData in EntityQuery()) + { + if (stationData.EmergencyShuttle == null) + continue; + + if (IsShuttleHijacked(stationData.EmergencyShuttle.Value, mindId)) + return 1f; + } + + return 0f; + } + + private bool IsShuttleHijacked(EntityUid shuttleGridId, EntityUid mindId) + { + var gridPlayers = Filter.BroadcastGrid(shuttleGridId).Recipients; + var humanoids = GetEntityQuery(); + var cuffable = GetEntityQuery(); + EntityQuery(); + + var agentOnShuttle = false; + foreach (var player in gridPlayers) + { + if (player.AttachedEntity == null || + !_mind.TryGetMind(player.AttachedEntity.Value, out var crewMindId, out _)) + continue; + + if (mindId == crewMindId) + { + agentOnShuttle = true; + continue; + } + + var isHumanoid = humanoids.HasComponent(player.AttachedEntity.Value); + if (!isHumanoid) // Only humanoids count as enemies + continue; + + var isAntagonist = _role.MindIsAntagonist(mindId); + if (isAntagonist) // Allow antagonist + continue; + + var isPersonIncapacitated = _mobState.IsIncapacitated(player.AttachedEntity.Value); + if (isPersonIncapacitated) // Allow dead and crit + continue; + + var isPersonCuffed = + cuffable.TryGetComponent(player.AttachedEntity.Value, out var cuffed) + && cuffed.CuffedHandCount > 0; + if (isPersonCuffed) // Allow handcuffed + continue; + + return false; + } + + return agentOnShuttle; + } +} diff --git a/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.Console.cs b/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.Console.cs index 62478082d8..deb2ba256d 100644 --- a/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.Console.cs +++ b/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.Console.cs @@ -5,6 +5,7 @@ using Content.Server.UserInterface; using Content.Shared.Access; using Content.Shared.CCVar; using Content.Shared.Database; +using Content.Shared.Emag.Systems; using Content.Shared.Popups; using Content.Shared.Shuttles.BUIStates; using Content.Shared.Shuttles.Events; @@ -89,6 +90,7 @@ public sealed partial class EmergencyShuttleSystem SubscribeLocalEvent(OnEmergencyRepeal); SubscribeLocalEvent(OnEmergencyRepealAll); SubscribeLocalEvent(OnEmergencyOpenAttempt); + SubscribeLocalEvent(OnEmagged); SubscribeLocalEvent(OnEscapeUnpaused); } @@ -103,6 +105,12 @@ public sealed partial class EmergencyShuttleSystem } } + private void OnEmagged(EntityUid uid, EmergencyShuttleConsoleComponent component, ref GotEmaggedEvent args) + { + _logger.Add(LogType.EmergencyShuttle, LogImpact.Extreme, $"{ToPrettyString(args.UserUid):player} emagged shuttle console for early launch"); + EarlyLaunch(); + } + private void SetAuthorizeTime(float obj) { _authorizeTime = obj; diff --git a/Resources/Locale/en-US/objectives/conditions/hijack-shuttle-condition.ftl b/Resources/Locale/en-US/objectives/conditions/hijack-shuttle-condition.ftl new file mode 100644 index 0000000000..5a0c1fd88b --- /dev/null +++ b/Resources/Locale/en-US/objectives/conditions/hijack-shuttle-condition.ftl @@ -0,0 +1,2 @@ +objective-condition-hijack-shuttle-title = Hijack emergency shuttle +objective-condition-hijack-shuttle-description = Leave on the shuttle free and clear of the loyal Nanotrasen crew on board. Use ANY methods available to you. Syndicate agents, Nanotrasen enemies, and handcuffed hostages may remain alive on the shuttle. Ignore assistance from anyone other than a support agent. diff --git a/Resources/Prototypes/Objectives/objectiveGroups.yml b/Resources/Prototypes/Objectives/objectiveGroups.yml index 2ddf78e032..7d6c9a48a3 100644 --- a/Resources/Prototypes/Objectives/objectiveGroups.yml +++ b/Resources/Prototypes/Objectives/objectiveGroups.yml @@ -33,6 +33,7 @@ weights: EscapeShuttleObjective: 1 DieObjective: 0.05 + HijackShuttleObjective: 0.02 - type: weightedRandom id: TraitorObjectiveGroupSocial From c09633fae313e17ae6a1e0bafd2b607df45a61bb Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 24 Oct 2023 03:56:50 -0400 Subject: [PATCH 019/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 2d00c7a9ee..259437e311 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Doru991 - changes: - - {message: 'Wheelchairs, unicycles and similar vehicles no longer act as a magical - barrier against stuns.', type: Fix} - - {message: Driving while asleep is no longer possible., type: Fix} - id: 4547 - time: '2023-08-13T07:13:19.0000000+00:00' - author: Potato1234_x changes: - {message: Vending machine sprites have been polished up., type: Tweak} @@ -2909,3 +2902,9 @@ Entries: - {message: Ore bags now pickup artifact fragments as well as ores, type: Fix} id: 5046 time: '2023-10-24T06:20:46.0000000+00:00' +- author: Morb0 + changes: + - {message: Syndicate have issued a new challenge objective for traitors with shuttle + hijacking, type: Add} + id: 5047 + time: '2023-10-24T07:55:47.0000000+00:00' From 41a9b8868077f2b7cb811b082273032c397088be Mon Sep 17 00:00:00 2001 From: Vasilis Date: Tue, 24 Oct 2023 10:35:39 +0200 Subject: [PATCH 020/102] Make it a lil easier to restrict what can go in a cannon (#21093) --- .../Entities/Objects/Weapons/Guns/Projectiles/arrows.yml | 1 + .../Entities/Objects/Weapons/Guns/pneumatic_cannon.yml | 2 +- Resources/Prototypes/tags.yml | 9 ++++++--- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml index 7dd6360a40..32a2ea4623 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml @@ -35,6 +35,7 @@ - type: Tag tags: - Arrow + - CannonRestrict - type: Projectile deleteOnCollide: false onlyCollideWhenShot: true diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/pneumatic_cannon.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/pneumatic_cannon.yml index f9413d6c67..9f3aec5c39 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/pneumatic_cannon.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/pneumatic_cannon.yml @@ -35,7 +35,7 @@ capacity: 30 blacklist: tags: - - Arrow + - CannonRestrict - type: Appearance - type: ItemMapper containerWhitelist: [gas_tank] diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index d7397d483c..a74fde7710 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -3,7 +3,7 @@ - type: Tag id: AirAlarmElectronics - + - type: Tag id: Airlock @@ -234,6 +234,9 @@ - type: Tag id: CanPilot + +- type: Tag + id: CannonRestrict - type: Tag id: CannotSuicide @@ -493,7 +496,7 @@ - type: Tag id: GeigerCounter - + - type: Tag id: GlassAirlock @@ -562,7 +565,7 @@ - type: Tag id: HighRiskItem - + - type: Tag id: HighSecDoor From c500a63ada2fc6ed8cd2e74b4692e687829da1b7 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Tue, 24 Oct 2023 19:40:30 +1100 Subject: [PATCH 021/102] Add placementreplacement to wallrocks (#21220) --- Resources/Prototypes/Entities/Structures/Walls/asteroid.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml index b36ba51ee0..9b513b2da1 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml @@ -149,6 +149,8 @@ parent: BaseStructure name: rock components: + - type: PlacementReplacement + key: walls - type: SoundOnGather - type: Gatherable whitelist: From 7ba0ea29263acab3bd641237945dd0e1319b2bc0 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Tue, 24 Oct 2023 20:19:08 +1100 Subject: [PATCH 022/102] IPlayerManager refactor (#21215) --- Content.Client/Actions/ActionsSystem.cs | 9 +- .../Managers/ClientAdminManager.cs | 2 +- .../UI/Tabs/AdminTab/TeleportWindow.xaml.cs | 1 - Content.Client/Alerts/ClientAlertsSystem.cs | 9 +- .../CharacterInfo/CharacterInfoSystem.cs | 12 -- .../Construction/ConstructionSystem.cs | 6 +- Content.Client/Drugs/DrugOverlaySystem.cs | 9 +- Content.Client/Drunk/DrunkSystem.cs | 9 +- Content.Client/Eye/Blinding/BlindingSystem.cs | 18 +- .../Eye/Blinding/BlurryVisionSystem.cs | 11 +- Content.Client/Eye/EyeLerpingSystem.cs | 4 +- Content.Client/Fullscreen/FullscreenHook.cs | 2 +- Content.Client/Gameplay/GameplayStateBase.cs | 2 +- Content.Client/Ghost/GhostSystem.cs | 12 +- Content.Client/Hands/Systems/HandsSystem.cs | 8 +- .../HealthOverlay/HealthOverlaySystem.cs | 13 +- .../Inventory/ClientInventorySystem.cs | 9 +- Content.Client/Mind/MindSystem.cs | 20 +++ Content.Client/Overlays/EquipmentHudSystem.cs | 9 +- .../Physics/Controllers/MoverController.cs | 17 +- Content.Client/Players/PlayerSystem.cs | 4 +- Content.Client/Popups/PopupSystem.cs | 1 - .../ReplaySpectatorSystem.Movement.cs | 2 +- .../ReplaySpectatorSystem.Position.cs | 12 +- .../ReplaySpectatorSystem.Spectate.cs | 14 +- .../Replay/Spectator/ReplaySpectatorSystem.cs | 3 +- Content.Client/Sandbox/SandboxSystem.cs | 2 +- Content.Client/Traits/ParacusiaSystem.cs | 6 +- .../Character/CharacterUIController.cs | 8 +- .../Systems/Chat/ChatUIController.cs | 29 +--- .../DamageOverlayUiController.cs | 10 +- .../Systems/Sandbox/SandboxUIController.cs | 2 +- .../Weapons/Melee/MeleeWeaponSystem.cs | 3 +- Content.IntegrationTests/Pair/TestPair.cs | 8 +- .../Tests/Actions/ActionsAddedTest.cs | 4 +- .../Tests/Administration/Logs/AddTests.cs | 8 +- .../Tests/Administration/Logs/QueryTests.cs | 5 +- .../Tests/Cleanup/EuiManagerTest.cs | 2 +- .../Tests/Interaction/InteractionTest.cs | 5 +- .../Tests/Minds/GhostRoleTests.cs | 3 +- .../Tests/Minds/MindTests.EntityDeletion.cs | 13 +- .../Tests/Minds/MindTests.Helpers.cs | 20 ++- .../Tests/Minds/MindTests.ReconnectTests.cs | 9 +- .../Tests/Minds/MindTests.cs | 30 ++-- .../Tests/Toolshed/ToolshedTest.cs | 7 +- Content.MapRenderer/Painters/MapPainter.cs | 2 +- .../AdminPermsChangedEventArgs.cs | 6 +- .../Administration/Commands/AGhost.cs | 3 +- .../Commands/AdminWhoCommand.cs | 3 +- .../Commands/AnnounceUiCommand.cs | 3 +- .../Administration/Commands/BanCommand.cs | 11 +- .../Administration/Commands/BanListCommand.cs | 4 +- .../Commands/BanPanelCommand.cs | 8 +- .../Administration/Commands/ControlMob.cs | 14 +- .../Administration/Commands/DSay.cs | 4 +- .../Administration/Commands/DeAdminCommand.cs | 4 +- .../Commands/ExplosionCommand.cs | 3 +- .../Administration/Commands/FaxUiCommand.cs | 3 +- .../Commands/OpenAdminLogsCommand.cs | 3 +- .../Commands/OpenAdminNotesCommand.cs | 4 +- .../Commands/OpenPermissionsCommand.cs | 4 +- .../Commands/OpenUserVisibleNotesCommand.cs | 3 +- .../Administration/Commands/PardonCommand.cs | 3 +- .../Commands/PlayGlobalSoundCommand.cs | 1 - .../Administration/Commands/ReAdminCommand.cs | 4 +- .../Administration/Commands/SetAdminOOC.cs | 4 +- .../Administration/Commands/SetMindCommand.cs | 1 + .../Commands/SetOutfitCommand.cs | 3 +- .../Administration/Commands/WarpCommand.cs | 4 +- .../ContentNetworkResourceManager.cs | 4 +- .../Logs/AdminLogManager.Json.cs | 6 +- .../Logs/Converters/PlayerSessionConverter.cs | 6 +- .../Administration/Managers/AdminManager.cs | 52 +++--- .../Administration/Managers/BanManager.cs | 3 +- .../Administration/Managers/IAdminManager.cs | 15 +- .../Administration/Managers/IBanManager.cs | 4 +- .../Administration/Notes/AdminNotesManager.cs | 2 +- .../Administration/Notes/AdminNotesSystem.cs | 2 +- .../Notes/IAdminNotesManager.cs | 2 +- .../QuickDialogSystem.OpenDialog.cs | 10 +- .../Administration/QuickDialogSystem.cs | 7 +- .../Administration/Systems/AdminSystem.cs | 8 +- .../Systems/AdminTestArenaSystem.cs | 4 +- .../Administration/Systems/AdminVerbSystem.cs | 18 +- .../Administration/Systems/BwoinkSystem.cs | 5 +- .../Administration/Toolshed/AdminsCommand.cs | 6 +- Content.Server/Afk/AFKSystem.cs | 9 +- Content.Server/Afk/AfkManager.cs | 15 +- Content.Server/Afk/Events/AFKEvent.cs | 6 +- Content.Server/Afk/Events/UnAFKEvent.cs | 6 +- Content.Server/Alert/Commands/ClearAlert.cs | 3 +- Content.Server/Alert/Commands/ShowAlert.cs | 3 +- .../Commands/SetAlertLevelCommand.cs | 5 +- Content.Server/Antag/AntagSelectionSystem.cs | 9 +- .../Arcade/BlockGame/BlockGame.Ui.cs | 20 +-- .../BlockGame/BlockGameArcadeComponent.cs | 6 +- .../Arcade/BlockGame/BlockGameArcadeSystem.cs | 6 +- .../Atmos/Commands/DeleteGasCommand.cs | 3 +- .../Atmos/Commands/ShowAtmosCommand.cs | 3 +- .../EntitySystems/AtmosDebugOverlaySystem.cs | 11 +- .../Atmos/EntitySystems/GasTankSystem.cs | 7 - .../EntitySystems/GasTileOverlaySystem.cs | 7 +- .../Body/Commands/AddHandCommand.cs | 3 +- .../Body/Commands/AttachBodyPartCommand.cs | 4 +- .../Body/Commands/DestroyMechanismCommand.cs | 3 +- .../Body/Commands/RemoveHandCommand.cs | 3 +- Content.Server/Body/Systems/BodySystem.cs | 2 +- .../Cargo/Systems/CargoSystem.Orders.cs | 2 +- .../CartridgeLoader/CartridgeLoaderSystem.cs | 6 +- .../Chat/Commands/AdminChatCommand.cs | 3 +- Content.Server/Chat/Commands/LOOCCommand.cs | 3 +- Content.Server/Chat/Commands/MeCommand.cs | 3 +- Content.Server/Chat/Commands/OOCCommand.cs | 3 +- Content.Server/Chat/Commands/SayCommand.cs | 3 +- .../Chat/Commands/SuicideCommand.cs | 3 +- .../Chat/Commands/WhisperCommand.cs | 3 +- Content.Server/Chat/Managers/ChatManager.cs | 16 +- Content.Server/Chat/Managers/IChatManager.cs | 12 +- Content.Server/Chat/Systems/ChatSystem.cs | 21 ++- .../EntitySystems/ChemistryGuideDataSystem.cs | 1 + Content.Server/Chunking/ChunkingSystem.cs | 6 +- Content.Server/Commands/CommandUtils.cs | 7 +- .../Commands/FixRotationsCommand.cs | 3 +- .../Commands/TileReplaceCommand.cs | 3 +- .../Construction/Commands/TileWallsCommand.cs | 5 +- .../ConstructionSystem.Initial.cs | 2 +- .../CrewManifest/CrewManifestSystem.cs | 17 +- .../Damage/Commands/GodModeCommand.cs | 4 +- .../Damage/ForceSay/DamageForceSaySystem.cs | 1 - Content.Server/Database/UserDbDataManager.cs | 14 +- Content.Server/Decals/DecalSystem.cs | 13 +- .../Disposal/TubeConnectionsCommand.cs | 3 +- Content.Server/EUI/BaseEui.cs | 2 +- Content.Server/EUI/EuiManager.cs | 2 +- .../EntityList/SpawnEntityListCommand.cs | 3 +- Content.Server/Examine/ExamineSystem.cs | 3 +- .../PuddleDebugDebugOverlaySystem.cs | 8 +- Content.Server/Fluids/ShowFluidsCommand.cs | 3 +- .../GameTicking/Commands/JoinGameCommand.cs | 3 +- .../GameTicking/Commands/ObserveCommand.cs | 3 +- .../GameTicking/Commands/RespawnCommand.cs | 2 +- .../Commands/ToggleReadyCommand.cs | 3 +- .../GameTicking/GameTicker.GamePreset.cs | 6 +- .../GameTicking/GameTicker.Lobby.cs | 8 +- .../GameTicking/GameTicker.Player.cs | 19 +- .../GameTicking/GameTicker.RoundFlow.cs | 24 ++- .../GameTicking/GameTicker.Spawning.cs | 28 +-- .../Rules/Components/TraitorRuleComponent.cs | 4 +- .../Rules/InactivityTimeRestartRuleSystem.cs | 1 + .../GameTicking/Rules/NukeopsRuleSystem.cs | 18 +- .../GameTicking/Rules/PiratesRuleSystem.cs | 4 +- .../GameTicking/Rules/RespawnRuleSystem.cs | 1 + .../GameTicking/Rules/TraitorRuleSystem.cs | 13 +- .../GameTicking/Rules/ZombieRuleSystem.cs | 10 +- Content.Server/Ghost/Ghost.cs | 3 +- .../Roles/Components/TakeGhostRoleEvent.cs | 2 +- Content.Server/Ghost/Roles/GhostRoleSystem.cs | 10 +- .../Gravity/GravityGeneratorSystem.cs | 4 +- Content.Server/Hands/Systems/HandsSystem.cs | 9 +- .../HumanoidAppearanceSystem.Modifier.cs | 5 +- .../Instruments/InstrumentComponent.cs | 4 +- .../Instruments/InstrumentSystem.cs | 6 +- .../Interaction/InteractionSystem.cs | 1 - Content.Server/Interaction/TilePryCommand.cs | 5 +- .../MagicMirror/MagicMirrorSystem.cs | 5 +- Content.Server/Mapping/MappingCommand.cs | 2 +- Content.Server/Maps/GridDraggingSystem.cs | 9 +- Content.Server/Medical/DefibrillatorSystem.cs | 2 +- Content.Server/Mind/Commands/RenameCommand.cs | 1 + Content.Server/Mind/MindSystem.cs | 164 +++++++++++------- Content.Server/Mind/Toolshed/MindCommand.cs | 6 +- Content.Server/Motd/MOTDCommand.cs | 7 +- Content.Server/Motd/MOTDSystem.cs | 14 +- Content.Server/Motd/SetMOTDCommand.cs | 7 +- .../Movement/Systems/LagCompensationSystem.cs | 2 +- Content.Server/NPC/Commands/NPCCommand.cs | 3 +- Content.Server/NPC/HTN/HTNSystem.cs | 7 +- .../NPC/Pathfinding/PathfindingSystem.cs | 4 +- .../NPC/Systems/NPCSteeringSystem.cs | 4 +- .../EntitySystems/NodeGroupSystem.cs | 7 +- Content.Server/Nutrition/Hungry.cs | 4 +- .../Commands/ListObjectivesCommand.cs | 2 +- Content.Server/PDA/PdaSystem.cs | 8 +- Content.Server/PDA/Ringer/RingerSystem.cs | 3 +- Content.Server/Paper/PaperSystem.cs | 6 +- Content.Server/Parallax/BiomeSystem.cs | 3 +- .../ParticleAcceleratorSystem.ControlBox.cs | 17 +- .../ParticleAcceleratorSystem.Parts.cs | 4 +- .../PlayTimeTrackingManager.cs | 40 ++--- .../PlayTimeTrackingSystem.cs | 13 +- Content.Server/Players/PlayerData.cs | 30 ---- Content.Server/Players/PlayerSystem.cs | 4 +- .../Pointing/EntitySystems/PointingSystem.cs | 5 +- Content.Server/Popups/PopupSystem.cs | 1 - Content.Server/Prayer/PrayerSystem.cs | 7 +- .../Managers/IServerPreferencesManager.cs | 8 +- .../Managers/ServerPreferencesManager.cs | 8 +- Content.Server/Pulling/PullingSystem.cs | 2 +- .../Systems/RadiationSystem.Debug.cs | 2 +- .../Research/Systems/ResearchSystem.Client.cs | 3 +- Content.Server/Salvage/SalvageRulerCommand.cs | 3 +- .../Sandbox/Commands/ColorNetworkCommand.cs | 3 +- Content.Server/Sandbox/SandboxSystem.cs | 1 + .../SensorMonitoringConsoleComponent.cs | 2 +- .../SensorMonitoringConsoleSystem.UI.cs | 4 +- .../ServerUpdates/ServerUpdateManager.cs | 1 + .../Systems/EmergencyShuttleSystem.cs | 3 +- .../Silicons/Borgs/BorgSystem.Modules.cs | 2 +- Content.Server/Silicons/Borgs/BorgSystem.cs | 2 +- .../Silicons/Laws/SiliconLawSystem.cs | 5 +- .../Station/Systems/StationJobsSystem.cs | 2 +- .../Storage/EntitySystems/StorageSystem.cs | 3 +- Content.Server/Tabletop/TabletopSession.cs | 4 +- .../Tabletop/TabletopSystem.Session.cs | 8 +- Content.Server/Tabletop/TabletopSystem.cs | 7 +- .../Commands/AdminDebug/ACmdCommand.cs | 4 +- .../Toolshed/Commands/VisualizeCommand.cs | 3 +- .../Uplink/Commands/AddUplinkCommand.cs | 5 +- .../UserInterface/ActivatableUIComponent.cs | 4 +- .../UserInterface/ActivatableUISystem.cs | 8 +- .../UserInterface/StatValuesCommand.cs | 3 +- Content.Server/Verbs/VerbSystem.cs | 5 +- Content.Server/Voting/IVoteHandle.cs | 4 +- .../Voting/Managers/IVoteManager.cs | 6 +- .../Managers/VoteManager.DefaultVotes.cs | 12 +- Content.Server/Voting/Managers/VoteManager.cs | 31 ++-- Content.Server/Voting/VoteCommands.cs | 9 +- Content.Server/Voting/VoteOptions.cs | 8 +- .../Weapons/Melee/MeleeWeaponSystem.cs | 4 +- Content.Server/Wires/WiresSystem.cs | 4 +- .../Systems/ArtifactAnalyzerSystem.cs | 3 +- .../Managers/ISharedAdminManager.cs | 2 +- Content.Shared/Buckle/SharedBuckleSystem.cs | 2 +- .../SharedHandsSystem.Interactions.cs | 2 +- .../Interaction/SharedInteractionSystem.cs | 2 +- .../Mind/Components/MindContainerComponent.cs | 65 +++++-- Content.Shared/Mind/MindComponent.cs | 49 +++--- Content.Shared/Mind/SharedMindSystem.cs | 91 +++++++--- .../Movement/Events/MoveInputEvent.cs | 2 - .../Systems/SharedContentEyeSystem.cs | 2 +- .../Systems/SharedMoverController.Input.cs | 2 +- .../{PlayerData.cs => ContentPlayerData.cs} | 21 +-- Content.Shared/Players/PlayerDataExt.cs | 30 ++++ Content.Shared/Players/SharedPlayerSystem.cs | 4 +- Content.Shared/Popups/SharedPopupSystem.cs | 1 - .../Pulling/Systems/SharedPullingSystem.cs | 2 +- Content.Shared/Roles/Jobs/SharedJobSystem.cs | 2 +- .../Weapons/Melee/SharedMeleeWeaponSystem.cs | 2 +- 248 files changed, 966 insertions(+), 1048 deletions(-) delete mode 100644 Content.Server/Players/PlayerData.cs rename Content.Shared/Players/{PlayerData.cs => ContentPlayerData.cs} (73%) create mode 100644 Content.Shared/Players/PlayerDataExt.cs diff --git a/Content.Client/Actions/ActionsSystem.cs b/Content.Client/Actions/ActionsSystem.cs index 83d927c94b..a487e5d8d8 100644 --- a/Content.Client/Actions/ActionsSystem.cs +++ b/Content.Client/Actions/ActionsSystem.cs @@ -2,7 +2,6 @@ using System.IO; using System.Linq; using Content.Shared.Actions; using JetBrains.Annotations; -using Robust.Client.GameObjects; using Robust.Client.Player; using Robust.Shared.ContentPack; using Robust.Shared.GameStates; @@ -41,8 +40,8 @@ namespace Content.Client.Actions public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(HandleComponentState); SubscribeLocalEvent(OnInstantHandleState); @@ -196,12 +195,12 @@ namespace Content.Client.Actions return GetActions(user); } - private void OnPlayerAttached(EntityUid uid, ActionsComponent component, PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, ActionsComponent component, LocalPlayerAttachedEvent args) { LinkAllActions(component); } - private void OnPlayerDetached(EntityUid uid, ActionsComponent component, PlayerDetachedEvent? args = null) + private void OnPlayerDetached(EntityUid uid, ActionsComponent component, LocalPlayerDetachedEvent? args = null) { UnlinkAllActions(); } diff --git a/Content.Client/Administration/Managers/ClientAdminManager.cs b/Content.Client/Administration/Managers/ClientAdminManager.cs index 8978e2fd6d..1a1366c6f2 100644 --- a/Content.Client/Administration/Managers/ClientAdminManager.cs +++ b/Content.Client/Administration/Managers/ClientAdminManager.cs @@ -4,7 +4,7 @@ using Robust.Client.Console; using Robust.Client.Player; using Robust.Shared.ContentPack; using Robust.Shared.Network; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Client.Administration.Managers diff --git a/Content.Client/Administration/UI/Tabs/AdminTab/TeleportWindow.xaml.cs b/Content.Client/Administration/UI/Tabs/AdminTab/TeleportWindow.xaml.cs index c5a9bd036a..1978b5c3c0 100644 --- a/Content.Client/Administration/UI/Tabs/AdminTab/TeleportWindow.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/AdminTab/TeleportWindow.xaml.cs @@ -5,7 +5,6 @@ using Robust.Client.Console; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; using Robust.Shared.IoC; -using Robust.Shared.Players; namespace Content.Client.Administration.UI.Tabs.AdminTab { diff --git a/Content.Client/Alerts/ClientAlertsSystem.cs b/Content.Client/Alerts/ClientAlertsSystem.cs index bb6d2d4df4..5089022415 100644 --- a/Content.Client/Alerts/ClientAlertsSystem.cs +++ b/Content.Client/Alerts/ClientAlertsSystem.cs @@ -1,7 +1,6 @@ using System.Linq; using Content.Shared.Alert; using JetBrains.Annotations; -using Robust.Client.GameObjects; using Robust.Client.Player; using Robust.Shared.Prototypes; @@ -22,8 +21,8 @@ public sealed class ClientAlertsSystem : AlertsSystem { base.Initialize(); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(ClientAlertsHandleState); } @@ -69,7 +68,7 @@ public sealed class ClientAlertsSystem : AlertsSystem SyncAlerts?.Invoke(this, component.Alerts); } - private void OnPlayerAttached(EntityUid uid, AlertsComponent component, PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, AlertsComponent component, LocalPlayerAttachedEvent args) { if (_playerManager.LocalPlayer?.ControlledEntity != uid) return; @@ -87,7 +86,7 @@ public sealed class ClientAlertsSystem : AlertsSystem ClearAlerts?.Invoke(this, EventArgs.Empty); } - private void OnPlayerDetached(EntityUid uid, AlertsComponent component, PlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, AlertsComponent component, LocalPlayerDetachedEvent args) { ClearAlerts?.Invoke(this, EventArgs.Empty); } diff --git a/Content.Client/CharacterInfo/CharacterInfoSystem.cs b/Content.Client/CharacterInfo/CharacterInfoSystem.cs index 93bd86d140..844a352a18 100644 --- a/Content.Client/CharacterInfo/CharacterInfoSystem.cs +++ b/Content.Client/CharacterInfo/CharacterInfoSystem.cs @@ -1,6 +1,5 @@ using Content.Shared.CharacterInfo; using Content.Shared.Objectives; -using Robust.Client.GameObjects; using Robust.Client.Player; using Robust.Client.UserInterface; @@ -11,14 +10,11 @@ public sealed class CharacterInfoSystem : EntitySystem [Dependency] private readonly IPlayerManager _players = default!; public event Action? OnCharacterUpdate; - public event Action? OnCharacterDetached; public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeNetworkEvent(OnCharacterInfoEvent); } @@ -33,14 +29,6 @@ public sealed class CharacterInfoSystem : EntitySystem RaiseNetworkEvent(new RequestCharacterInfoEvent(GetNetEntity(entity.Value))); } - private void OnPlayerAttached(PlayerAttachSysMessage msg) - { - if (msg.AttachedEntity == default) - { - OnCharacterDetached?.Invoke(); - } - } - private void OnCharacterInfoEvent(CharacterInfoEvent msg, EntitySessionEventArgs args) { var entity = GetEntity(msg.NetEntity); diff --git a/Content.Client/Construction/ConstructionSystem.cs b/Content.Client/Construction/ConstructionSystem.cs index 98d2dfd414..9fc638cea2 100644 --- a/Content.Client/Construction/ConstructionSystem.cs +++ b/Content.Client/Construction/ConstructionSystem.cs @@ -38,7 +38,7 @@ namespace Content.Client.Construction base.Initialize(); UpdatesOutsidePrediction = true; - SubscribeLocalEvent(HandlePlayerAttached); + SubscribeLocalEvent(HandlePlayerAttached); SubscribeNetworkEvent(HandleAckStructure); SubscribeNetworkEvent(OnConstructionGuideReceived); @@ -110,9 +110,9 @@ namespace Content.Client.Construction ClearGhost(msg.GhostId); } - private void HandlePlayerAttached(PlayerAttachSysMessage msg) + private void HandlePlayerAttached(LocalPlayerAttachedEvent msg) { - var available = IsCraftingAvailable(msg.AttachedEntity); + var available = IsCraftingAvailable(msg.Entity); UpdateCraftingAvailability(available); } diff --git a/Content.Client/Drugs/DrugOverlaySystem.cs b/Content.Client/Drugs/DrugOverlaySystem.cs index 7be63b4c50..ec0d014072 100644 --- a/Content.Client/Drugs/DrugOverlaySystem.cs +++ b/Content.Client/Drugs/DrugOverlaySystem.cs @@ -1,5 +1,4 @@ using Content.Shared.Drugs; -using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.Player; @@ -24,18 +23,18 @@ public sealed class DrugOverlaySystem : EntitySystem SubscribeLocalEvent(OnInit); SubscribeLocalEvent(OnShutdown); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); _overlay = new(); } - private void OnPlayerAttached(EntityUid uid, SeeingRainbowsComponent component, PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, SeeingRainbowsComponent component, LocalPlayerAttachedEvent args) { _overlayMan.AddOverlay(_overlay); } - private void OnPlayerDetached(EntityUid uid, SeeingRainbowsComponent component, PlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, SeeingRainbowsComponent component, LocalPlayerDetachedEvent args) { _overlay.Intoxication = 0; _overlayMan.RemoveOverlay(_overlay); diff --git a/Content.Client/Drunk/DrunkSystem.cs b/Content.Client/Drunk/DrunkSystem.cs index 0573b2ff3e..4f2ec70b56 100644 --- a/Content.Client/Drunk/DrunkSystem.cs +++ b/Content.Client/Drunk/DrunkSystem.cs @@ -1,5 +1,4 @@ using Content.Shared.Drunk; -using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.Player; @@ -19,18 +18,18 @@ public sealed class DrunkSystem : SharedDrunkSystem SubscribeLocalEvent(OnDrunkInit); SubscribeLocalEvent(OnDrunkShutdown); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); _overlay = new(); } - private void OnPlayerAttached(EntityUid uid, DrunkComponent component, PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, DrunkComponent component, LocalPlayerAttachedEvent args) { _overlayMan.AddOverlay(_overlay); } - private void OnPlayerDetached(EntityUid uid, DrunkComponent component, PlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, DrunkComponent component, LocalPlayerDetachedEvent args) { _overlay.CurrentBoozePower = 0; _overlayMan.RemoveOverlay(_overlay); diff --git a/Content.Client/Eye/Blinding/BlindingSystem.cs b/Content.Client/Eye/Blinding/BlindingSystem.cs index f0b760d838..f255f7ef01 100644 --- a/Content.Client/Eye/Blinding/BlindingSystem.cs +++ b/Content.Client/Eye/Blinding/BlindingSystem.cs @@ -1,17 +1,7 @@ - -using Content.Shared.Eye.Blinding; -using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.Player; -using System; -using System.Collections.Generic; -using System.Linq; -using Content.Shared.Administration; -using Content.Shared.Administration.Events; using Content.Shared.Eye.Blinding.Components; using Content.Shared.GameTicking; -using Robust.Shared.GameObjects; -using Robust.Shared.Network; namespace Content.Client.Eye.Blinding; @@ -31,20 +21,20 @@ public sealed class BlindingSystem : EntitySystem SubscribeLocalEvent(OnBlindInit); SubscribeLocalEvent(OnBlindShutdown); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeNetworkEvent(RoundRestartCleanup); _overlay = new(); } - private void OnPlayerAttached(EntityUid uid, BlindableComponent component, PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, BlindableComponent component, LocalPlayerAttachedEvent args) { _overlayMan.AddOverlay(_overlay); } - private void OnPlayerDetached(EntityUid uid, BlindableComponent component, PlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, BlindableComponent component, LocalPlayerDetachedEvent args) { _overlayMan.RemoveOverlay(_overlay); _lightManager.Enabled = true; diff --git a/Content.Client/Eye/Blinding/BlurryVisionSystem.cs b/Content.Client/Eye/Blinding/BlurryVisionSystem.cs index 1bac2a97bf..8be5b4ed93 100644 --- a/Content.Client/Eye/Blinding/BlurryVisionSystem.cs +++ b/Content.Client/Eye/Blinding/BlurryVisionSystem.cs @@ -1,9 +1,6 @@ -using Content.Shared.Eye.Blinding; using Content.Shared.Eye.Blinding.Components; -using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.Player; -using Robust.Shared.GameStates; namespace Content.Client.Eye.Blinding; @@ -20,18 +17,18 @@ public sealed class BlurryVisionSystem : EntitySystem SubscribeLocalEvent(OnBlurryInit); SubscribeLocalEvent(OnBlurryShutdown); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); _overlay = new(); } - private void OnPlayerAttached(EntityUid uid, BlurryVisionComponent component, PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, BlurryVisionComponent component, LocalPlayerAttachedEvent args) { _overlayMan.AddOverlay(_overlay); } - private void OnPlayerDetached(EntityUid uid, BlurryVisionComponent component, PlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, BlurryVisionComponent component, LocalPlayerDetachedEvent args) { _overlayMan.RemoveOverlay(_overlay); } diff --git a/Content.Client/Eye/EyeLerpingSystem.cs b/Content.Client/Eye/EyeLerpingSystem.cs index 8e54196b81..b46921a9b4 100644 --- a/Content.Client/Eye/EyeLerpingSystem.cs +++ b/Content.Client/Eye/EyeLerpingSystem.cs @@ -30,7 +30,7 @@ public sealed class EyeLerpingSystem : EntitySystem SubscribeLocalEvent(OnAttached); SubscribeLocalEvent(HandleMapChange); - SubscribeLocalEvent(OnDetached); + SubscribeLocalEvent(OnDetached); UpdatesAfter.Add(typeof(TransformSystem)); UpdatesAfter.Add(typeof(PhysicsSystem)); @@ -94,7 +94,7 @@ public sealed class EyeLerpingSystem : EntitySystem AddEye(ev.Entity, ev.Component, true); } - private void OnDetached(EntityUid uid, LerpingEyeComponent component, PlayerDetachedEvent args) + private void OnDetached(EntityUid uid, LerpingEyeComponent component, LocalPlayerDetachedEvent args) { if (!component.ManuallyAdded) RemCompDeferred(uid, component); diff --git a/Content.Client/Fullscreen/FullscreenHook.cs b/Content.Client/Fullscreen/FullscreenHook.cs index 78a0151736..7917fddfbb 100644 --- a/Content.Client/Fullscreen/FullscreenHook.cs +++ b/Content.Client/Fullscreen/FullscreenHook.cs @@ -4,7 +4,7 @@ using Robust.Client.Input; using Robust.Shared.Input.Binding; using Robust.Shared; using Robust.Shared.Configuration; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Client.Fullscreen; public sealed class FullscreenHook diff --git a/Content.Client/Gameplay/GameplayStateBase.cs b/Content.Client/Gameplay/GameplayStateBase.cs index 788a4e5dff..454c063260 100644 --- a/Content.Client/Gameplay/GameplayStateBase.cs +++ b/Content.Client/Gameplay/GameplayStateBase.cs @@ -16,7 +16,7 @@ using Robust.Shared.Console; using Robust.Shared.Input; using Robust.Shared.Input.Binding; using Robust.Shared.Map; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Client.Gameplay diff --git a/Content.Client/Ghost/GhostSystem.cs b/Content.Client/Ghost/GhostSystem.cs index 5727534109..a89d0858d9 100644 --- a/Content.Client/Ghost/GhostSystem.cs +++ b/Content.Client/Ghost/GhostSystem.cs @@ -58,10 +58,10 @@ namespace Content.Client.Ghost SubscribeLocalEvent(OnGhostRemove); SubscribeLocalEvent(OnGhostState); - SubscribeLocalEvent(OnGhostPlayerAttach); - SubscribeLocalEvent(OnGhostPlayerDetach); + SubscribeLocalEvent(OnGhostPlayerAttach); + SubscribeLocalEvent(OnGhostPlayerDetach); - SubscribeLocalEvent(OnPlayerAttach); + SubscribeLocalEvent(OnPlayerAttach); SubscribeNetworkEvent(OnGhostWarpsResponse); SubscribeNetworkEvent(OnUpdateGhostRoleCount); @@ -130,7 +130,7 @@ namespace Content.Client.Ghost PlayerRemoved?.Invoke(component); } - private void OnGhostPlayerAttach(EntityUid uid, GhostComponent component, PlayerAttachedEvent playerAttachedEvent) + private void OnGhostPlayerAttach(EntityUid uid, GhostComponent component, LocalPlayerAttachedEvent localPlayerAttachedEvent) { if (uid != _playerManager.LocalPlayer?.ControlledEntity) return; @@ -161,13 +161,13 @@ namespace Content.Client.Ghost return true; } - private void OnGhostPlayerDetach(EntityUid uid, GhostComponent component, PlayerDetachedEvent args) + private void OnGhostPlayerDetach(EntityUid uid, GhostComponent component, LocalPlayerDetachedEvent args) { if (PlayerDetach(uid)) component.IsAttached = false; } - private void OnPlayerAttach(PlayerAttachedEvent ev) + private void OnPlayerAttach(LocalPlayerAttachedEvent ev) { if (!HasComp(ev.Entity)) PlayerDetach(ev.Entity); diff --git a/Content.Client/Hands/Systems/HandsSystem.cs b/Content.Client/Hands/Systems/HandsSystem.cs index ed40589f7f..31de7ec143 100644 --- a/Content.Client/Hands/Systems/HandsSystem.cs +++ b/Content.Client/Hands/Systems/HandsSystem.cs @@ -42,8 +42,8 @@ namespace Content.Client.Hands.Systems { base.Initialize(); - SubscribeLocalEvent(HandlePlayerAttached); - SubscribeLocalEvent(HandlePlayerDetached); + SubscribeLocalEvent(HandlePlayerAttached); + SubscribeLocalEvent(HandlePlayerDetached); SubscribeLocalEvent(OnHandsStartup); SubscribeLocalEvent(OnHandsShutdown); SubscribeLocalEvent(HandleComponentState); @@ -361,12 +361,12 @@ namespace Content.Client.Hands.Systems #region Gui - private void HandlePlayerAttached(EntityUid uid, HandsComponent component, PlayerAttachedEvent args) + private void HandlePlayerAttached(EntityUid uid, HandsComponent component, LocalPlayerAttachedEvent args) { OnPlayerHandsAdded?.Invoke(component); } - private void HandlePlayerDetached(EntityUid uid, HandsComponent component, PlayerDetachedEvent args) + private void HandlePlayerDetached(EntityUid uid, HandsComponent component, LocalPlayerDetachedEvent args) { OnPlayerHandsRemoved?.Invoke(); } diff --git a/Content.Client/HealthOverlay/HealthOverlaySystem.cs b/Content.Client/HealthOverlay/HealthOverlaySystem.cs index baeb4fe025..29ac937199 100644 --- a/Content.Client/HealthOverlay/HealthOverlaySystem.cs +++ b/Content.Client/HealthOverlay/HealthOverlaySystem.cs @@ -3,8 +3,8 @@ using Content.Shared.Damage; using Content.Shared.GameTicking; using Content.Shared.Mobs.Components; using JetBrains.Annotations; -using Robust.Client.GameObjects; using Robust.Client.Graphics; +using Robust.Client.Player; namespace Content.Client.HealthOverlay { @@ -13,9 +13,9 @@ namespace Content.Client.HealthOverlay { [Dependency] private readonly IEyeManager _eyeManager = default!; [Dependency] private readonly IEntityManager _entities = default!; + [Dependency] private readonly IPlayerManager _player = default!; private readonly Dictionary _guis = new(); - private EntityUid? _attachedEntity; private bool _enabled; public bool Enabled @@ -42,7 +42,6 @@ namespace Content.Client.HealthOverlay base.Initialize(); SubscribeNetworkEvent(Reset); - SubscribeLocalEvent(HandlePlayerAttached); } public void Reset(RoundRestartCleanupEvent ev) @@ -53,12 +52,6 @@ namespace Content.Client.HealthOverlay } _guis.Clear(); - _attachedEntity = default; - } - - private void HandlePlayerAttached(PlayerAttachSysMessage message) - { - _attachedEntity = message.AttachedEntity; } public override void FrameUpdate(float frameTime) @@ -70,7 +63,7 @@ namespace Content.Client.HealthOverlay return; } - if (_attachedEntity is not {} ent || Deleted(ent)) + if (_player.LocalEntity is not {} ent || Deleted(ent)) { return; } diff --git a/Content.Client/Inventory/ClientInventorySystem.cs b/Content.Client/Inventory/ClientInventorySystem.cs index ffff392aa4..f0a12b3b1f 100644 --- a/Content.Client/Inventory/ClientInventorySystem.cs +++ b/Content.Client/Inventory/ClientInventorySystem.cs @@ -10,7 +10,6 @@ using Content.Shared.Inventory; using Content.Shared.Inventory.Events; using Content.Shared.Storage; using JetBrains.Annotations; -using Robust.Client.GameObjects; using Robust.Client.Player; using Robust.Client.UserInterface; using Robust.Shared.Containers; @@ -43,8 +42,8 @@ namespace Content.Client.Inventory UpdatesOutsidePrediction = true; base.Initialize(); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(OnShutdown); @@ -113,12 +112,12 @@ namespace Content.Client.Inventory OnUnlinkInventory?.Invoke(); } - private void OnPlayerDetached(EntityUid uid, InventorySlotsComponent component, PlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, InventorySlotsComponent component, LocalPlayerDetachedEvent args) { OnUnlinkInventory?.Invoke(); } - private void OnPlayerAttached(EntityUid uid, InventorySlotsComponent component, PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, InventorySlotsComponent component, LocalPlayerAttachedEvent args) { if (TryGetSlots(uid, out var definitions)) { diff --git a/Content.Client/Mind/MindSystem.cs b/Content.Client/Mind/MindSystem.cs index 87d9e9ddbe..cc43c349e4 100644 --- a/Content.Client/Mind/MindSystem.cs +++ b/Content.Client/Mind/MindSystem.cs @@ -4,4 +4,24 @@ namespace Content.Client.Mind; public sealed class MindSystem : SharedMindSystem { + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnHandleState); + } + + private void OnHandleState(EntityUid uid, MindComponent component, ref AfterAutoHandleStateEvent args) + { + // Because minds are generally not networked, there might be weird situations were a client thinks multiple + // users share a mind? E.g., if an admin periodical gets sent all minds via some PVS override, but doesn't get + // sent intermediate states? Not sure if this is actually possible, but better to be safe. + foreach (var (user, mind) in UserMinds) + { + if (mind == uid) + UserMinds.Remove(user); + } + + if (component.UserId != null) + UserMinds[component.UserId.Value] = uid; + } } diff --git a/Content.Client/Overlays/EquipmentHudSystem.cs b/Content.Client/Overlays/EquipmentHudSystem.cs index 1d5ec03291..ac618691d8 100644 --- a/Content.Client/Overlays/EquipmentHudSystem.cs +++ b/Content.Client/Overlays/EquipmentHudSystem.cs @@ -1,7 +1,6 @@ using Content.Shared.GameTicking; using Content.Shared.Inventory; using Content.Shared.Inventory.Events; -using Robust.Client.GameObjects; using Robust.Client.Player; namespace Content.Client.Overlays; @@ -24,8 +23,8 @@ public abstract class EquipmentHudSystem : EntitySystem where T : IComponent SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnRemove); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(OnCompEquip); SubscribeLocalEvent(OnCompUnequip); @@ -65,12 +64,12 @@ public abstract class EquipmentHudSystem : EntitySystem where T : IComponent RefreshOverlay(uid); } - private void OnPlayerAttached(PlayerAttachedEvent args) + private void OnPlayerAttached(LocalPlayerAttachedEvent args) { RefreshOverlay(args.Entity); } - private void OnPlayerDetached(PlayerDetachedEvent args) + private void OnPlayerDetached(LocalPlayerDetachedEvent args) { if (_player.LocalPlayer?.ControlledEntity == null) Deactivate(); diff --git a/Content.Client/Physics/Controllers/MoverController.cs b/Content.Client/Physics/Controllers/MoverController.cs index 54c5c3de15..52340b3391 100644 --- a/Content.Client/Physics/Controllers/MoverController.cs +++ b/Content.Client/Physics/Controllers/MoverController.cs @@ -1,7 +1,6 @@ using Content.Shared.Movement.Components; using Content.Shared.Movement.Systems; using Content.Shared.Pulling.Components; -using Robust.Client.GameObjects; using Robust.Client.Physics; using Robust.Client.Player; using Robust.Shared.Physics.Components; @@ -17,10 +16,10 @@ namespace Content.Client.Physics.Controllers public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnRelayPlayerAttached); - SubscribeLocalEvent(OnRelayPlayerDetached); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnRelayPlayerAttached); + SubscribeLocalEvent(OnRelayPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(OnUpdatePredicted); SubscribeLocalEvent(OnUpdateRelayTargetPredicted); @@ -54,7 +53,7 @@ namespace Content.Client.Physics.Controllers // What if the entity is being pulled by a vehicle controlled by the player? } - private void OnRelayPlayerAttached(EntityUid uid, RelayInputMoverComponent component, PlayerAttachedEvent args) + private void OnRelayPlayerAttached(EntityUid uid, RelayInputMoverComponent component, LocalPlayerAttachedEvent args) { Physics.UpdateIsPredicted(uid); Physics.UpdateIsPredicted(component.RelayEntity); @@ -62,7 +61,7 @@ namespace Content.Client.Physics.Controllers SetMoveInput(inputMover, MoveButtons.None); } - private void OnRelayPlayerDetached(EntityUid uid, RelayInputMoverComponent component, PlayerDetachedEvent args) + private void OnRelayPlayerDetached(EntityUid uid, RelayInputMoverComponent component, LocalPlayerDetachedEvent args) { Physics.UpdateIsPredicted(uid); Physics.UpdateIsPredicted(component.RelayEntity); @@ -70,12 +69,12 @@ namespace Content.Client.Physics.Controllers SetMoveInput(inputMover, MoveButtons.None); } - private void OnPlayerAttached(EntityUid uid, InputMoverComponent component, PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, InputMoverComponent component, LocalPlayerAttachedEvent args) { SetMoveInput(component, MoveButtons.None); } - private void OnPlayerDetached(EntityUid uid, InputMoverComponent component, PlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, InputMoverComponent component, LocalPlayerDetachedEvent args) { SetMoveInput(component, MoveButtons.None); } diff --git a/Content.Client/Players/PlayerSystem.cs b/Content.Client/Players/PlayerSystem.cs index d5ce4ec197..dba95ef7a6 100644 --- a/Content.Client/Players/PlayerSystem.cs +++ b/Content.Client/Players/PlayerSystem.cs @@ -1,11 +1,11 @@ using Content.Shared.Players; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Client.Players; public sealed class PlayerSystem : SharedPlayerSystem { - public override PlayerData? ContentData(ICommonSession? session) + public override ContentPlayerData? ContentData(ICommonSession? session) { return null; } diff --git a/Content.Client/Popups/PopupSystem.cs b/Content.Client/Popups/PopupSystem.cs index 1d4ca19ce2..d68272a107 100644 --- a/Content.Client/Popups/PopupSystem.cs +++ b/Content.Client/Popups/PopupSystem.cs @@ -9,7 +9,6 @@ using Robust.Client.UserInterface; using Robust.Shared.Configuration; using Robust.Shared.Map; using Robust.Shared.Player; -using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Replays; using Robust.Shared.Timing; diff --git a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Movement.cs b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Movement.cs index 3bb2afe122..d48a1eab46 100644 --- a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Movement.cs +++ b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Movement.cs @@ -2,7 +2,7 @@ using Content.Shared.Movement.Components; using Robust.Shared.Input; using Robust.Shared.Input.Binding; using Robust.Shared.Map; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Client.Replay.Spectator; diff --git a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Position.cs b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Position.cs index 45a175e688..479e2eff97 100644 --- a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Position.cs +++ b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Position.cs @@ -1,5 +1,5 @@ using Content.Shared.Movement.Components; -using Robust.Client.GameObjects; +using Robust.Client.Player; using Robust.Shared.Map; using Robust.Shared.Map.Components; using Robust.Shared.Network; @@ -79,7 +79,7 @@ public sealed partial class ReplaySpectatorSystem public void SetSpectatorPosition(SpectatorData data) { - if (_player.LocalPlayer == null) + if (_player.LocalSession == null) return; if (data.Controller != null @@ -87,13 +87,13 @@ public sealed partial class ReplaySpectatorSystem && Exists(session.AttachedEntity) && Transform(session.AttachedEntity.Value).MapID != MapId.Nullspace) { - _player.LocalPlayer.AttachEntity(session.AttachedEntity.Value, EntityManager, _client); + _player.SetAttachedEntity(_player.LocalSession, session.AttachedEntity); return; } if (Exists(data.Entity) && Transform(data.Entity).MapID != MapId.Nullspace) { - _player.LocalPlayer.AttachEntity(data.Entity, EntityManager, _client); + _player.SetAttachedEntity(_player.LocalSession, data.Entity); return; } @@ -118,7 +118,7 @@ public sealed partial class ReplaySpectatorSystem return; } - if (data.Eye != null && TryComp(_player.LocalPlayer.ControlledEntity, out InputMoverComponent? newMover)) + if (data.Eye != null && TryComp(_player.LocalSession.AttachedEntity, out InputMoverComponent? newMover)) { newMover.RelativeEntity = data.Eye.Value.Ent; newMover.TargetRelativeRotation = newMover.RelativeRotation = data.Eye.Value.Rot; @@ -177,7 +177,7 @@ public sealed partial class ReplaySpectatorSystem SetSpectatorPosition(default); } - private void OnDetached(EntityUid uid, ReplaySpectatorComponent component, PlayerDetachedEvent args) + private void OnDetached(EntityUid uid, ReplaySpectatorComponent component, LocalPlayerDetachedEvent args) { if (IsClientSide(uid)) QueueDel(uid); diff --git a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Spectate.cs b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Spectate.cs index f3475c5479..80a8429055 100644 --- a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Spectate.cs +++ b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Spectate.cs @@ -32,10 +32,10 @@ public sealed partial class ReplaySpectatorSystem public void SpectateEntity(EntityUid target) { - if (_player.LocalPlayer == null) + if (_player.LocalSession == null) return; - var old = _player.LocalPlayer.ControlledEntity; + var old = _player.LocalSession.AttachedEntity; if (old == target) { @@ -44,7 +44,7 @@ public sealed partial class ReplaySpectatorSystem return; } - _player.LocalPlayer.AttachEntity(target, EntityManager, _client); + _player.SetAttachedEntity(_player.LocalSession, target); EnsureComp(target); _stateMan.RequestStateChange(); @@ -59,10 +59,10 @@ public sealed partial class ReplaySpectatorSystem public TransformComponent SpawnSpectatorGhost(EntityCoordinates coords, bool gridAttach) { - if (_player.LocalPlayer == null) + if (_player.LocalSession == null) throw new InvalidOperationException(); - var old = _player.LocalPlayer.ControlledEntity; + var old = _player.LocalSession.AttachedEntity; var ent = Spawn("ReplayObserver", coords); _eye.SetMaxZoom(ent, Vector2.One * 5); @@ -73,7 +73,7 @@ public sealed partial class ReplaySpectatorSystem if (gridAttach) _transform.AttachToGridOrMap(ent); - _player.LocalPlayer.AttachEntity(ent, EntityManager, _client); + _player.SetAttachedEntity(_player.LocalSession, ent); if (old != null) { @@ -93,7 +93,7 @@ public sealed partial class ReplaySpectatorSystem { if (args.Length == 0) { - if (_player.LocalPlayer?.ControlledEntity is { } current) + if (_player.LocalSession?.AttachedEntity is { } current) SpawnSpectatorGhost(new EntityCoordinates(current, default), true); else SpawnSpectatorGhost(default, true); diff --git a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.cs b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.cs index c75529c037..3b9662ed8c 100644 --- a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.cs +++ b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.cs @@ -6,7 +6,6 @@ using Robust.Client.Player; using Robust.Client.Replays.Playback; using Robust.Client.State; using Robust.Shared.Console; -using Robust.Shared.Network; using Robust.Shared.Serialization.Markdown.Mapping; namespace Content.Client.Replay.Spectator; @@ -40,7 +39,7 @@ public sealed partial class ReplaySpectatorSystem : EntitySystem SubscribeLocalEvent>(OnGetAlternativeVerbs); SubscribeLocalEvent(OnTerminating); - SubscribeLocalEvent(OnDetached); + SubscribeLocalEvent(OnDetached); SubscribeLocalEvent(OnParentChanged); InitializeBlockers(); diff --git a/Content.Client/Sandbox/SandboxSystem.cs b/Content.Client/Sandbox/SandboxSystem.cs index 7dcbfa0ee0..d16751e371 100644 --- a/Content.Client/Sandbox/SandboxSystem.cs +++ b/Content.Client/Sandbox/SandboxSystem.cs @@ -5,7 +5,7 @@ using Robust.Client.Console; using Robust.Client.Placement; using Robust.Client.Placement.Modes; using Robust.Shared.Map; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Client.Sandbox { diff --git a/Content.Client/Traits/ParacusiaSystem.cs b/Content.Client/Traits/ParacusiaSystem.cs index 34c7d6859e..87abec80bb 100644 --- a/Content.Client/Traits/ParacusiaSystem.cs +++ b/Content.Client/Traits/ParacusiaSystem.cs @@ -1,8 +1,6 @@ using System.Numerics; using Content.Shared.Traits.Assorted; -using Content.Client.Camera; using Robust.Shared.Random; -using Robust.Client.GameObjects; using Robust.Client.Player; using Robust.Shared.Timing; @@ -19,7 +17,7 @@ public sealed class ParacusiaSystem : SharedParacusiaSystem { base.Initialize(); SubscribeLocalEvent(OnComponentStartup); - SubscribeLocalEvent(OnPlayerDetach); + SubscribeLocalEvent(OnPlayerDetach); } public override void Update(float frameTime) @@ -40,7 +38,7 @@ public sealed class ParacusiaSystem : SharedParacusiaSystem component.NextIncidentTime = _timing.CurTime + TimeSpan.FromSeconds(_random.NextFloat(component.MinTimeBetweenIncidents, component.MaxTimeBetweenIncidents)); } - private void OnPlayerDetach(EntityUid uid, ParacusiaComponent component, PlayerDetachedEvent args) + private void OnPlayerDetach(EntityUid uid, ParacusiaComponent component, LocalPlayerDetachedEvent args) { component.Stream?.Stop(); } diff --git a/Content.Client/UserInterface/Systems/Character/CharacterUIController.cs b/Content.Client/UserInterface/Systems/Character/CharacterUIController.cs index 925b2dae4f..45bdada6e7 100644 --- a/Content.Client/UserInterface/Systems/Character/CharacterUIController.cs +++ b/Content.Client/UserInterface/Systems/Character/CharacterUIController.cs @@ -8,6 +8,7 @@ using Content.Client.UserInterface.Systems.Objectives.Controls; using Content.Shared.Input; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.Player; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controllers; using Robust.Client.UserInterface.Controls; @@ -21,6 +22,7 @@ namespace Content.Client.UserInterface.Systems.Character; [UsedImplicitly] public sealed class CharacterUIController : UIController, IOnStateEntered, IOnStateExited, IOnSystemChanged { + [Dependency] private readonly IPlayerManager _player = default!; [UISystemDependency] private readonly CharacterInfoSystem _characterInfo = default!; [UISystemDependency] private readonly SpriteSystem _sprite = default!; @@ -56,13 +58,13 @@ public sealed class CharacterUIController : UIController, IOnStateEntered(OnChatMessage); _net.RegisterNetMessage(OnDeleteChatMessagesBy); @@ -170,7 +171,7 @@ public sealed class ChatUIController : UIController _speechBubbleRoot = new LayoutContainer(); - OnLocalPlayerChanged(new LocalPlayerChangedEventArgs(null, _player.LocalPlayer)); + UpdateChannelPermissions(); _input.SetInputCommand(ContentKeyFunctions.FocusChat, InputCmdHandler.FromDelegate(_ => FocusChat())); @@ -363,29 +364,7 @@ public sealed class ChatUIController : UIController _speechBubbleRoot.SetPositionLast(); } - private void OnLocalPlayerChanged(LocalPlayerChangedEventArgs obj) - { - if (obj.OldPlayer != null) - { - obj.OldPlayer.EntityAttached -= OnLocalPlayerEntityAttached; - obj.OldPlayer.EntityDetached -= OnLocalPlayerEntityDetached; - } - - if (obj.NewPlayer != null) - { - obj.NewPlayer.EntityAttached += OnLocalPlayerEntityAttached; - obj.NewPlayer.EntityDetached += OnLocalPlayerEntityDetached; - } - - UpdateChannelPermissions(); - } - - private void OnLocalPlayerEntityAttached(EntityAttachedEventArgs obj) - { - UpdateChannelPermissions(); - } - - private void OnLocalPlayerEntityDetached(EntityDetachedEventArgs obj) + private void OnAttachedChanged(EntityUid uid) { UpdateChannelPermissions(); } diff --git a/Content.Client/UserInterface/Systems/DamageOverlays/DamageOverlayUiController.cs b/Content.Client/UserInterface/Systems/DamageOverlays/DamageOverlayUiController.cs index 0836314dbc..ba4a871199 100644 --- a/Content.Client/UserInterface/Systems/DamageOverlays/DamageOverlayUiController.cs +++ b/Content.Client/UserInterface/Systems/DamageOverlays/DamageOverlayUiController.cs @@ -1,11 +1,9 @@ -using Content.Client.Alerts; using Content.Shared.Damage; using Content.Shared.FixedPoint; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; using JetBrains.Annotations; -using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.Player; using Robust.Client.UserInterface; @@ -25,13 +23,13 @@ public sealed class DamageOverlayUiController : UIController public override void Initialize() { _overlay = new Overlays.DamageOverlay(); - SubscribeLocalEvent(OnPlayerAttach); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttach); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(OnMobStateChanged); SubscribeLocalEvent(OnThresholdCheck); } - private void OnPlayerAttach(PlayerAttachedEvent args) + private void OnPlayerAttach(LocalPlayerAttachedEvent args) { ClearOverlay(); if (!EntityManager.TryGetComponent(args.Entity, out var mobState)) @@ -41,7 +39,7 @@ public sealed class DamageOverlayUiController : UIController _overlayManager.AddOverlay(_overlay); } - private void OnPlayerDetached(PlayerDetachedEvent args) + private void OnPlayerDetached(LocalPlayerDetachedEvent args) { _overlayManager.RemoveOverlay(_overlay); ClearOverlay(); diff --git a/Content.Client/UserInterface/Systems/Sandbox/SandboxUIController.cs b/Content.Client/UserInterface/Systems/Sandbox/SandboxUIController.cs index d7ec9f3497..778de82210 100644 --- a/Content.Client/UserInterface/Systems/Sandbox/SandboxUIController.cs +++ b/Content.Client/UserInterface/Systems/Sandbox/SandboxUIController.cs @@ -17,7 +17,7 @@ using Robust.Client.UserInterface.Controllers; using Robust.Client.UserInterface.Controllers.Implementations; using Robust.Shared.Input.Binding; using Robust.Shared.Map; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Utility; using static Robust.Client.UserInterface.Controls.BaseButton; diff --git a/Content.Client/Weapons/Melee/MeleeWeaponSystem.cs b/Content.Client/Weapons/Melee/MeleeWeaponSystem.cs index 397032cd15..2d2883d8b7 100644 --- a/Content.Client/Weapons/Melee/MeleeWeaponSystem.cs +++ b/Content.Client/Weapons/Melee/MeleeWeaponSystem.cs @@ -16,7 +16,8 @@ using Robust.Client.State; using Robust.Shared.Input; using Robust.Shared.Map; using Robust.Shared.Player; -using Robust.Shared.Players; +using Robust.Shared.Prototypes; +using Robust.Shared.Timing; namespace Content.Client.Weapons.Melee; diff --git a/Content.IntegrationTests/Pair/TestPair.cs b/Content.IntegrationTests/Pair/TestPair.cs index 2971573ff2..2672b4db56 100644 --- a/Content.IntegrationTests/Pair/TestPair.cs +++ b/Content.IntegrationTests/Pair/TestPair.cs @@ -3,13 +3,11 @@ using System.Collections.Generic; using System.IO; using System.Linq; using Content.Server.GameTicking; -using Content.Server.Players; -using Content.Shared.Mind; using Content.Shared.Players; -using Robust.Server.Player; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Timing; using Robust.UnitTesting; @@ -30,8 +28,8 @@ public sealed partial class TestPair public RobustIntegrationTest.ServerIntegrationInstance Server { get; private set; } = default!; public RobustIntegrationTest.ClientIntegrationInstance Client { get; private set; } = default!; - public IPlayerSession? Player => (IPlayerSession?) Server.PlayerMan.Sessions.FirstOrDefault(); - public PlayerData? PlayerData => Player?.Data.ContentData(); + public ICommonSession? Player => Server.PlayerMan.Sessions.FirstOrDefault(); + public ContentPlayerData? PlayerData => Player?.Data.ContentData(); public PoolTestLogHandler ServerLogHandler { get; private set; } = default!; public PoolTestLogHandler ClientLogHandler { get; private set; } = default!; diff --git a/Content.IntegrationTests/Tests/Actions/ActionsAddedTest.cs b/Content.IntegrationTests/Tests/Actions/ActionsAddedTest.cs index 01f8bdd938..01daeea93c 100644 --- a/Content.IntegrationTests/Tests/Actions/ActionsAddedTest.cs +++ b/Content.IntegrationTests/Tests/Actions/ActionsAddedTest.cs @@ -3,8 +3,6 @@ using Content.Shared.Actions; using Content.Shared.CombatMode; using Robust.Server.Player; using Robust.Shared.GameObjects; -using Robust.Shared.Players; -using PlayerManager = Robust.Client.Player.PlayerManager; namespace Content.IntegrationTests.Tests.Actions; @@ -26,7 +24,7 @@ public sealed class ActionsAddedTest var sEntMan = server.ResolveDependency(); var cEntMan = client.ResolveDependency(); var clientSession = client.ResolveDependency().LocalPlayer?.Session; - var serverSession = server.ResolveDependency().ServerSessions.Single(); + var serverSession = server.ResolveDependency().Sessions.Single(); var sActionSystem = server.System(); var cActionSystem = client.System(); diff --git a/Content.IntegrationTests/Tests/Administration/Logs/AddTests.cs b/Content.IntegrationTests/Tests/Administration/Logs/AddTests.cs index 6562a26b5e..98c7363a6c 100644 --- a/Content.IntegrationTests/Tests/Administration/Logs/AddTests.cs +++ b/Content.IntegrationTests/Tests/Administration/Logs/AddTests.cs @@ -7,8 +7,6 @@ using Content.Shared.Administration.Logs; using Content.Shared.Database; using Robust.Server.Player; using Robust.Shared.GameObjects; -using Robust.Shared.Map; -using Robust.Shared.Utility; namespace Content.IntegrationTests.Tests.Administration.Logs; @@ -177,7 +175,7 @@ public sealed class AddTests await server.WaitPost(() => { - var player = sPlayers.ServerSessions.First(); + var player = sPlayers.Sessions.First(); playerGuid = player.UserId; Assert.DoesNotThrow(() => @@ -280,7 +278,7 @@ public sealed class AddTests await server.WaitPost(() => { - var player = sPlayers.ServerSessions.Single(); + var player = sPlayers.Sessions.Single(); sAdminLogSystem.Add(LogType.Unknown, $"{player} {player} test log: {guid}"); }); @@ -318,7 +316,7 @@ public sealed class AddTests await server.WaitPost(() => { - var player = sPlayers.ServerSessions.Single(); + var player = sPlayers.Sessions.Single(); sAdminLogSystem.Add(LogType.Unknown, $"{player:first} {player:second} test log: {guid}"); }); diff --git a/Content.IntegrationTests/Tests/Administration/Logs/QueryTests.cs b/Content.IntegrationTests/Tests/Administration/Logs/QueryTests.cs index 1155edfad2..5a58757d53 100644 --- a/Content.IntegrationTests/Tests/Administration/Logs/QueryTests.cs +++ b/Content.IntegrationTests/Tests/Administration/Logs/QueryTests.cs @@ -5,6 +5,7 @@ using Content.Server.GameTicking; using Content.Shared.Database; using Robust.Server.Player; using Robust.Shared.GameObjects; +using Robust.Shared.Player; namespace Content.IntegrationTests.Tests.Administration.Logs; @@ -27,11 +28,11 @@ public sealed class QueryTests var date = DateTime.UtcNow; var guid = Guid.NewGuid(); - IPlayerSession player = default; + ICommonSession player = default; await server.WaitPost(() => { - player = sPlayers.ServerSessions.First(); + player = sPlayers.Sessions.First(); sAdminLogSystem.Add(LogType.Unknown, $"{player.AttachedEntity:Entity} test log: {guid}"); }); diff --git a/Content.IntegrationTests/Tests/Cleanup/EuiManagerTest.cs b/Content.IntegrationTests/Tests/Cleanup/EuiManagerTest.cs index 9aac4e2892..e2bff03501 100644 --- a/Content.IntegrationTests/Tests/Cleanup/EuiManagerTest.cs +++ b/Content.IntegrationTests/Tests/Cleanup/EuiManagerTest.cs @@ -25,7 +25,7 @@ public sealed class EuiManagerTest await server.WaitAssertion(() => { - var clientSession = sPlayerManager.ServerSessions.Single(); + var clientSession = sPlayerManager.Sessions.Single(); var ui = new AdminAnnounceEui(); eui.OpenEui(ui, clientSession); }); diff --git a/Content.IntegrationTests/Tests/Interaction/InteractionTest.cs b/Content.IntegrationTests/Tests/Interaction/InteractionTest.cs index b4b6c2239f..df77410e54 100644 --- a/Content.IntegrationTests/Tests/Interaction/InteractionTest.cs +++ b/Content.IntegrationTests/Tests/Interaction/InteractionTest.cs @@ -14,6 +14,7 @@ using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction; using Content.Shared.Mind; +using Content.Shared.Players; using Robust.Client.Input; using Robust.Client.UserInterface; using Robust.Server.GameObjects; @@ -21,7 +22,7 @@ using Robust.Server.Player; using Robust.Shared.GameObjects; using Robust.Shared.Log; using Robust.Shared.Map; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Timing; using Robust.UnitTesting; @@ -67,7 +68,7 @@ public abstract partial class InteractionTest protected NetEntity Player; protected ICommonSession ClientSession = default!; - protected IPlayerSession ServerSession = default!; + protected ICommonSession ServerSession = default!; public EntityUid? ClientTarget; diff --git a/Content.IntegrationTests/Tests/Minds/GhostRoleTests.cs b/Content.IntegrationTests/Tests/Minds/GhostRoleTests.cs index 28e49645c9..22a185798e 100644 --- a/Content.IntegrationTests/Tests/Minds/GhostRoleTests.cs +++ b/Content.IntegrationTests/Tests/Minds/GhostRoleTests.cs @@ -5,6 +5,7 @@ using Content.Server.Ghost.Roles.Components; using Content.Server.Players; using Content.Shared.Ghost; using Content.Shared.Mind; +using Content.Shared.Players; using Robust.Shared.Console; using Robust.Shared.GameObjects; using Robust.Shared.Map; @@ -43,7 +44,7 @@ public sealed class GhostRoleTests var sPlayerMan = server.ResolveDependency(); var conHost = client.ResolveDependency(); var mindSystem = entMan.System(); - var session = sPlayerMan.ServerSessions.Single(); + var session = sPlayerMan.Sessions.Single(); var originalMindId = session.ContentData()!.Mind!.Value; // Spawn player entity & attach diff --git a/Content.IntegrationTests/Tests/Minds/MindTests.EntityDeletion.cs b/Content.IntegrationTests/Tests/Minds/MindTests.EntityDeletion.cs index 9fc68ef93d..a67a45ecb4 100644 --- a/Content.IntegrationTests/Tests/Minds/MindTests.EntityDeletion.cs +++ b/Content.IntegrationTests/Tests/Minds/MindTests.EntityDeletion.cs @@ -2,6 +2,7 @@ using System.Linq; using Content.Server.Players; using Content.Shared.Ghost; using Content.Shared.Mind; +using Content.Shared.Players; using Robust.Server.Console; using Robust.Server.GameObjects; using Robust.Server.Player; @@ -35,7 +36,7 @@ public sealed partial class MindTests MindComponent mind = default!; await server.WaitAssertion(() => { - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); playerEnt = entMan.SpawnEntity(null, MapCoordinates.Nullspace); visitEnt = entMan.SpawnEntity(null, MapCoordinates.Nullspace); @@ -81,7 +82,7 @@ public sealed partial class MindTests var entMan = server.ResolveDependency(); var mapManager = server.ResolveDependency(); var playerMan = server.ResolveDependency(); - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); var mindSystem = entMan.EntitySysManager.GetEntitySystem(); @@ -128,7 +129,7 @@ public sealed partial class MindTests var entMan = server.ResolveDependency(); var playerMan = server.ResolveDependency(); - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); Assert.That(!entMan.HasComponent(player.AttachedEntity), "Player was initially a ghost?"); @@ -162,7 +163,7 @@ public sealed partial class MindTests var mindSystem = entMan.EntitySysManager.GetEntitySystem(); var mind = GetMind(pair); - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); #pragma warning disable NUnit2045 // Interdependent assertions. Assert.That(player.AttachedEntity, Is.Not.Null); Assert.That(entMan.EntityExists(player.AttachedEntity)); @@ -218,7 +219,7 @@ public sealed partial class MindTests var playerMan = server.ResolveDependency(); var serverConsole = server.ResolveDependency(); - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); var ghost = await BecomeGhost(pair); @@ -263,7 +264,7 @@ public sealed partial class MindTests var playerMan = server.ResolveDependency(); var serverConsole = server.ResolveDependency(); - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); EntityUid ghost = default!; diff --git a/Content.IntegrationTests/Tests/Minds/MindTests.Helpers.cs b/Content.IntegrationTests/Tests/Minds/MindTests.Helpers.cs index f71a6ad5f9..bbc011acac 100644 --- a/Content.IntegrationTests/Tests/Minds/MindTests.Helpers.cs +++ b/Content.IntegrationTests/Tests/Minds/MindTests.Helpers.cs @@ -3,12 +3,14 @@ using Content.IntegrationTests.Pair; using Content.Server.Players; using Content.Shared.Ghost; using Content.Shared.Mind; +using Content.Shared.Players; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Enums; using Robust.Shared.GameObjects; using Robust.Shared.Map; using Robust.Shared.Network; +using Robust.Shared.Player; namespace Content.IntegrationTests.Tests.Minds; @@ -36,7 +38,7 @@ public sealed partial class MindTests var playerMan = pair.Server.ResolveDependency(); var mindSys = entMan.System(); - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); EntityUid entity = default; EntityUid mindId = default!; @@ -71,7 +73,7 @@ public sealed partial class MindTests EntityUid mindId = default!; MindComponent mind = default!; - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); await pair.Server.WaitAssertion(() => { var oldUid = player.AttachedEntity; @@ -118,7 +120,7 @@ public sealed partial class MindTests { var playerMan = pair.Server.ResolveDependency(); var entMan = pair.Server.ResolveDependency(); - var player = playerMan.ServerSessions.SingleOrDefault(); + var player = playerMan.Sessions.SingleOrDefault(); Assert.That(player, Is.Not.Null); var mindId = player.ContentData()!.Mind!.Value; @@ -139,7 +141,7 @@ public sealed partial class MindTests var netManager = pair.Client.ResolveDependency(); var playerMan = pair.Server.ResolveDependency(); var entMan = pair.Server.ResolveDependency(); - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); var mindId = player.ContentData()!.Mind!.Value; var mind = entMan.GetComponent(mindId); @@ -161,21 +163,21 @@ public sealed partial class MindTests { var netManager = pair.Client.ResolveDependency(); var playerMan = pair.Server.ResolveDependency(); - Assert.That(!playerMan.ServerSessions.Any()); + Assert.That(!playerMan.Sessions.Any()); await Task.WhenAll(pair.Client.WaitIdleAsync(), pair.Client.WaitIdleAsync()); pair.Client.SetConnectTarget(pair.Server); await pair.Client.WaitPost(() => netManager.ClientConnect(null!, 0, username)); await pair.RunTicksSync(5); - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); Assert.That(player.Status, Is.EqualTo(SessionStatus.InGame)); } - private static async Task DisconnectReconnect(Pair.TestPair pair) + private static async Task DisconnectReconnect(Pair.TestPair pair) { var playerMan = pair.Server.ResolveDependency(); - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); var name = player.Name; var id = player.UserId; @@ -183,7 +185,7 @@ public sealed partial class MindTests await Connect(pair, name); // Session has changed - var newSession = playerMan.ServerSessions.Single(); + var newSession = playerMan.Sessions.Single(); Assert.Multiple(() => { Assert.That(newSession, Is.Not.EqualTo(player)); diff --git a/Content.IntegrationTests/Tests/Minds/MindTests.ReconnectTests.cs b/Content.IntegrationTests/Tests/Minds/MindTests.ReconnectTests.cs index ea2110c03a..9939ebc545 100644 --- a/Content.IntegrationTests/Tests/Minds/MindTests.ReconnectTests.cs +++ b/Content.IntegrationTests/Tests/Minds/MindTests.ReconnectTests.cs @@ -49,7 +49,7 @@ public sealed partial class MindTests var mind = GetMind(pair); var playerMan = pair.Server.ResolveDependency(); - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); var name = player.Name; var user = player.UserId; Assert.That(mind.Comp.OwnedEntity, Is.Not.Null); @@ -72,7 +72,7 @@ public sealed partial class MindTests // Reconnect await Connect(pair, name); - player = playerMan.ServerSessions.Single(); + player = playerMan.Sessions.Single(); Assert.Multiple(() => { Assert.That(user, Is.EqualTo(player.UserId)); @@ -127,8 +127,10 @@ public sealed partial class MindTests var mindSys = entMan.System(); var mind = GetMind(pair); + Assert.Null(mind.Comp.VisitingEntity); + // Make player visit a new mob - var original = mind.Comp.CurrentEntity; + var original = mind.Comp.OwnedEntity; EntityUid visiting = default; await pair.Server.WaitAssertion(() => { @@ -137,6 +139,7 @@ public sealed partial class MindTests }); await pair.RunTicksSync(5); + Assert.That(mind.Comp.VisitingEntity, Is.EqualTo(visiting)); await DisconnectReconnect(pair); // Player is back in control of the visited mob, mind was preserved diff --git a/Content.IntegrationTests/Tests/Minds/MindTests.cs b/Content.IntegrationTests/Tests/Minds/MindTests.cs index fb2fef43ed..c9788b80a6 100644 --- a/Content.IntegrationTests/Tests/Minds/MindTests.cs +++ b/Content.IntegrationTests/Tests/Minds/MindTests.cs @@ -11,6 +11,7 @@ using Content.Shared.Damage.Prototypes; using Content.Shared.FixedPoint; using Content.Shared.Mind; using Content.Shared.Mind.Components; +using Content.Shared.Players; using Content.Shared.Roles; using Content.Shared.Roles.Jobs; using Robust.Server.Console; @@ -67,13 +68,12 @@ public sealed partial class MindTests var entity = entMan.SpawnEntity(null, new MapCoordinates()); var mindComp = entMan.EnsureComponent(entity); - var mindId = mindSystem.CreateMind(null); - var mind = entMan.GetComponent(mindId); + var mind = mindSystem.CreateMind(null); - Assert.That(mind.UserId, Is.EqualTo(null)); + Assert.That(mind.Comp.UserId, Is.EqualTo(null)); - mindSystem.TransferTo(mindId, entity, mind: mind); - Assert.That(mindSystem.GetMind(entity, mindComp), Is.EqualTo(mindId)); + mindSystem.TransferTo(mind, entity, mind: mind); + Assert.That(mindSystem.GetMind(entity, mindComp), Is.EqualTo(mind.Owner)); }); await pair.CleanReturnAsync(); @@ -94,11 +94,11 @@ public sealed partial class MindTests var entity = entMan.SpawnEntity(null, new MapCoordinates()); var mindComp = entMan.EnsureComponent(entity); - var mindId = mindSystem.CreateMind(null); + var mindId = mindSystem.CreateMind(null).Owner; mindSystem.TransferTo(mindId, entity); Assert.That(mindSystem.GetMind(entity, mindComp), Is.EqualTo(mindId)); - var mind2 = mindSystem.CreateMind(null); + var mind2 = mindSystem.CreateMind(null).Owner; mindSystem.TransferTo(mind2, entity); Assert.Multiple(() => { @@ -184,7 +184,7 @@ public sealed partial class MindTests var mindComp = entMan.EnsureComponent(entity); entMan.EnsureComponent(targetEntity); - var mind = mindSystem.CreateMind(null); + var mind = mindSystem.CreateMind(null).Owner; mindSystem.TransferTo(mind, entity); @@ -276,7 +276,7 @@ public sealed partial class MindTests var entity = entMan.SpawnEntity(null, new MapCoordinates()); var mindComp = entMan.EnsureComponent(entity); - var mindId = mindSystem.CreateMind(null); + var mindId = mindSystem.CreateMind(null).Owner; var mind = entMan.EnsureComponent(mindId); Assert.That(mind.UserId, Is.EqualTo(null)); @@ -334,7 +334,7 @@ public sealed partial class MindTests public async Task TestPlayerCanGhost() { // Client is needed to spawn session - await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true }); + await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true, DummyTicker = false }); var server = pair.Server; var entMan = server.ResolveDependency(); @@ -346,7 +346,7 @@ public sealed partial class MindTests EntityUid entity = default!; EntityUid mindId = default!; MindComponent mind = default!; - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); await server.WaitAssertion(() => { @@ -407,12 +407,6 @@ public sealed partial class MindTests await pair.CleanReturnAsync(); } - // TODO Implement - /*[Test] - public async Task TestPlayerCanReturnFromGhostWhenDead() - { - }*/ - [Test] public async Task TestGhostDoesNotInfiniteLoop() { @@ -433,7 +427,7 @@ public sealed partial class MindTests EntityUid ghost = default!; EntityUid mindId = default!; MindComponent mind = default!; - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); await server.WaitAssertion(() => { diff --git a/Content.IntegrationTests/Tests/Toolshed/ToolshedTest.cs b/Content.IntegrationTests/Tests/Toolshed/ToolshedTest.cs index ca7eeac199..d6aec781a9 100644 --- a/Content.IntegrationTests/Tests/Toolshed/ToolshedTest.cs +++ b/Content.IntegrationTests/Tests/Toolshed/ToolshedTest.cs @@ -2,8 +2,7 @@ using System.Collections.Generic; using Content.IntegrationTests.Pair; using Content.Server.Administration.Managers; -using Robust.Server.Player; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Toolshed; using Robust.Shared.Toolshed.Errors; using Robust.Shared.Toolshed.Syntax; @@ -60,7 +59,7 @@ public abstract class ToolshedTest : IInvocationContext AdminManager = Server.ResolveDependency(); } - protected bool InvokeCommand(string command, out object? result, IPlayerSession? session = null) + protected bool InvokeCommand(string command, out object? result, ICommonSession? session = null) { return Toolshed.InvokeCommand(this, command, null, out result); } @@ -95,7 +94,7 @@ public abstract class ToolshedTest : IInvocationContext return true; } - protected IPlayerSession? InvocationSession { get; set; } + protected ICommonSession? InvocationSession { get; set; } public ICommonSession? Session { diff --git a/Content.MapRenderer/Painters/MapPainter.cs b/Content.MapRenderer/Painters/MapPainter.cs index b799db78a5..8f3dd59baf 100644 --- a/Content.MapRenderer/Painters/MapPainter.cs +++ b/Content.MapRenderer/Painters/MapPainter.cs @@ -68,7 +68,7 @@ namespace Content.MapRenderer.Painters await server.WaitPost(() => { - var playerEntity = sPlayerManager.ServerSessions.Single().AttachedEntity; + var playerEntity = sPlayerManager.Sessions.Single().AttachedEntity; if (playerEntity.HasValue) { diff --git a/Content.Server/Administration/AdminPermsChangedEventArgs.cs b/Content.Server/Administration/AdminPermsChangedEventArgs.cs index 24ca7aca68..07eb416be6 100644 --- a/Content.Server/Administration/AdminPermsChangedEventArgs.cs +++ b/Content.Server/Administration/AdminPermsChangedEventArgs.cs @@ -1,5 +1,5 @@ using Content.Shared.Administration; -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Administration { @@ -8,7 +8,7 @@ namespace Content.Server.Administration /// public sealed class AdminPermsChangedEventArgs : EventArgs { - public AdminPermsChangedEventArgs(IPlayerSession player, AdminFlags? flags) + public AdminPermsChangedEventArgs(ICommonSession player, AdminFlags? flags) { Player = player; Flags = flags; @@ -17,7 +17,7 @@ namespace Content.Server.Administration /// /// The player that had their admin permissions changed. /// - public IPlayerSession Player { get; } + public ICommonSession Player { get; } /// /// The admin flags of the player. Null if the player is no longer an admin. diff --git a/Content.Server/Administration/Commands/AGhost.cs b/Content.Server/Administration/Commands/AGhost.cs index 42a8600ff1..2d1a15a0be 100644 --- a/Content.Server/Administration/Commands/AGhost.cs +++ b/Content.Server/Administration/Commands/AGhost.cs @@ -2,7 +2,6 @@ using Content.Shared.Administration; using Content.Shared.Ghost; using Content.Shared.Mind; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands @@ -18,7 +17,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("Nah"); diff --git a/Content.Server/Administration/Commands/AdminWhoCommand.cs b/Content.Server/Administration/Commands/AdminWhoCommand.cs index 8e6c402c4e..9765e8385f 100644 --- a/Content.Server/Administration/Commands/AdminWhoCommand.cs +++ b/Content.Server/Administration/Commands/AdminWhoCommand.cs @@ -2,7 +2,6 @@ using Content.Server.Administration.Managers; using Content.Server.Afk; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Utility; @@ -35,7 +34,7 @@ public sealed class AdminWhoCommand : IConsoleCommand if (adminData.Title is { } title) sb.Append($": [{title}]"); - if (shell.Player is IPlayerSession player && adminMgr.HasAdminFlag(player, AdminFlags.Admin)) + if (shell.Player is { } player && adminMgr.HasAdminFlag(player, AdminFlags.Admin)) { if (afk.IsAfk(admin)) sb.Append(" [AFK]"); diff --git a/Content.Server/Administration/Commands/AnnounceUiCommand.cs b/Content.Server/Administration/Commands/AnnounceUiCommand.cs index c4cd7f13e4..d80db96686 100644 --- a/Content.Server/Administration/Commands/AnnounceUiCommand.cs +++ b/Content.Server/Administration/Commands/AnnounceUiCommand.cs @@ -1,7 +1,6 @@ using Content.Server.Administration.UI; using Content.Server.EUI; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands @@ -17,7 +16,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("This does not work from the server console."); diff --git a/Content.Server/Administration/Commands/BanCommand.cs b/Content.Server/Administration/Commands/BanCommand.cs index 58a801e410..156fdf496a 100644 --- a/Content.Server/Administration/Commands/BanCommand.cs +++ b/Content.Server/Administration/Commands/BanCommand.cs @@ -1,15 +1,8 @@ using System.Linq; -using System.Net; -using System.Net.Sockets; -using System.Text; using Content.Server.Administration.Managers; -using Content.Server.Administration.Notes; -using Content.Server.Database; -using Content.Server.GameTicking; using Content.Shared.Administration; using Content.Shared.CCVar; using Content.Shared.Database; -using Content.Shared.Players.PlayTimeTracking; using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Console; @@ -84,7 +77,7 @@ public sealed class BanCommand : LocalizedCommands } var located = await _locator.LookupIdByNameOrIdAsync(target); - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (located == null) { @@ -102,7 +95,7 @@ public sealed class BanCommand : LocalizedCommands { if (args.Length == 1) { - var options = _playerManager.ServerSessions.Select(c => c.Name).OrderBy(c => c).ToArray(); + var options = _playerManager.Sessions.Select(c => c.Name).OrderBy(c => c).ToArray(); return CompletionResult.FromHintOptions(options, LocalizationManager.GetString("cmd-ban-hint")); } diff --git a/Content.Server/Administration/Commands/BanListCommand.cs b/Content.Server/Administration/Commands/BanListCommand.cs index 1c2be52394..a5bc97dce3 100644 --- a/Content.Server/Administration/Commands/BanListCommand.cs +++ b/Content.Server/Administration/Commands/BanListCommand.cs @@ -36,7 +36,7 @@ public sealed class BanListCommand : LocalizedCommands return; } - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { var bans = await _dbManager.GetServerBansAsync(data.LastAddress, data.UserId, data.LastHWId, false); @@ -67,7 +67,7 @@ public sealed class BanListCommand : LocalizedCommands return CompletionResult.Empty; var playerMgr = IoCManager.Resolve(); - var options = playerMgr.ServerSessions.Select(c => c.Name).OrderBy(c => c).ToArray(); + var options = playerMgr.Sessions.Select(c => c.Name).OrderBy(c => c).ToArray(); return CompletionResult.FromHintOptions(options, Loc.GetString("cmd-banlist-hint")); } } diff --git a/Content.Server/Administration/Commands/BanPanelCommand.cs b/Content.Server/Administration/Commands/BanPanelCommand.cs index 6036e5aa6e..9f9ec9e89f 100644 --- a/Content.Server/Administration/Commands/BanPanelCommand.cs +++ b/Content.Server/Administration/Commands/BanPanelCommand.cs @@ -1,12 +1,6 @@ using Content.Shared.Administration; using Robust.Shared.Console; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Content.Server.EUI; -using Robust.Server.Player; namespace Content.Server.Administration.Commands; @@ -21,7 +15,7 @@ public sealed class BanPanelCommand : LocalizedCommands public override async void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError(Loc.GetString("cmd-banpanel-server")); return; diff --git a/Content.Server/Administration/Commands/ControlMob.cs b/Content.Server/Administration/Commands/ControlMob.cs index 2d205e44d3..317461a373 100644 --- a/Content.Server/Administration/Commands/ControlMob.cs +++ b/Content.Server/Administration/Commands/ControlMob.cs @@ -1,6 +1,5 @@ +using Content.Server.Mind; using Content.Shared.Administration; -using Content.Shared.Mind; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands @@ -16,7 +15,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteLine("shell-server-cannot"); return; @@ -42,14 +41,7 @@ namespace Content.Server.Administration.Commands return; } - var mindSystem = _entities.System(); - if (!mindSystem.TryGetMind(target, out var mindId, out var mind)) - { - shell.WriteLine(Loc.GetString("shell-entity-is-not-mob")); - return; - } - - mindSystem.TransferTo(mindId, target, mind: mind); + _entities.System().ControlMob(player.UserId, target); } } } diff --git a/Content.Server/Administration/Commands/DSay.cs b/Content.Server/Administration/Commands/DSay.cs index 79b0e8db7d..61b47d7856 100644 --- a/Content.Server/Administration/Commands/DSay.cs +++ b/Content.Server/Administration/Commands/DSay.cs @@ -1,7 +1,5 @@ -using Content.Server.Chat; using Content.Server.Chat.Systems; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands @@ -17,7 +15,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("shell-only-players-can-run-this-command"); diff --git a/Content.Server/Administration/Commands/DeAdminCommand.cs b/Content.Server/Administration/Commands/DeAdminCommand.cs index c2bbfa7a33..cf65941200 100644 --- a/Content.Server/Administration/Commands/DeAdminCommand.cs +++ b/Content.Server/Administration/Commands/DeAdminCommand.cs @@ -1,10 +1,8 @@ using Content.Server.Administration.Managers; using Content.Shared.Administration; using JetBrains.Annotations; -using Robust.Server.Player; using Robust.Shared.Console; - namespace Content.Server.Administration.Commands { [UsedImplicitly] @@ -17,7 +15,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("You cannot use this command from the server console."); diff --git a/Content.Server/Administration/Commands/ExplosionCommand.cs b/Content.Server/Administration/Commands/ExplosionCommand.cs index d48b69a5ad..56ed78b2e2 100644 --- a/Content.Server/Administration/Commands/ExplosionCommand.cs +++ b/Content.Server/Administration/Commands/ExplosionCommand.cs @@ -3,7 +3,6 @@ using Content.Server.EUI; using Content.Server.Explosion.EntitySystems; using Content.Shared.Administration; using Content.Shared.Explosion; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; using Robust.Shared.Prototypes; @@ -21,7 +20,7 @@ public sealed class OpenExplosionEui : IConsoleCommand public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteError("This does not work from the server console."); diff --git a/Content.Server/Administration/Commands/FaxUiCommand.cs b/Content.Server/Administration/Commands/FaxUiCommand.cs index b06d36d08b..cf9e97e399 100644 --- a/Content.Server/Administration/Commands/FaxUiCommand.cs +++ b/Content.Server/Administration/Commands/FaxUiCommand.cs @@ -1,7 +1,6 @@ using Content.Server.EUI; using Content.Server.Fax.AdminUI; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands; @@ -16,7 +15,7 @@ public sealed class FaxUiCommand : IConsoleCommand public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("shell-only-players-can-run-this-command"); diff --git a/Content.Server/Administration/Commands/OpenAdminLogsCommand.cs b/Content.Server/Administration/Commands/OpenAdminLogsCommand.cs index 9f28dc907c..47ff3e1a1c 100644 --- a/Content.Server/Administration/Commands/OpenAdminLogsCommand.cs +++ b/Content.Server/Administration/Commands/OpenAdminLogsCommand.cs @@ -1,7 +1,6 @@ using Content.Server.Administration.Logs; using Content.Server.EUI; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands; @@ -15,7 +14,7 @@ public sealed class OpenAdminLogsCommand : IConsoleCommand public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteLine("This does not work from the server console."); return; diff --git a/Content.Server/Administration/Commands/OpenAdminNotesCommand.cs b/Content.Server/Administration/Commands/OpenAdminNotesCommand.cs index 147c0d6a82..e6ae4f7616 100644 --- a/Content.Server/Administration/Commands/OpenAdminNotesCommand.cs +++ b/Content.Server/Administration/Commands/OpenAdminNotesCommand.cs @@ -1,7 +1,5 @@ using Content.Server.Administration.Notes; -using Content.Server.Database; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands; @@ -17,7 +15,7 @@ public sealed class OpenAdminNotesCommand : IConsoleCommand public async void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError("This does not work from the server console."); return; diff --git a/Content.Server/Administration/Commands/OpenPermissionsCommand.cs b/Content.Server/Administration/Commands/OpenPermissionsCommand.cs index 78d56cb4fb..fd3227d4aa 100644 --- a/Content.Server/Administration/Commands/OpenPermissionsCommand.cs +++ b/Content.Server/Administration/Commands/OpenPermissionsCommand.cs @@ -1,10 +1,8 @@ using Content.Server.Administration.UI; using Content.Server.EUI; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; - namespace Content.Server.Administration.Commands { [AdminCommand(AdminFlags.Permissions)] @@ -16,7 +14,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("This does not work from the server console."); diff --git a/Content.Server/Administration/Commands/OpenUserVisibleNotesCommand.cs b/Content.Server/Administration/Commands/OpenUserVisibleNotesCommand.cs index d61114fcae..507c7ab279 100644 --- a/Content.Server/Administration/Commands/OpenUserVisibleNotesCommand.cs +++ b/Content.Server/Administration/Commands/OpenUserVisibleNotesCommand.cs @@ -1,7 +1,6 @@ using Content.Server.Administration.Notes; using Content.Shared.Administration; using Content.Shared.CCVar; -using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Console; @@ -27,7 +26,7 @@ public sealed class OpenUserVisibleNotesCommand : IConsoleCommand return; } - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError("This does not work from the server console."); return; diff --git a/Content.Server/Administration/Commands/PardonCommand.cs b/Content.Server/Administration/Commands/PardonCommand.cs index 869024eb7c..9cbaaece31 100644 --- a/Content.Server/Administration/Commands/PardonCommand.cs +++ b/Content.Server/Administration/Commands/PardonCommand.cs @@ -1,7 +1,6 @@ using System.Text; using Content.Server.Database; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands @@ -15,7 +14,7 @@ namespace Content.Server.Administration.Commands public async void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; var dbMan = IoCManager.Resolve(); if (args.Length != 1) diff --git a/Content.Server/Administration/Commands/PlayGlobalSoundCommand.cs b/Content.Server/Administration/Commands/PlayGlobalSoundCommand.cs index ec5b21dcee..fdf067181d 100644 --- a/Content.Server/Administration/Commands/PlayGlobalSoundCommand.cs +++ b/Content.Server/Administration/Commands/PlayGlobalSoundCommand.cs @@ -6,7 +6,6 @@ using Robust.Shared.Audio; using Robust.Shared.Console; using Robust.Shared.ContentPack; using Robust.Shared.Player; -using Robust.Shared.Players; using Robust.Shared.Prototypes; namespace Content.Server.Administration.Commands; diff --git a/Content.Server/Administration/Commands/ReAdminCommand.cs b/Content.Server/Administration/Commands/ReAdminCommand.cs index 12ff13221a..a3f5993766 100644 --- a/Content.Server/Administration/Commands/ReAdminCommand.cs +++ b/Content.Server/Administration/Commands/ReAdminCommand.cs @@ -1,9 +1,7 @@ using Content.Server.Administration.Managers; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; - namespace Content.Server.Administration.Commands { [AnyCommand] @@ -15,7 +13,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("You cannot use this command from the server console."); diff --git a/Content.Server/Administration/Commands/SetAdminOOC.cs b/Content.Server/Administration/Commands/SetAdminOOC.cs index bb11b938d8..27528e1940 100644 --- a/Content.Server/Administration/Commands/SetAdminOOC.cs +++ b/Content.Server/Administration/Commands/SetAdminOOC.cs @@ -1,8 +1,6 @@ - using Content.Server.Database; using Content.Server.Preferences.Managers; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands @@ -16,7 +14,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (!(shell.Player is IPlayerSession)) + if (shell.Player == null) { shell.WriteError(Loc.GetString("shell-only-players-can-run-this-command")); return; diff --git a/Content.Server/Administration/Commands/SetMindCommand.cs b/Content.Server/Administration/Commands/SetMindCommand.cs index b9ff329ed2..5310c2dd7f 100644 --- a/Content.Server/Administration/Commands/SetMindCommand.cs +++ b/Content.Server/Administration/Commands/SetMindCommand.cs @@ -2,6 +2,7 @@ using Content.Server.Players; using Content.Shared.Administration; using Content.Shared.Mind; using Content.Shared.Mind.Components; +using Content.Shared.Players; using Robust.Server.Player; using Robust.Shared.Console; diff --git a/Content.Server/Administration/Commands/SetOutfitCommand.cs b/Content.Server/Administration/Commands/SetOutfitCommand.cs index 28172ee6c5..b2e7f4e6cc 100644 --- a/Content.Server/Administration/Commands/SetOutfitCommand.cs +++ b/Content.Server/Administration/Commands/SetOutfitCommand.cs @@ -10,7 +10,6 @@ using Content.Shared.PDA; using Content.Shared.Preferences; using Content.Shared.Roles; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Prototypes; @@ -57,7 +56,7 @@ namespace Content.Server.Administration.Commands if (args.Length == 1) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError(Loc.GetString("set-outfit-command-is-not-player-error")); return; diff --git a/Content.Server/Administration/Commands/WarpCommand.cs b/Content.Server/Administration/Commands/WarpCommand.cs index 30a6d127aa..0d6da0d993 100644 --- a/Content.Server/Administration/Commands/WarpCommand.cs +++ b/Content.Server/Administration/Commands/WarpCommand.cs @@ -4,11 +4,9 @@ using Content.Server.Warps; using Content.Shared.Administration; using Content.Shared.Follower; using Content.Shared.Ghost; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; using Robust.Shared.Map; -using Robust.Shared.Physics; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; @@ -28,7 +26,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("Only players can use this command"); diff --git a/Content.Server/Administration/ContentNetworkResourceManager.cs b/Content.Server/Administration/ContentNetworkResourceManager.cs index 0d3f3291e6..dd95a2d897 100644 --- a/Content.Server/Administration/ContentNetworkResourceManager.cs +++ b/Content.Server/Administration/ContentNetworkResourceManager.cs @@ -1,8 +1,8 @@ using Content.Server.Database; using Content.Shared.CCVar; -using Robust.Server.Player; using Robust.Server.Upload; using Robust.Shared.Configuration; +using Robust.Shared.Player; using Robust.Shared.Upload; namespace Content.Server.Administration; @@ -22,7 +22,7 @@ public sealed class ContentNetworkResourceManager _netRes.OnResourceUploaded += OnUploadResource; } - private async void OnUploadResource(IPlayerSession session, NetworkResourceUploadMessage msg) + private async void OnUploadResource(ICommonSession session, NetworkResourceUploadMessage msg) { if (StoreUploaded) await _serverDb.AddUploadedResourceLogAsync(session.UserId, DateTime.Now, msg.RelativePath.ToString(), msg.Data); diff --git a/Content.Server/Administration/Logs/AdminLogManager.Json.cs b/Content.Server/Administration/Logs/AdminLogManager.Json.cs index 63f30c7a66..0a67d61cef 100644 --- a/Content.Server/Administration/Logs/AdminLogManager.Json.cs +++ b/Content.Server/Administration/Logs/AdminLogManager.Json.cs @@ -3,8 +3,8 @@ using System.Text.Json; using System.Text.Json.Serialization; using Content.Server.Administration.Logs.Converters; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Map; +using Robust.Shared.Player; namespace Content.Server.Administration.Logs; @@ -44,7 +44,7 @@ public sealed partial class AdminLogManager var value = properties[key]; value = value switch { - IPlayerSession player => new SerializablePlayer(player), + ICommonSession player => new SerializablePlayer(player), EntityCoordinates entityCoordinates => new SerializableEntityCoordinates(_entityManager, entityCoordinates), _ => value }; @@ -56,7 +56,7 @@ public sealed partial class AdminLogManager { EntityUid id => id, EntityStringRepresentation rep => rep.Uid, - IPlayerSession {AttachedEntity: {Valid: true}} session => session.AttachedEntity, + ICommonSession {AttachedEntity: {Valid: true}} session => session.AttachedEntity, IComponent component => component.Owner, _ => null }; diff --git a/Content.Server/Administration/Logs/Converters/PlayerSessionConverter.cs b/Content.Server/Administration/Logs/Converters/PlayerSessionConverter.cs index 0605c2db2a..c1567448cc 100644 --- a/Content.Server/Administration/Logs/Converters/PlayerSessionConverter.cs +++ b/Content.Server/Administration/Logs/Converters/PlayerSessionConverter.cs @@ -1,5 +1,5 @@ using System.Text.Json; -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Administration.Logs.Converters; @@ -36,9 +36,9 @@ public sealed class PlayerSessionConverter : AdminLogConverter _admins = new(); + private readonly Dictionary _admins = new(); private readonly HashSet _promotedPlayers = new(); public event Action? OnPermsChanged; - public IEnumerable ActiveAdmins => _admins + public IEnumerable ActiveAdmins => _admins .Where(p => p.Value.Data.Active) .Select(p => p.Key); - public IEnumerable AllAdmins => _admins.Select(p => p.Key); + public IEnumerable AllAdmins => _admins.Select(p => p.Key); private readonly AdminCommandPermissions _commandPermissions = new(); private readonly AdminCommandPermissions _toolshedCommandPermissions = new(); @@ -56,7 +56,7 @@ namespace Content.Server.Administration.Managers public AdminData? GetAdminData(ICommonSession session, bool includeDeAdmin = false) { - if (_admins.TryGetValue((IPlayerSession)session, out var reg) && (reg.Data.Active || includeDeAdmin)) + if (_admins.TryGetValue(session, out var reg) && (reg.Data.Active || includeDeAdmin)) { return reg.Data; } @@ -66,13 +66,13 @@ namespace Content.Server.Administration.Managers public AdminData? GetAdminData(EntityUid uid, bool includeDeAdmin = false) { - if (_playerManager.TryGetSessionByEntity(uid, out var session) && session is IPlayerSession playerSession) - return GetAdminData(playerSession, includeDeAdmin); + if (_playerManager.TryGetSessionByEntity(uid, out var session)) + return GetAdminData(session, includeDeAdmin); return null; } - public void DeAdmin(IPlayerSession session) + public void DeAdmin(ICommonSession session) { if (!_admins.TryGetValue(session, out var reg)) { @@ -95,7 +95,7 @@ namespace Content.Server.Administration.Managers UpdateAdminStatus(session); } - public void ReAdmin(IPlayerSession session) + public void ReAdmin(ICommonSession session) { if (!_admins.TryGetValue(session, out var reg)) { @@ -119,7 +119,7 @@ namespace Content.Server.Administration.Managers UpdateAdminStatus(session); } - public async void ReloadAdmin(IPlayerSession player) + public async void ReloadAdmin(ICommonSession player) { var data = await LoadAdminData(player); var curAdmin = _admins.GetValueOrDefault(player); @@ -236,7 +236,7 @@ namespace Content.Server.Administration.Managers _toolshed.ActivePermissionController = this; } - public void PromoteHost(IPlayerSession player) + public void PromoteHost(ICommonSession player) { _promotedPlayers.Add(player.UserId); @@ -250,7 +250,7 @@ namespace Content.Server.Administration.Managers } // NOTE: Also sends commands list for non admins.. - private void UpdateAdminStatus(IPlayerSession session) + private void UpdateAdminStatus(ICommonSession session) { var msg = new MsgUpdateAdminStatus(); @@ -290,7 +290,7 @@ namespace Content.Server.Administration.Managers } } - private async void LoginAdminMaybe(IPlayerSession session) + private async void LoginAdminMaybe(ICommonSession session) { var adminDat = await LoadAdminData(session); if (adminDat == null) @@ -323,7 +323,7 @@ namespace Content.Server.Administration.Managers UpdateAdminStatus(session); } - private async Task<(AdminData dat, int? rankId, bool specialLogin)?> LoadAdminData(IPlayerSession session) + private async Task<(AdminData dat, int? rankId, bool specialLogin)?> LoadAdminData(ICommonSession session) { var promoteHost = IsLocal(session) && _cfg.GetCVar(CCVars.ConsoleLoginLocal) || _promotedPlayers.Contains(session.UserId) @@ -387,7 +387,7 @@ namespace Content.Server.Administration.Managers } } - private static bool IsLocal(IPlayerSession player) + private static bool IsLocal(ICommonSession player) { var ep = player.ConnectedClient.RemoteEndPoint; var addr = ep.Address; @@ -419,7 +419,7 @@ namespace Content.Server.Administration.Managers return false; } - public bool CanCommand(IPlayerSession session, string cmdName) + public bool CanCommand(ICommonSession session, string cmdName) { if (_commandPermissions.AnyCommands.Contains(cmdName)) { @@ -474,7 +474,7 @@ namespace Content.Server.Administration.Managers return true; } - var data = GetAdminData((IPlayerSession)user); + var data = GetAdminData(user); if (data == null) { // Player isn't an admin. @@ -520,32 +520,32 @@ namespace Content.Server.Administration.Managers return (attribs.Length != 0, attribs); } - public bool CanViewVar(IPlayerSession session) + public bool CanViewVar(ICommonSession session) { return CanCommand(session, "vv"); } - public bool CanAdminPlace(IPlayerSession session) + public bool CanAdminPlace(ICommonSession session) { return GetAdminData(session)?.CanAdminPlace() ?? false; } - public bool CanScript(IPlayerSession session) + public bool CanScript(ICommonSession session) { return GetAdminData(session)?.CanScript() ?? false; } - public bool CanAdminMenu(IPlayerSession session) + public bool CanAdminMenu(ICommonSession session) { return GetAdminData(session)?.CanAdminMenu() ?? false; } - public bool CanAdminReloadPrototypes(IPlayerSession session) + public bool CanAdminReloadPrototypes(ICommonSession session) { return GetAdminData(session)?.CanAdminReloadPrototypes() ?? false; } - private void SendPermsChangedEvent(IPlayerSession session) + private void SendPermsChangedEvent(ICommonSession session) { var flags = GetAdminData(session)?.Flags; OnPermsChanged?.Invoke(new AdminPermsChangedEventArgs(session, flags)); @@ -553,7 +553,7 @@ namespace Content.Server.Administration.Managers private sealed class AdminReg { - public readonly IPlayerSession Session; + public readonly ICommonSession Session; public AdminData Data; public int? RankId; @@ -561,7 +561,7 @@ namespace Content.Server.Administration.Managers // Such as console.loginlocal or promotehost public bool IsSpecialLogin; - public AdminReg(IPlayerSession session, AdminData data) + public AdminReg(ICommonSession session, AdminData data) { Data = data; Session = session; diff --git a/Content.Server/Administration/Managers/BanManager.cs b/Content.Server/Administration/Managers/BanManager.cs index 765df17b17..4d51d35576 100644 --- a/Content.Server/Administration/Managers/BanManager.cs +++ b/Content.Server/Administration/Managers/BanManager.cs @@ -15,6 +15,7 @@ using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Utility; @@ -283,7 +284,7 @@ public sealed class BanManager : IBanManager, IPostInjectInit SendRoleBans(player); } - public void SendRoleBans(IPlayerSession pSession) + public void SendRoleBans(ICommonSession pSession) { var roleBans = _cachedRoleBans.GetValueOrDefault(pSession.UserId) ?? new HashSet(); var bans = new MsgRoleBans() diff --git a/Content.Server/Administration/Managers/IAdminManager.cs b/Content.Server/Administration/Managers/IAdminManager.cs index eeed5cc36e..a52ec7b099 100644 --- a/Content.Server/Administration/Managers/IAdminManager.cs +++ b/Content.Server/Administration/Managers/IAdminManager.cs @@ -1,9 +1,8 @@ using Content.Shared.Administration; using Content.Shared.Administration.Managers; -using Robust.Server.Player; +using Robust.Shared.Player; using Robust.Shared.Toolshed; - namespace Content.Server.Administration.Managers { /// @@ -22,12 +21,12 @@ namespace Content.Server.Administration.Managers /// /// This does not include admins that are de-adminned. /// - IEnumerable ActiveAdmins { get; } + IEnumerable ActiveAdmins { get; } /// /// Gets all admins currently on the server, even de-adminned ones. /// - IEnumerable AllAdmins { get; } + IEnumerable AllAdmins { get; } /// /// De-admins an admin temporarily so they are effectively a normal player. @@ -35,18 +34,18 @@ namespace Content.Server.Administration.Managers /// /// De-adminned admins are able to re-admin at any time if they so desire. /// - void DeAdmin(IPlayerSession session); + void DeAdmin(ICommonSession session); /// /// Re-admins a de-adminned admin. /// - void ReAdmin(IPlayerSession session); + void ReAdmin(ICommonSession session); /// /// Re-loads the permissions of an player in case their admin data changed DB-side. /// /// - void ReloadAdmin(IPlayerSession player); + void ReloadAdmin(ICommonSession player); /// /// Reloads admin permissions for all admins with a certain rank. @@ -57,7 +56,7 @@ namespace Content.Server.Administration.Managers void Initialize(); - void PromoteHost(IPlayerSession player); + void PromoteHost(ICommonSession player); bool TryGetCommandFlags(CommandSpec command, out AdminFlags[]? flags); } diff --git a/Content.Server/Administration/Managers/IBanManager.cs b/Content.Server/Administration/Managers/IBanManager.cs index 8458feac8d..dafe3d35bd 100644 --- a/Content.Server/Administration/Managers/IBanManager.cs +++ b/Content.Server/Administration/Managers/IBanManager.cs @@ -2,8 +2,8 @@ using System.Collections.Immutable; using System.Net; using System.Threading.Tasks; using Content.Shared.Database; -using Robust.Server.Player; using Robust.Shared.Network; +using Robust.Shared.Player; namespace Content.Server.Administration.Managers; @@ -55,5 +55,5 @@ public interface IBanManager /// Sends role bans to the target /// /// Player's session - public void SendRoleBans(IPlayerSession pSession); + public void SendRoleBans(ICommonSession pSession); } diff --git a/Content.Server/Administration/Notes/AdminNotesManager.cs b/Content.Server/Administration/Notes/AdminNotesManager.cs index 8a7846663f..0c1e7f3daa 100644 --- a/Content.Server/Administration/Notes/AdminNotesManager.cs +++ b/Content.Server/Administration/Notes/AdminNotesManager.cs @@ -11,7 +11,7 @@ using Content.Shared.Database; using Content.Shared.Players.PlayTimeTracking; using Robust.Shared.Configuration; using Robust.Shared.Network; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.Administration.Notes; diff --git a/Content.Server/Administration/Notes/AdminNotesSystem.cs b/Content.Server/Administration/Notes/AdminNotesSystem.cs index fd9f3f6bfa..f2eb033dca 100644 --- a/Content.Server/Administration/Notes/AdminNotesSystem.cs +++ b/Content.Server/Administration/Notes/AdminNotesSystem.cs @@ -1,13 +1,13 @@ using Content.Server.Administration.Commands; using Content.Server.Chat.Managers; using Content.Server.EUI; -using Content.Shared.Chat; using Content.Shared.Database; using Content.Shared.Verbs; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; +using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Server.Administration.Notes; diff --git a/Content.Server/Administration/Notes/IAdminNotesManager.cs b/Content.Server/Administration/Notes/IAdminNotesManager.cs index ae7133c56d..a726bd11c8 100644 --- a/Content.Server/Administration/Notes/IAdminNotesManager.cs +++ b/Content.Server/Administration/Notes/IAdminNotesManager.cs @@ -2,7 +2,7 @@ using System.Threading.Tasks; using Content.Server.Database; using Content.Shared.Administration.Notes; using Content.Shared.Database; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.Administration.Notes; diff --git a/Content.Server/Administration/QuickDialogSystem.OpenDialog.cs b/Content.Server/Administration/QuickDialogSystem.OpenDialog.cs index 521bee776f..fb013a88ad 100644 --- a/Content.Server/Administration/QuickDialogSystem.OpenDialog.cs +++ b/Content.Server/Administration/QuickDialogSystem.OpenDialog.cs @@ -1,6 +1,6 @@ using Content.Shared.Administration; using JetBrains.Annotations; -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Administration; @@ -16,7 +16,7 @@ public sealed partial class QuickDialogSystem /// The action to execute upon the dialog being cancelled. /// Type of the input. [PublicAPI] - public void OpenDialog(IPlayerSession session, string title, string prompt, Action okAction, + public void OpenDialog(ICommonSession session, string title, string prompt, Action okAction, Action? cancelAction = null) { OpenDialogInternal( @@ -53,7 +53,7 @@ public sealed partial class QuickDialogSystem /// Type of the first input. /// Type of the second input. [PublicAPI] - public void OpenDialog(IPlayerSession session, string title, string prompt1, string prompt2, + public void OpenDialog(ICommonSession session, string title, string prompt1, string prompt2, Action okAction, Action? cancelAction = null) { OpenDialogInternal( @@ -96,7 +96,7 @@ public sealed partial class QuickDialogSystem /// Type of the second input. /// Type of the third input. [PublicAPI] - public void OpenDialog(IPlayerSession session, string title, string prompt1, string prompt2, + public void OpenDialog(ICommonSession session, string title, string prompt1, string prompt2, string prompt3, Action okAction, Action? cancelAction = null) { OpenDialogInternal( @@ -142,7 +142,7 @@ public sealed partial class QuickDialogSystem /// Type of the third input. /// Type of the fourth input. [PublicAPI] - public void OpenDialog(IPlayerSession session, string title, string prompt1, string prompt2, + public void OpenDialog(ICommonSession session, string title, string prompt1, string prompt2, string prompt3, string prompt4, Action okAction, Action? cancelAction = null) { OpenDialogInternal( diff --git a/Content.Server/Administration/QuickDialogSystem.cs b/Content.Server/Administration/QuickDialogSystem.cs index 51b8cf79c2..96423e5223 100644 --- a/Content.Server/Administration/QuickDialogSystem.cs +++ b/Content.Server/Administration/QuickDialogSystem.cs @@ -1,12 +1,9 @@ -using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.CodeAnalysis; using Content.Shared.Administration; -using Microsoft.CodeAnalysis.CSharp.Syntax; using Robust.Server.Player; using Robust.Shared.Enums; using Robust.Shared.Network; using Robust.Shared.Player; -using Robust.Shared.Serialization.TypeSerializers.Interfaces; namespace Content.Server.Administration; @@ -87,7 +84,7 @@ public sealed partial class QuickDialogSystem : EntitySystem _openDialogsByUser.Remove(user); } - private void OpenDialogInternal(IPlayerSession session, string title, List entries, QuickDialogButtonFlag buttons, Action okAction, Action cancelAction) + private void OpenDialogInternal(ICommonSession session, string title, List entries, QuickDialogButtonFlag buttons, Action okAction, Action cancelAction) { var did = GetDialogId(); RaiseNetworkEvent( diff --git a/Content.Server/Administration/Systems/AdminSystem.cs b/Content.Server/Administration/Systems/AdminSystem.cs index 66f7a8999b..feabaa2aad 100644 --- a/Content.Server/Administration/Systems/AdminSystem.cs +++ b/Content.Server/Administration/Systems/AdminSystem.cs @@ -109,7 +109,7 @@ namespace Content.Server.Administration.Systems } } - public void UpdatePlayerList(IPlayerSession player) + public void UpdatePlayerList(ICommonSession player) { _playerList[player.UserId] = GetPlayerInfo(player.Data, player); @@ -203,7 +203,7 @@ namespace Content.Server.Administration.Systems UpdatePanicBunker(); } - private void SendFullPlayerList(IPlayerSession playerSession) + private void SendFullPlayerList(ICommonSession playerSession) { var ev = new FullPlayerListEvent(); @@ -212,7 +212,7 @@ namespace Content.Server.Administration.Systems RaiseNetworkEvent(ev, playerSession.ConnectedClient); } - private PlayerInfo GetPlayerInfo(IPlayerData data, IPlayerSession? session) + private PlayerInfo GetPlayerInfo(SessionData data, ICommonSession? session) { var name = data.UserName; var entityName = string.Empty; @@ -326,7 +326,7 @@ namespace Content.Server.Administration.Systems /// chat messages and showing a popup to other players. /// Their items are dropped on the ground. /// - public void Erase(IPlayerSession player) + public void Erase(ICommonSession player) { var entity = player.AttachedEntity; _chat.DeleteMessagesBy(player); diff --git a/Content.Server/Administration/Systems/AdminTestArenaSystem.cs b/Content.Server/Administration/Systems/AdminTestArenaSystem.cs index e65acf571c..e3671bcdfb 100644 --- a/Content.Server/Administration/Systems/AdminTestArenaSystem.cs +++ b/Content.Server/Administration/Systems/AdminTestArenaSystem.cs @@ -1,8 +1,8 @@ using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Map; using Robust.Shared.Map.Components; using Robust.Shared.Network; +using Robust.Shared.Player; namespace Content.Server.Administration.Systems; @@ -20,7 +20,7 @@ public sealed class AdminTestArenaSystem : EntitySystem public Dictionary ArenaMap { get; private set; } = new(); public Dictionary ArenaGrid { get; private set; } = new(); - public (EntityUid Map, EntityUid? Grid) AssertArenaLoaded(IPlayerSession admin) + public (EntityUid Map, EntityUid? Grid) AssertArenaLoaded(ICommonSession admin) { if (ArenaMap.TryGetValue(admin.UserId, out var arenaMap) && !Deleted(arenaMap) && !Terminating(arenaMap)) { diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.cs b/Content.Server/Administration/Systems/AdminVerbSystem.cs index c7e23374a3..bc065745f5 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.cs @@ -6,6 +6,7 @@ using Content.Server.Disposal.Tube; using Content.Server.Disposal.Tube.Components; using Content.Server.EUI; using Content.Server.Ghost.Roles; +using Content.Server.Mind; using Content.Server.Mind.Commands; using Content.Server.Prayer; using Content.Server.Xenoarchaeology.XenoArtifacts; @@ -18,17 +19,15 @@ using Content.Shared.Database; using Content.Shared.Examine; using Content.Shared.GameTicking; using Content.Shared.Inventory; -using Content.Shared.Mind; using Content.Shared.Mind.Components; using Content.Shared.Popups; using Content.Shared.Verbs; using Robust.Server.Console; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; using Robust.Shared.Map.Components; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Timing; using Robust.Shared.Toolshed; @@ -56,7 +55,7 @@ namespace Content.Server.Administration.Systems [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; [Dependency] private readonly PrayerSystem _prayerSystem = default!; [Dependency] private readonly EuiManager _eui = default!; - [Dependency] private readonly SharedMindSystem _mindSystem = default!; + [Dependency] private readonly MindSystem _mindSystem = default!; [Dependency] private readonly ToolshedManager _toolshed = default!; [Dependency] private readonly RejuvenateSystem _rejuvenate = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; @@ -277,12 +276,7 @@ namespace Content.Server.Administration.Systems // TODO VERB ICON control mob icon Act = () => { - MakeSentientCommand.MakeSentient(args.Target, EntityManager); - - if (!_minds.TryGetMind(player, out var mindId, out var mind)) - return; - - _mindSystem.TransferTo(mindId, args.Target, ghostCheckOverride: true, mind: mind); + _mindSystem.ControlMob(args.User, args.Target); }, Impact = LogImpact.High, ConfirmationPopup = true @@ -358,7 +352,7 @@ namespace Content.Server.Administration.Systems var message = ExamineSystemShared.InRangeUnOccluded(args.User, args.Target) ? Loc.GetString("in-range-unoccluded-verb-on-activate-not-occluded") : Loc.GetString("in-range-unoccluded-verb-on-activate-occluded"); - + _popup.PopupEntity(message, args.Target, args.User); } }; @@ -432,7 +426,7 @@ namespace Content.Server.Administration.Systems } } - public void OpenEditSolutionsEui(IPlayerSession session, EntityUid uid) + public void OpenEditSolutionsEui(ICommonSession session, EntityUid uid) { if (session.AttachedEntity == null) return; diff --git a/Content.Server/Administration/Systems/BwoinkSystem.cs b/Content.Server/Administration/Systems/BwoinkSystem.cs index 98e5af1126..31ef285a88 100644 --- a/Content.Server/Administration/Systems/BwoinkSystem.cs +++ b/Content.Server/Administration/Systems/BwoinkSystem.cs @@ -17,6 +17,7 @@ using Robust.Shared; using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -119,7 +120,7 @@ namespace Content.Server.Administration.Systems _typingUpdateTimestamps[args.SenderSession.UserId] = (_timing.RealTime, msg.Typing); // Non-admins can only ever type on their own ahelp, guard against fake messages - var isAdmin = _adminManager.GetAdminData((IPlayerSession) args.SenderSession)?.HasFlag(AdminFlags.Adminhelp) ?? false; + var isAdmin = _adminManager.GetAdminData(args.SenderSession)?.HasFlag(AdminFlags.Adminhelp) ?? false; var channel = isAdmin ? msg.Channel : args.SenderSession.UserId; var update = new BwoinkPlayerTypingUpdated(channel, args.SenderSession.Name, msg.Typing); @@ -376,7 +377,7 @@ namespace Content.Server.Administration.Systems protected override void OnBwoinkTextMessage(BwoinkTextMessage message, EntitySessionEventArgs eventArgs) { base.OnBwoinkTextMessage(message, eventArgs); - var senderSession = (IPlayerSession) eventArgs.SenderSession; + var senderSession = eventArgs.SenderSession; // TODO: Sanitize text? // Confirm that this person is actually allowed to send a message here. diff --git a/Content.Server/Administration/Toolshed/AdminsCommand.cs b/Content.Server/Administration/Toolshed/AdminsCommand.cs index aa82e0f1d9..1d64f748fd 100644 --- a/Content.Server/Administration/Toolshed/AdminsCommand.cs +++ b/Content.Server/Administration/Toolshed/AdminsCommand.cs @@ -1,6 +1,6 @@ using Content.Server.Administration.Managers; using Content.Shared.Administration; -using Robust.Server.Player; +using Robust.Shared.Player; using Robust.Shared.Toolshed; namespace Content.Server.Administration.Toolshed; @@ -11,13 +11,13 @@ public sealed class AdminsCommand : ToolshedCommand [Dependency] private readonly IAdminManager _admin = default!; [CommandImplementation("active")] - public IEnumerable Active() + public IEnumerable Active() { return _admin.ActiveAdmins; } [CommandImplementation("all")] - public IEnumerable All() + public IEnumerable All() { return _admin.AllAdmins; } diff --git a/Content.Server/Afk/AFKSystem.cs b/Content.Server/Afk/AFKSystem.cs index 0938f45f73..f634a415dc 100644 --- a/Content.Server/Afk/AFKSystem.cs +++ b/Content.Server/Afk/AFKSystem.cs @@ -1,4 +1,3 @@ -using System.Linq; using Content.Server.Afk.Events; using Content.Server.GameTicking; using Content.Shared.CCVar; @@ -24,7 +23,7 @@ public sealed class AFKSystem : EntitySystem private float _checkDelay; private TimeSpan _checkTime; - private readonly HashSet _afkPlayers = new(); + private readonly HashSet _afkPlayers = new(); public override void Initialize() { @@ -73,11 +72,9 @@ public sealed class AFKSystem : EntitySystem _checkTime = _timing.CurTime + TimeSpan.FromSeconds(_checkDelay); - foreach (var session in Filter.GetAllPlayers()) + foreach (var pSession in Filter.GetAllPlayers()) { - if (session.Status != SessionStatus.InGame) continue; - - var pSession = (IPlayerSession) session; + if (pSession.Status != SessionStatus.InGame) continue; var isAfk = _afkManager.IsAfk(pSession); if (isAfk && _afkPlayers.Add(pSession)) diff --git a/Content.Server/Afk/AfkManager.cs b/Content.Server/Afk/AfkManager.cs index 24cd1e28ce..52dc7715df 100644 --- a/Content.Server/Afk/AfkManager.cs +++ b/Content.Server/Afk/AfkManager.cs @@ -5,6 +5,7 @@ using Robust.Shared.Configuration; using Robust.Shared.Console; using Robust.Shared.Enums; using Robust.Shared.Input; +using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.Afk @@ -20,13 +21,13 @@ namespace Content.Server.Afk /// /// The player to check. /// True if the player is AFK, false otherwise. - bool IsAfk(IPlayerSession player); + bool IsAfk(ICommonSession player); /// /// Resets AFK status for the player as if they just did an action and are definitely not AFK. /// /// The player to set AFK status for. - void PlayerDidAction(IPlayerSession player); + void PlayerDidAction(ICommonSession player); void Initialize(); } @@ -40,7 +41,7 @@ namespace Content.Server.Afk [Dependency] private readonly IConfigurationManager _cfg = default!; [Dependency] private readonly IConsoleHost _consoleHost = default!; - private readonly Dictionary _lastActionTimes = new(); + private readonly Dictionary _lastActionTimes = new(); public void Initialize() { @@ -55,7 +56,7 @@ namespace Content.Server.Afk HandleInputCmd); } - public void PlayerDidAction(IPlayerSession player) + public void PlayerDidAction(ICommonSession player) { if (player.Status == SessionStatus.Disconnected) // Make sure we don't re-add to the dictionary if the player is disconnected now. @@ -64,7 +65,7 @@ namespace Content.Server.Afk _lastActionTimes[player] = _gameTiming.RealTime; } - public bool IsAfk(IPlayerSession player) + public bool IsAfk(ICommonSession player) { if (!_lastActionTimes.TryGetValue(player, out var time)) // Some weird edge case like disconnected clients. Just say true I guess. @@ -87,13 +88,13 @@ namespace Content.Server.Afk private void ConsoleHostOnAnyCommandExecuted(IConsoleShell shell, string commandname, string argstr, string[] args) { - if (shell.Player is IPlayerSession player) + if (shell.Player is { } player) PlayerDidAction(player); } private void HandleInputCmd(FullInputCmdMessage msg, EntitySessionEventArgs args) { - PlayerDidAction((IPlayerSession) args.SenderSession); + PlayerDidAction(args.SenderSession); } } } diff --git a/Content.Server/Afk/Events/AFKEvent.cs b/Content.Server/Afk/Events/AFKEvent.cs index 6adb950e47..ee9d548043 100644 --- a/Content.Server/Afk/Events/AFKEvent.cs +++ b/Content.Server/Afk/Events/AFKEvent.cs @@ -1,4 +1,4 @@ -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Afk.Events; @@ -8,9 +8,9 @@ namespace Content.Server.Afk.Events; [ByRefEvent] public readonly struct AFKEvent { - public readonly IPlayerSession Session; + public readonly ICommonSession Session; - public AFKEvent(IPlayerSession playerSession) + public AFKEvent(ICommonSession playerSession) { Session = playerSession; } diff --git a/Content.Server/Afk/Events/UnAFKEvent.cs b/Content.Server/Afk/Events/UnAFKEvent.cs index 3dd034583c..0983c256f0 100644 --- a/Content.Server/Afk/Events/UnAFKEvent.cs +++ b/Content.Server/Afk/Events/UnAFKEvent.cs @@ -1,4 +1,4 @@ -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Afk.Events; @@ -8,9 +8,9 @@ namespace Content.Server.Afk.Events; [ByRefEvent] public readonly struct UnAFKEvent { - public readonly IPlayerSession Session; + public readonly ICommonSession Session; - public UnAFKEvent(IPlayerSession playerSession) + public UnAFKEvent(ICommonSession playerSession) { Session = playerSession; } diff --git a/Content.Server/Alert/Commands/ClearAlert.cs b/Content.Server/Alert/Commands/ClearAlert.cs index e43f06413c..1759612702 100644 --- a/Content.Server/Alert/Commands/ClearAlert.cs +++ b/Content.Server/Alert/Commands/ClearAlert.cs @@ -2,7 +2,6 @@ using Content.Server.Administration; using Content.Server.Commands; using Content.Shared.Administration; using Content.Shared.Alert; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Alert.Commands @@ -16,7 +15,7 @@ namespace Content.Server.Alert.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player?.AttachedEntity == null) { shell.WriteLine("You don't have an entity."); diff --git a/Content.Server/Alert/Commands/ShowAlert.cs b/Content.Server/Alert/Commands/ShowAlert.cs index edb634b546..11901e9af0 100644 --- a/Content.Server/Alert/Commands/ShowAlert.cs +++ b/Content.Server/Alert/Commands/ShowAlert.cs @@ -2,7 +2,6 @@ using Content.Server.Administration; using Content.Server.Commands; using Content.Shared.Administration; using Content.Shared.Alert; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Alert.Commands @@ -16,7 +15,7 @@ namespace Content.Server.Alert.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player?.AttachedEntity == null) { shell.WriteLine("You cannot run this from the server or without an attached entity."); diff --git a/Content.Server/AlertLevel/Commands/SetAlertLevelCommand.cs b/Content.Server/AlertLevel/Commands/SetAlertLevelCommand.cs index 009a8b5f23..2c432a2419 100644 --- a/Content.Server/AlertLevel/Commands/SetAlertLevelCommand.cs +++ b/Content.Server/AlertLevel/Commands/SetAlertLevelCommand.cs @@ -3,7 +3,6 @@ using Content.Server.Administration; using Content.Server.Station.Systems; using Content.Shared.Administration; using JetBrains.Annotations; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.AlertLevel.Commands @@ -19,7 +18,7 @@ namespace Content.Server.AlertLevel.Commands public CompletionResult GetCompletion(IConsoleShell shell, string[] args) { var levelNames = new string[] {}; - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player?.AttachedEntity != null) { var stationUid = EntitySystem.Get().GetOwningStation(player.AttachedEntity.Value); @@ -54,7 +53,7 @@ namespace Content.Server.AlertLevel.Commands return; } - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player?.AttachedEntity == null) { shell.WriteLine(Loc.GetString("shell-only-players-can-run-this-command")); diff --git a/Content.Server/Antag/AntagSelectionSystem.cs b/Content.Server/Antag/AntagSelectionSystem.cs index 5e323f5ab8..737b723d39 100644 --- a/Content.Server/Antag/AntagSelectionSystem.cs +++ b/Content.Server/Antag/AntagSelectionSystem.cs @@ -22,6 +22,7 @@ using Content.Server.Station.Systems; using Content.Server.Shuttles.Systems; using Content.Shared.Mobs; using Robust.Server.Containers; +using Robust.Shared.Player; using Robust.Shared.Prototypes; namespace Content.Server.Antag; @@ -88,9 +89,9 @@ public sealed class AntagSelectionSystem : GameRuleSystem out List chosen, bool includeHeads = false) { - var allPlayers = _playerSystem.ServerSessions.ToList(); - var playerList = new List(); - var prefList = new List(); + var allPlayers = _playerSystem.Sessions.ToList(); + var playerList = new List(); + var prefList = new List(); chosen = new List(); foreach (var player in allPlayers) { @@ -116,7 +117,7 @@ public sealed class AntagSelectionSystem : GameRuleSystem var antags = Math.Clamp(allPlayers.Count / antagsPerPlayer, 1, maxAntags); for (var antag = 0; antag < antags; antag++) { - IPlayerSession chosenPlayer = null!; + ICommonSession? chosenPlayer = null; if (prefList.Count == 0) { if (playerList.Count == 0) diff --git a/Content.Server/Arcade/BlockGame/BlockGame.Ui.cs b/Content.Server/Arcade/BlockGame/BlockGame.Ui.cs index 92a96ea226..ef69600783 100644 --- a/Content.Server/Arcade/BlockGame/BlockGame.Ui.cs +++ b/Content.Server/Arcade/BlockGame/BlockGame.Ui.cs @@ -1,6 +1,6 @@ using Content.Shared.Arcade; -using Robust.Server.Player; using System.Linq; +using Robust.Shared.Player; namespace Content.Server.Arcade.BlockGame; @@ -166,7 +166,7 @@ public sealed partial class BlockGame /// /// The message to send to a specific player/spectator. /// The target recipient. - private void SendMessage(BoundUserInterfaceMessage message, IPlayerSession session) + private void SendMessage(BoundUserInterfaceMessage message, ICommonSession session) { if (_uiSystem.TryGetUi(_owner, BlockGameUiKey.Key, out var bui)) _uiSystem.TrySendUiMessage(bui, message, session); @@ -176,7 +176,7 @@ public sealed partial class BlockGame /// Handles sending the current state of the game to a player that has just opened the UI. /// /// The target recipient. - public void UpdateNewPlayerUI(IPlayerSession session) + public void UpdateNewPlayerUI(ICommonSession session) { if (_gameOver) { @@ -209,7 +209,7 @@ public sealed partial class BlockGame /// Handles broadcasting the full player-visible game state to a specific player/spectator. /// /// The target recipient. - private void FullUpdate(IPlayerSession session) + private void FullUpdate(ICommonSession session) { UpdateFieldUI(session); SendNextPieceUpdate(session); @@ -235,7 +235,7 @@ public sealed partial class BlockGame /// Handles broadcasting the current location of all of the blocks in the playfield + the active piece to a specific player/spectator. /// /// The target recipient. - public void UpdateFieldUI(IPlayerSession session) + public void UpdateFieldUI(ICommonSession session) { if (!Started) return; @@ -283,7 +283,7 @@ public sealed partial class BlockGame /// Broadcasts the state of the next queued piece to a specific viewer. /// /// The target recipient. - private void SendNextPieceUpdate(IPlayerSession session) + private void SendNextPieceUpdate(ICommonSession session) { SendMessage(new BlockGameMessages.BlockGameVisualUpdateMessage(NextPiece.BlocksForPreview(), BlockGameMessages.BlockGameVisualType.NextBlock), session); } @@ -303,7 +303,7 @@ public sealed partial class BlockGame /// Broadcasts the state of the currently held piece to a specific viewer. /// /// The target recipient. - private void SendHoldPieceUpdate(IPlayerSession session) + private void SendHoldPieceUpdate(ICommonSession session) { if (HeldPiece.HasValue) SendMessage(new BlockGameMessages.BlockGameVisualUpdateMessage(HeldPiece.Value.BlocksForPreview(), BlockGameMessages.BlockGameVisualType.HoldBlock), session); @@ -323,7 +323,7 @@ public sealed partial class BlockGame /// Broadcasts the current game level to a specific viewer. /// /// The target recipient. - private void SendLevelUpdate(IPlayerSession session) + private void SendLevelUpdate(ICommonSession session) { SendMessage(new BlockGameMessages.BlockGameLevelUpdateMessage(Level), session); } @@ -340,7 +340,7 @@ public sealed partial class BlockGame /// Broadcasts the current game score to a specific viewer. /// /// The target recipient. - private void SendPointsUpdate(IPlayerSession session) + private void SendPointsUpdate(ICommonSession session) { SendMessage(new BlockGameMessages.BlockGameScoreUpdateMessage(Points), session); } @@ -357,7 +357,7 @@ public sealed partial class BlockGame /// Broadcasts the current game high score positions to a specific viewer. /// /// The target recipient. - private void SendHighscoreUpdate(IPlayerSession session) + private void SendHighscoreUpdate(ICommonSession session) { SendMessage(new BlockGameMessages.BlockGameHighScoreUpdateMessage(_arcadeSystem.GetLocalHighscores(), _arcadeSystem.GetGlobalHighscores()), session); } diff --git a/Content.Server/Arcade/BlockGame/BlockGameArcadeComponent.cs b/Content.Server/Arcade/BlockGame/BlockGameArcadeComponent.cs index 268d5be4d2..5613d91544 100644 --- a/Content.Server/Arcade/BlockGame/BlockGameArcadeComponent.cs +++ b/Content.Server/Arcade/BlockGame/BlockGameArcadeComponent.cs @@ -1,4 +1,4 @@ -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Arcade.BlockGame; @@ -13,10 +13,10 @@ public sealed partial class BlockGameArcadeComponent : Component /// /// The player currently playing the active session of NT-BG. /// - public IPlayerSession? Player = null; + public ICommonSession? Player = null; /// /// The players currently viewing (but not playing) the active session of NT-BG. /// - public readonly List Spectators = new(); + public readonly List Spectators = new(); } diff --git a/Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs b/Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs index dac29accc9..ecc5bfd3e2 100644 --- a/Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs +++ b/Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs @@ -2,7 +2,7 @@ using Content.Server.Power.Components; using Content.Server.UserInterface; using Content.Shared.Arcade; using Robust.Server.GameObjects; -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Arcade.BlockGame; @@ -30,7 +30,7 @@ public sealed class BlockGameArcadeSystem : EntitySystem } } - private void UpdatePlayerStatus(EntityUid uid, IPlayerSession session, PlayerBoundUserInterface? bui = null, BlockGameArcadeComponent? blockGame = null) + private void UpdatePlayerStatus(EntityUid uid, ICommonSession session, PlayerBoundUserInterface? bui = null, BlockGameArcadeComponent? blockGame = null) { if (!Resolve(uid, ref blockGame)) return; @@ -67,7 +67,7 @@ public sealed class BlockGameArcadeSystem : EntitySystem private void OnAfterUiClose(EntityUid uid, BlockGameArcadeComponent component, BoundUIClosedEvent args) { - if (args.Session is not IPlayerSession session) + if (args.Session is not { } session) return; if (component.Player != session) diff --git a/Content.Server/Atmos/Commands/DeleteGasCommand.cs b/Content.Server/Atmos/Commands/DeleteGasCommand.cs index 0f0c399b11..9e7594c024 100644 --- a/Content.Server/Atmos/Commands/DeleteGasCommand.cs +++ b/Content.Server/Atmos/Commands/DeleteGasCommand.cs @@ -2,7 +2,6 @@ using Content.Server.Administration; using Content.Server.Atmos.EntitySystems; using Content.Shared.Administration; using Content.Shared.Atmos; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; @@ -20,7 +19,7 @@ namespace Content.Server.Atmos.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; EntityUid? gridId; Gas? gas = null; diff --git a/Content.Server/Atmos/Commands/ShowAtmosCommand.cs b/Content.Server/Atmos/Commands/ShowAtmosCommand.cs index 5ad73ec906..263ef947d0 100644 --- a/Content.Server/Atmos/Commands/ShowAtmosCommand.cs +++ b/Content.Server/Atmos/Commands/ShowAtmosCommand.cs @@ -1,7 +1,6 @@ using Content.Server.Administration; using Content.Server.Atmos.EntitySystems; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Atmos.Commands @@ -15,7 +14,7 @@ namespace Content.Server.Atmos.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("You must be a player to use this command."); diff --git a/Content.Server/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs b/Content.Server/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs index 34f558a252..90edd4caed 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs @@ -10,6 +10,7 @@ using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Map; using Robust.Shared.Map.Components; +using Robust.Shared.Player; namespace Content.Server.Atmos.EntitySystems { @@ -27,7 +28,7 @@ namespace Content.Server.Atmos.EntitySystems /// To modify it see and /// . /// - private readonly HashSet _playerObservers = new(); + private readonly HashSet _playerObservers = new(); /// /// Overlay update ticks per second. @@ -48,17 +49,17 @@ namespace Content.Server.Atmos.EntitySystems _playerManager.PlayerStatusChanged -= OnPlayerStatusChanged; } - public bool AddObserver(IPlayerSession observer) + public bool AddObserver(ICommonSession observer) { return _playerObservers.Add(observer); } - public bool HasObserver(IPlayerSession observer) + public bool HasObserver(ICommonSession observer) { return _playerObservers.Contains(observer); } - public bool RemoveObserver(IPlayerSession observer) + public bool RemoveObserver(ICommonSession observer) { if (!_playerObservers.Remove(observer)) { @@ -76,7 +77,7 @@ namespace Content.Server.Atmos.EntitySystems /// /// The observer to toggle. /// true if added, false if removed. - public bool ToggleObserver(IPlayerSession observer) + public bool ToggleObserver(ICommonSession observer) { if (HasObserver(observer)) { diff --git a/Content.Server/Atmos/EntitySystems/GasTankSystem.cs b/Content.Server/Atmos/EntitySystems/GasTankSystem.cs index df867d3516..17715435b2 100644 --- a/Content.Server/Atmos/EntitySystems/GasTankSystem.cs +++ b/Content.Server/Atmos/EntitySystems/GasTankSystem.cs @@ -12,7 +12,6 @@ using Content.Shared.Toggleable; using Content.Shared.Verbs; using JetBrains.Annotations; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Audio; using Robust.Shared.Containers; using Robust.Shared.Physics.Systems; @@ -60,12 +59,6 @@ namespace Content.Server.Atmos.EntitySystems private void OnGasTankToggleInternals(Entity ent, ref GasTankToggleInternalsMessage args) { - if (args.Session is not IPlayerSession playerSession || - playerSession.AttachedEntity == null) - { - return; - } - ToggleInternals(ent); } diff --git a/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs b/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs index c229ef50c9..b0e8cf71c7 100644 --- a/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs +++ b/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs @@ -16,6 +16,7 @@ using Robust.Shared; using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Map; +using Robust.Shared.Player; using Robust.Shared.Threading; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -35,7 +36,7 @@ namespace Content.Server.Atmos.EntitySystems [Robust.Shared.IoC.Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!; [Robust.Shared.IoC.Dependency] private readonly ChunkingSystem _chunkingSys = default!; - private readonly Dictionary>> _lastSentChunks = new(); + private readonly Dictionary>> _lastSentChunks = new(); // Oh look its more duplicated decal system code! private ObjectPool> _chunkIndexPool = @@ -286,12 +287,12 @@ namespace Content.Server.Atmos.EntitySystems // Now we'll go through each player, then through each chunk in range of that player checking if the player is still in range // If they are, check if they need the new data to send (i.e. if there's an overlay for the gas). // Afterwards we reset all the chunk data for the next time we tick. - var players = _playerManager.ServerSessions.Where(x => x.Status == SessionStatus.InGame).ToArray(); + var players = _playerManager.Sessions.Where(x => x.Status == SessionStatus.InGame).ToArray(); var opts = new ParallelOptions { MaxDegreeOfParallelism = _parMan.ParallelProcessCount }; Parallel.ForEach(players, opts, p => UpdatePlayer(p, curTick)); } - private void UpdatePlayer(IPlayerSession playerSession, GameTick curTick) + private void UpdatePlayer(ICommonSession playerSession, GameTick curTick) { var chunksInRange = _chunkingSys.GetChunksForSession(playerSession, ChunkSize, _chunkIndexPool, _chunkViewerPool); var previouslySent = _lastSentChunks[playerSession]; diff --git a/Content.Server/Body/Commands/AddHandCommand.cs b/Content.Server/Body/Commands/AddHandCommand.cs index 308295c06c..655d0c88f9 100644 --- a/Content.Server/Body/Commands/AddHandCommand.cs +++ b/Content.Server/Body/Commands/AddHandCommand.cs @@ -4,7 +4,6 @@ using Content.Server.Body.Systems; using Content.Shared.Administration; using Content.Shared.Body.Components; using Content.Shared.Body.Part; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -27,7 +26,7 @@ namespace Content.Server.Body.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; EntityUid entity; EntityUid hand; diff --git a/Content.Server/Body/Commands/AttachBodyPartCommand.cs b/Content.Server/Body/Commands/AttachBodyPartCommand.cs index 267b520808..24604b88b7 100644 --- a/Content.Server/Body/Commands/AttachBodyPartCommand.cs +++ b/Content.Server/Body/Commands/AttachBodyPartCommand.cs @@ -1,10 +1,8 @@ -using System.Linq; using Content.Server.Administration; using Content.Server.Body.Systems; using Content.Shared.Administration; using Content.Shared.Body.Components; using Content.Shared.Body.Part; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Body.Commands @@ -20,7 +18,7 @@ namespace Content.Server.Body.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; EntityUid bodyId; EntityUid? partUid; diff --git a/Content.Server/Body/Commands/DestroyMechanismCommand.cs b/Content.Server/Body/Commands/DestroyMechanismCommand.cs index 6ad0631150..3aa28f4072 100644 --- a/Content.Server/Body/Commands/DestroyMechanismCommand.cs +++ b/Content.Server/Body/Commands/DestroyMechanismCommand.cs @@ -2,7 +2,6 @@ using Content.Server.Administration; using Content.Server.Body.Systems; using Content.Shared.Administration; using Content.Shared.Body.Components; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Random; @@ -17,7 +16,7 @@ namespace Content.Server.Body.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("Only a player can run this command."); diff --git a/Content.Server/Body/Commands/RemoveHandCommand.cs b/Content.Server/Body/Commands/RemoveHandCommand.cs index 729db4bc44..4a2956ae7a 100644 --- a/Content.Server/Body/Commands/RemoveHandCommand.cs +++ b/Content.Server/Body/Commands/RemoveHandCommand.cs @@ -4,7 +4,6 @@ using Content.Server.Body.Systems; using Content.Shared.Administration; using Content.Shared.Body.Components; using Content.Shared.Body.Part; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Random; @@ -22,7 +21,7 @@ namespace Content.Server.Body.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("Only a player can run this command."); diff --git a/Content.Server/Body/Systems/BodySystem.cs b/Content.Server/Body/Systems/BodySystem.cs index f2f848c488..242b02d78c 100644 --- a/Content.Server/Body/Systems/BodySystem.cs +++ b/Content.Server/Body/Systems/BodySystem.cs @@ -116,7 +116,7 @@ public sealed class BodySystem : SharedBodySystem if (!Resolve(bodyId, ref body, false)) return new HashSet(); - if (LifeStage(bodyId) >= EntityLifeStage.Terminating || EntityManager.IsQueuedForDeletion(bodyId)) + if (TerminatingOrDeleted(bodyId) || EntityManager.IsQueuedForDeletion(bodyId)) return new HashSet(); var xform = Transform(bodyId); diff --git a/Content.Server/Cargo/Systems/CargoSystem.Orders.cs b/Content.Server/Cargo/Systems/CargoSystem.Orders.cs index d9327b5150..f659357ad3 100644 --- a/Content.Server/Cargo/Systems/CargoSystem.Orders.cs +++ b/Content.Server/Cargo/Systems/CargoSystem.Orders.cs @@ -8,7 +8,7 @@ using Content.Shared.Cargo.Events; using Content.Shared.Cargo.Prototypes; using Content.Shared.Database; using Robust.Shared.Map; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Utility; diff --git a/Content.Server/CartridgeLoader/CartridgeLoaderSystem.cs b/Content.Server/CartridgeLoader/CartridgeLoaderSystem.cs index 9f7acce4fd..02b2eee771 100644 --- a/Content.Server/CartridgeLoader/CartridgeLoaderSystem.cs +++ b/Content.Server/CartridgeLoader/CartridgeLoaderSystem.cs @@ -6,9 +6,9 @@ using Content.Shared.CartridgeLoader; using Content.Shared.Interaction; using Robust.Server.Containers; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Containers; using Robust.Shared.Map; +using Robust.Shared.Player; namespace Content.Server.CartridgeLoader; @@ -98,7 +98,7 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem /// and use this method to update its state so the cartridge loaders state can be added to it. /// /// - public void UpdateUiState(EntityUid loaderUid, IPlayerSession? session, CartridgeLoaderComponent? loader) + public void UpdateUiState(EntityUid loaderUid, ICommonSession? session, CartridgeLoaderComponent? loader) { if (!Resolve(loaderUid, ref loader)) return; @@ -122,7 +122,7 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem /// This method is called "UpdateCartridgeUiState" but cartridges and a programs are the same. A cartridge is just a program as a visible item. /// /// - public void UpdateCartridgeUiState(EntityUid loaderUid, BoundUserInterfaceState state, IPlayerSession? session = default!, CartridgeLoaderComponent? loader = default!) + public void UpdateCartridgeUiState(EntityUid loaderUid, BoundUserInterfaceState state, ICommonSession? session = default!, CartridgeLoaderComponent? loader = default!) { if (!Resolve(loaderUid, ref loader)) return; diff --git a/Content.Server/Chat/Commands/AdminChatCommand.cs b/Content.Server/Chat/Commands/AdminChatCommand.cs index 8aa95ffee1..979051e9d3 100644 --- a/Content.Server/Chat/Commands/AdminChatCommand.cs +++ b/Content.Server/Chat/Commands/AdminChatCommand.cs @@ -1,7 +1,6 @@ using Content.Server.Administration; using Content.Server.Chat.Managers; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Chat.Commands @@ -15,7 +14,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = (IPlayerSession?) shell.Player; + var player = shell.Player; if (player == null) { diff --git a/Content.Server/Chat/Commands/LOOCCommand.cs b/Content.Server/Chat/Commands/LOOCCommand.cs index a897a0b2bf..9e16193fc3 100644 --- a/Content.Server/Chat/Commands/LOOCCommand.cs +++ b/Content.Server/Chat/Commands/LOOCCommand.cs @@ -1,6 +1,5 @@ using Content.Server.Chat.Systems; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; @@ -15,7 +14,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError("This command cannot be run from the server."); return; diff --git a/Content.Server/Chat/Commands/MeCommand.cs b/Content.Server/Chat/Commands/MeCommand.cs index 36f86cf4d6..e763d5656e 100644 --- a/Content.Server/Chat/Commands/MeCommand.cs +++ b/Content.Server/Chat/Commands/MeCommand.cs @@ -1,6 +1,5 @@ using Content.Server.Chat.Systems; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; @@ -15,7 +14,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError("This command cannot be run from the server."); return; diff --git a/Content.Server/Chat/Commands/OOCCommand.cs b/Content.Server/Chat/Commands/OOCCommand.cs index bef2024608..36f6303fbd 100644 --- a/Content.Server/Chat/Commands/OOCCommand.cs +++ b/Content.Server/Chat/Commands/OOCCommand.cs @@ -1,6 +1,5 @@ using Content.Server.Chat.Managers; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Chat.Commands @@ -14,7 +13,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError("This command cannot be run from the server."); return; diff --git a/Content.Server/Chat/Commands/SayCommand.cs b/Content.Server/Chat/Commands/SayCommand.cs index 7c2125d8c1..273f908c9a 100644 --- a/Content.Server/Chat/Commands/SayCommand.cs +++ b/Content.Server/Chat/Commands/SayCommand.cs @@ -1,6 +1,5 @@ using Content.Server.Chat.Systems; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; @@ -15,7 +14,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError("This command cannot be run from the server."); return; diff --git a/Content.Server/Chat/Commands/SuicideCommand.cs b/Content.Server/Chat/Commands/SuicideCommand.cs index 389ff039bf..c967ba78d7 100644 --- a/Content.Server/Chat/Commands/SuicideCommand.cs +++ b/Content.Server/Chat/Commands/SuicideCommand.cs @@ -1,7 +1,6 @@ using Content.Server.GameTicking; using Content.Shared.Administration; using Content.Shared.Mind; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; @@ -18,7 +17,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteLine(Loc.GetString("shell-cannot-run-command-from-server")); return; diff --git a/Content.Server/Chat/Commands/WhisperCommand.cs b/Content.Server/Chat/Commands/WhisperCommand.cs index 41eba8b384..c88e2519ee 100644 --- a/Content.Server/Chat/Commands/WhisperCommand.cs +++ b/Content.Server/Chat/Commands/WhisperCommand.cs @@ -1,6 +1,5 @@ using Content.Server.Chat.Systems; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; @@ -15,7 +14,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError("This command cannot be run from the server."); return; diff --git a/Content.Server/Chat/Managers/ChatManager.cs b/Content.Server/Chat/Managers/ChatManager.cs index 88e143d24e..59a9d305bd 100644 --- a/Content.Server/Chat/Managers/ChatManager.cs +++ b/Content.Server/Chat/Managers/ChatManager.cs @@ -10,11 +10,9 @@ using Content.Shared.CCVar; using Content.Shared.Chat; using Content.Shared.Database; using Content.Shared.Mind; -using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Network; using Robust.Shared.Player; -using Robust.Shared.Players; using Robust.Shared.Replays; using Robust.Shared.Utility; @@ -51,8 +49,8 @@ namespace Content.Server.Chat.Managers private bool _oocEnabled = true; private bool _adminOocEnabled = true; - public Dictionary SenderKeys { get; } = new(); - public Dictionary> SenderEntities { get; } = new(); + public Dictionary SenderKeys { get; } = new(); + public Dictionary> SenderEntities { get; } = new(); public void Initialize() { @@ -79,7 +77,7 @@ namespace Content.Server.Chat.Managers DispatchServerAnnouncement(Loc.GetString(val ? "chat-manager-admin-ooc-chat-enabled-message" : "chat-manager-admin-ooc-chat-disabled-message")); } - public void DeleteMessagesBy(IPlayerSession player) + public void DeleteMessagesBy(ICommonSession player) { var key = SenderKeys.GetValueOrDefault(player); var entities = SenderEntities.GetValueOrDefault(player) ?? new HashSet(); @@ -165,7 +163,7 @@ namespace Content.Server.Chat.Managers /// The player sending the message. /// The message. /// The type of message. - public void TrySendOOCMessage(IPlayerSession player, string message, OOCChatType type) + public void TrySendOOCMessage(ICommonSession player, string message, OOCChatType type) { // Check if message exceeds the character limit if (message.Length > MaxMessageLength) @@ -189,7 +187,7 @@ namespace Content.Server.Chat.Managers #region Private API - private void SendOOC(IPlayerSession player, string message) + private void SendOOC(ICommonSession player, string message) { if (_adminManager.IsAdmin(player)) { @@ -226,7 +224,7 @@ namespace Content.Server.Chat.Managers _adminLogger.Add(LogType.Chat, LogImpact.Low, $"OOC from {player:Player}: {message}"); } - private void SendAdminChat(IPlayerSession player, string message) + private void SendAdminChat(ICommonSession player, string message) { if (!_adminManager.IsAdmin(player)) { @@ -326,7 +324,7 @@ namespace Content.Server.Chat.Managers } } - public bool MessageCharacterLimit(IPlayerSession? player, string message) + public bool MessageCharacterLimit(ICommonSession? player, string message) { var isOverLength = false; diff --git a/Content.Server/Chat/Managers/IChatManager.cs b/Content.Server/Chat/Managers/IChatManager.cs index 10103f011d..5317b3054e 100644 --- a/Content.Server/Chat/Managers/IChatManager.cs +++ b/Content.Server/Chat/Managers/IChatManager.cs @@ -1,8 +1,6 @@ using Content.Shared.Chat; -using Robust.Server.Player; using Robust.Shared.Network; using Robust.Shared.Player; -using Robust.Shared.Players; namespace Content.Server.Chat.Managers { @@ -12,12 +10,12 @@ namespace Content.Server.Chat.Managers /// Keys identifying messages sent by a specific player, used when sending /// /// - Dictionary SenderKeys { get; } + Dictionary SenderKeys { get; } /// /// Tracks which entities a player was attached to while sending messages. /// - Dictionary> SenderEntities { get; } + Dictionary> SenderEntities { get; } void Initialize(); @@ -30,7 +28,7 @@ namespace Content.Server.Chat.Managers void DispatchServerMessage(ICommonSession player, string message, bool suppressLog = false); - void TrySendOOCMessage(IPlayerSession player, string message, OOCChatType type); + void TrySendOOCMessage(ICommonSession player, string message, OOCChatType type); void SendHookOOC(string sender, string message); void SendAdminAnnouncement(string message); @@ -47,8 +45,8 @@ namespace Content.Server.Chat.Managers void ChatMessageToAll(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, bool recordReplay, Color? colorOverride = null, string? audioPath = null, float audioVolume = 0, int? senderKey = null); - bool MessageCharacterLimit(IPlayerSession player, string message); + bool MessageCharacterLimit(ICommonSession player, string message); - void DeleteMessagesBy(IPlayerSession player); + void DeleteMessagesBy(ICommonSession player); } } diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs index 455d34c907..3315f61c2f 100644 --- a/Content.Server/Chat/Systems/ChatSystem.cs +++ b/Content.Server/Chat/Systems/ChatSystem.cs @@ -7,7 +7,6 @@ using Content.Server.Administration.Logs; using Content.Server.Administration.Managers; using Content.Server.Chat.Managers; using Content.Server.GameTicking; -using Content.Server.Players; using Content.Server.Station.Components; using Content.Server.Station.Systems; using Content.Shared.ActionBlocker; @@ -18,6 +17,7 @@ using Content.Shared.Ghost; using Content.Shared.IdentityManagement; using Content.Shared.Interaction; using Content.Shared.Mobs.Systems; +using Content.Shared.Players; using Content.Shared.Radio; using Robust.Server.GameObjects; using Robust.Server.Player; @@ -26,7 +26,6 @@ using Robust.Shared.Configuration; using Robust.Shared.Console; using Robust.Shared.Network; using Robust.Shared.Player; -using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Replays; @@ -147,7 +146,7 @@ public sealed partial class ChatSystem : SharedChatSystem InGameICChatType desiredType, bool hideChat, bool hideLog = false, IConsoleShell? shell = null, - IPlayerSession? player = null, string? nameOverride = null, + ICommonSession? player = null, string? nameOverride = null, bool checkRadioPrefix = true, bool ignoreActionBlocker = false) { @@ -172,7 +171,7 @@ public sealed partial class ChatSystem : SharedChatSystem ChatTransmitRange range, bool hideLog = false, IConsoleShell? shell = null, - IPlayerSession? player = null, + ICommonSession? player = null, string? nameOverride = null, bool checkRadioPrefix = true, bool ignoreActionBlocker = false @@ -253,7 +252,7 @@ public sealed partial class ChatSystem : SharedChatSystem InGameOOCChatType type, bool hideChat, IConsoleShell? shell = null, - IPlayerSession? player = null + ICommonSession? player = null ) { if (!CanSendInGame(message, shell, player)) @@ -547,7 +546,7 @@ public sealed partial class ChatSystem : SharedChatSystem } // ReSharper disable once InconsistentNaming - private void SendLOOC(EntityUid source, IPlayerSession player, string message, bool hideChat) + private void SendLOOC(EntityUid source, ICommonSession player, string message, bool hideChat) { var name = FormattedMessage.EscapeText(Identity.Name(source, EntityManager)); @@ -571,7 +570,7 @@ public sealed partial class ChatSystem : SharedChatSystem _adminLogger.Add(LogType.Chat, LogImpact.Low, $"LOOC from {player:Player}: {message}"); } - private void SendDeadChat(EntityUid source, IPlayerSession player, string message, bool hideChat) + private void SendDeadChat(EntityUid source, ICommonSession player, string message, bool hideChat) { var clients = GetDeadChatClients(); var playerName = Name(source); @@ -628,13 +627,13 @@ public sealed partial class ChatSystem : SharedChatSystem initialResult = MessageRangeCheckResult.Full; break; case ChatTransmitRange.GhostRangeLimit: - initialResult = (data.Observer && data.Range < 0 && !_adminManager.IsAdmin((IPlayerSession) session)) ? MessageRangeCheckResult.HideChat : MessageRangeCheckResult.Full; + initialResult = (data.Observer && data.Range < 0 && !_adminManager.IsAdmin(session)) ? MessageRangeCheckResult.HideChat : MessageRangeCheckResult.Full; break; case ChatTransmitRange.HideChat: initialResult = MessageRangeCheckResult.HideChat; break; case ChatTransmitRange.NoGhosts: - initialResult = (data.Observer && !_adminManager.IsAdmin((IPlayerSession) session)) ? MessageRangeCheckResult.Disallowed : MessageRangeCheckResult.Full; + initialResult = (data.Observer && !_adminManager.IsAdmin(session)) ? MessageRangeCheckResult.Disallowed : MessageRangeCheckResult.Full; break; } var insistHideChat = data.HideChatOverride ?? false; @@ -666,7 +665,7 @@ public sealed partial class ChatSystem : SharedChatSystem /// /// Returns true if the given player is 'allowed' to send the given message, false otherwise. /// - private bool CanSendInGame(string message, IConsoleShell? shell = null, IPlayerSession? player = null) + private bool CanSendInGame(string message, IConsoleShell? shell = null, ICommonSession? player = null) { // Non-players don't have to worry about these restrictions. if (player == null) @@ -694,7 +693,7 @@ public sealed partial class ChatSystem : SharedChatSystem { var newMessage = message.Trim(); newMessage = SanitizeMessageReplaceWords(newMessage); - + if (capitalize) newMessage = SanitizeMessageCapital(newMessage); if (capitalizeTheWordI) diff --git a/Content.Server/Chemistry/EntitySystems/ChemistryGuideDataSystem.cs b/Content.Server/Chemistry/EntitySystems/ChemistryGuideDataSystem.cs index 8cbdd82f07..7485c0e901 100644 --- a/Content.Server/Chemistry/EntitySystems/ChemistryGuideDataSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/ChemistryGuideDataSystem.cs @@ -2,6 +2,7 @@ using Content.Shared.Chemistry.Reagent; using Robust.Server.Player; using Robust.Shared.Enums; +using Robust.Shared.Player; using Robust.Shared.Prototypes; namespace Content.Server.Chemistry.EntitySystems; diff --git a/Content.Server/Chunking/ChunkingSystem.cs b/Content.Server/Chunking/ChunkingSystem.cs index 4ef44d1678..6f44c43be8 100644 --- a/Content.Server/Chunking/ChunkingSystem.cs +++ b/Content.Server/Chunking/ChunkingSystem.cs @@ -1,12 +1,12 @@ using System.Linq; using Content.Shared.Decals; using Microsoft.Extensions.ObjectPool; -using Robust.Server.Player; using Robust.Shared; using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Map; using Robust.Shared.Map.Components; +using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Shared.Chunking; @@ -41,7 +41,7 @@ public sealed class ChunkingSystem : EntitySystem private void OnPvsRangeChanged(float value) => _baseViewBounds = Box2.UnitCentered.Scale(value); public Dictionary> GetChunksForSession( - IPlayerSession session, + ICommonSession session, int chunkSize, ObjectPool> indexPool, ObjectPool>> viewerPool, @@ -52,7 +52,7 @@ public sealed class ChunkingSystem : EntitySystem return chunks; } - private HashSet GetSessionViewers(IPlayerSession session) + private HashSet GetSessionViewers(ICommonSession session) { var viewers = new HashSet(); if (session.Status != SessionStatus.InGame || session.AttachedEntity is null) diff --git a/Content.Server/Commands/CommandUtils.cs b/Content.Server/Commands/CommandUtils.cs index 11adaec9a2..172f3324e3 100644 --- a/Content.Server/Commands/CommandUtils.cs +++ b/Content.Server/Commands/CommandUtils.cs @@ -3,6 +3,7 @@ using System.Globalization; using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Network; +using Robust.Shared.Player; namespace Content.Server.Commands { @@ -16,7 +17,7 @@ namespace Content.Server.Commands /// sending a failure to the performer if unable to. /// public static bool TryGetSessionByUsernameOrId(IConsoleShell shell, - string usernameOrId, IPlayerSession performer, [NotNullWhen(true)] out IPlayerSession? session) + string usernameOrId, ICommonSession performer, [NotNullWhen(true)] out ICommonSession? session) { var plyMgr = IoCManager.Resolve(); if (plyMgr.TryGetSessionByUsername(usernameOrId, out session)) return true; @@ -36,7 +37,7 @@ namespace Content.Server.Commands /// sending a failure to the performer if unable to. /// public static bool TryGetAttachedEntityByUsernameOrId(IConsoleShell shell, - string usernameOrId, IPlayerSession performer, out EntityUid attachedEntity) + string usernameOrId, ICommonSession performer, out EntityUid attachedEntity) { attachedEntity = default; if (!TryGetSessionByUsernameOrId(shell, usernameOrId, performer, out var session)) return false; @@ -67,7 +68,7 @@ namespace Content.Server.Commands transform.LocalPosition.Y.ToString(CultureInfo.InvariantCulture)); ruleString = ruleString.Replace("$NAME", entMan.GetComponent(ent).EntityName); - if (shell.Player is IPlayerSession player) + if (shell.Player is { } player) { if (player.AttachedEntity is {Valid: true} p) { diff --git a/Content.Server/Construction/Commands/FixRotationsCommand.cs b/Content.Server/Construction/Commands/FixRotationsCommand.cs index d23fa0a31b..bdbfaf170d 100644 --- a/Content.Server/Construction/Commands/FixRotationsCommand.cs +++ b/Content.Server/Construction/Commands/FixRotationsCommand.cs @@ -3,7 +3,6 @@ using Content.Server.Power.Components; using Content.Shared.Administration; using Content.Shared.Construction; using Content.Shared.Tag; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map.Components; @@ -21,7 +20,7 @@ namespace Content.Server.Construction.Commands public void Execute(IConsoleShell shell, string argsOther, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; EntityUid? gridId; var xformQuery = _entManager.GetEntityQuery(); diff --git a/Content.Server/Construction/Commands/TileReplaceCommand.cs b/Content.Server/Construction/Commands/TileReplaceCommand.cs index ed1fba2424..f63fd4c13e 100644 --- a/Content.Server/Construction/Commands/TileReplaceCommand.cs +++ b/Content.Server/Construction/Commands/TileReplaceCommand.cs @@ -1,6 +1,5 @@ using Content.Server.Administration; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; using Robust.Shared.Map.Components; @@ -20,7 +19,7 @@ sealed class TileReplaceCommand : IConsoleCommand public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; EntityUid? gridId; string tileIdA; string tileIdB; diff --git a/Content.Server/Construction/Commands/TileWallsCommand.cs b/Content.Server/Construction/Commands/TileWallsCommand.cs index 55389e41cc..731d4da7f8 100644 --- a/Content.Server/Construction/Commands/TileWallsCommand.cs +++ b/Content.Server/Construction/Commands/TileWallsCommand.cs @@ -2,10 +2,9 @@ using Content.Server.Administration; using Content.Shared.Administration; using Content.Shared.Maps; using Content.Shared.Tag; -using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; +using Robust.Server.GameObjects; using Robust.Shared.Map.Components; namespace Content.Server.Construction.Commands @@ -29,7 +28,7 @@ namespace Content.Server.Construction.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; EntityUid? gridId; switch (args.Length) diff --git a/Content.Server/Construction/ConstructionSystem.Initial.cs b/Content.Server/Construction/ConstructionSystem.Initial.cs index e74edb5da2..21978f2d0c 100644 --- a/Content.Server/Construction/ConstructionSystem.Initial.cs +++ b/Content.Server/Construction/ConstructionSystem.Initial.cs @@ -16,7 +16,7 @@ using Content.Shared.Interaction; using Content.Shared.Inventory; using Content.Shared.Storage; using Robust.Shared.Containers; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.Construction diff --git a/Content.Server/CrewManifest/CrewManifestSystem.cs b/Content.Server/CrewManifest/CrewManifestSystem.cs index aed0575324..4c4f17f61d 100644 --- a/Content.Server/CrewManifest/CrewManifestSystem.cs +++ b/Content.Server/CrewManifest/CrewManifestSystem.cs @@ -10,10 +10,9 @@ using Content.Shared.CCVar; using Content.Shared.CrewManifest; using Content.Shared.GameTicking; using Content.Shared.StationRecords; -using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Console; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.CrewManifest; @@ -60,7 +59,7 @@ public sealed class CrewManifestSystem : EntitySystem private void OnRequestCrewManifest(RequestCrewManifestMessage message, EntitySessionEventArgs args) { - if (args.SenderSession is not IPlayerSession sessionCast + if (args.SenderSession is not { } sessionCast || !_configManager.GetCVar(CCVars.CrewManifestWithoutEntity)) { return; @@ -93,12 +92,12 @@ public sealed class CrewManifestSystem : EntitySystem private void OnBoundUiClose(EntityUid uid, CrewManifestViewerComponent component, BoundUIClosedEvent ev) { var owningStation = _stationSystem.GetOwningStation(uid); - if (owningStation == null || ev.Session is not IPlayerSession sessionCast) + if (owningStation == null || ev.Session is not { } session) { return; } - CloseEui(owningStation.Value, sessionCast, uid); + CloseEui(owningStation.Value, session, uid); } /// @@ -126,7 +125,7 @@ public sealed class CrewManifestSystem : EntitySystem private void OpenEuiFromBui(EntityUid uid, CrewManifestViewerComponent component, CrewManifestOpenUiMessage msg) { var owningStation = _stationSystem.GetOwningStation(uid); - if (owningStation == null || msg.Session is not IPlayerSession sessionCast) + if (owningStation == null || msg.Session is not { } session) { return; } @@ -136,7 +135,7 @@ public sealed class CrewManifestSystem : EntitySystem return; } - OpenEui(owningStation.Value, sessionCast, uid); + OpenEui(owningStation.Value, session, uid); } /// @@ -145,7 +144,7 @@ public sealed class CrewManifestSystem : EntitySystem /// Station that we're displaying the crew manifest for. /// The player's session. /// If this EUI should be 'owned' by an entity. - public void OpenEui(EntityUid station, IPlayerSession session, EntityUid? owner = null) + public void OpenEui(EntityUid station, ICommonSession session, EntityUid? owner = null) { if (!HasComp(station)) { @@ -252,7 +251,7 @@ public sealed class CrewManifestCommand : IConsoleCommand return; } - if (shell.Player == null || shell.Player is not IPlayerSession session) + if (shell.Player == null || shell.Player is not { } session) { shell.WriteLine("You must run this from a client."); return; diff --git a/Content.Server/Damage/Commands/GodModeCommand.cs b/Content.Server/Damage/Commands/GodModeCommand.cs index 92a0e53f0f..866737f17a 100644 --- a/Content.Server/Damage/Commands/GodModeCommand.cs +++ b/Content.Server/Damage/Commands/GodModeCommand.cs @@ -1,8 +1,6 @@ using Content.Server.Administration; -using Content.Server.Damage.Systems; using Content.Shared.Administration; using Content.Shared.Damage.Systems; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Damage.Commands @@ -18,7 +16,7 @@ namespace Content.Server.Damage.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; EntityUid entity; switch (args.Length) diff --git a/Content.Server/Damage/ForceSay/DamageForceSaySystem.cs b/Content.Server/Damage/ForceSay/DamageForceSaySystem.cs index 3d3346403a..457fab4bb2 100644 --- a/Content.Server/Damage/ForceSay/DamageForceSaySystem.cs +++ b/Content.Server/Damage/ForceSay/DamageForceSaySystem.cs @@ -6,7 +6,6 @@ using Content.Shared.Mobs.Systems; using Content.Shared.Stunnable; using Robust.Server.GameObjects; using Robust.Server.Player; -using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; diff --git a/Content.Server/Database/UserDbDataManager.cs b/Content.Server/Database/UserDbDataManager.cs index f2c506240b..f8b1611fd5 100644 --- a/Content.Server/Database/UserDbDataManager.cs +++ b/Content.Server/Database/UserDbDataManager.cs @@ -2,8 +2,8 @@ using System.Threading.Tasks; using Content.Server.Players.PlayTimeTracking; using Content.Server.Preferences.Managers; -using Robust.Server.Player; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Server.Database; @@ -25,7 +25,7 @@ public sealed class UserDbDataManager // TODO: Ideally connected/disconnected would be subscribed to IPlayerManager directly, // but this runs into ordering issues with game ticker. - public void ClientConnected(IPlayerSession session) + public void ClientConnected(ICommonSession session) { DebugTools.Assert(!_users.ContainsKey(session.UserId), "We should not have any cached data on client connect."); @@ -36,7 +36,7 @@ public sealed class UserDbDataManager _users.Add(session.UserId, data); } - public void ClientDisconnected(IPlayerSession session) + public void ClientDisconnected(ICommonSession session) { _users.Remove(session.UserId, out var data); if (data == null) @@ -49,24 +49,24 @@ public sealed class UserDbDataManager _playTimeTracking.ClientDisconnected(session); } - private async Task Load(IPlayerSession session, CancellationToken cancel) + private async Task Load(ICommonSession session, CancellationToken cancel) { await Task.WhenAll( _prefs.LoadData(session, cancel), _playTimeTracking.LoadData(session, cancel)); } - public Task WaitLoadComplete(IPlayerSession session) + public Task WaitLoadComplete(ICommonSession session) { return _users[session.UserId].Task; } - public bool IsLoadComplete(IPlayerSession session) + public bool IsLoadComplete(ICommonSession session) { return GetLoadTask(session).IsCompleted; } - public Task GetLoadTask(IPlayerSession session) + public Task GetLoadTask(ICommonSession session) { return _users[session.UserId].Task; } diff --git a/Content.Server/Decals/DecalSystem.cs b/Content.Server/Decals/DecalSystem.cs index ed281e05ba..ce2e0711e7 100644 --- a/Content.Server/Decals/DecalSystem.cs +++ b/Content.Server/Decals/DecalSystem.cs @@ -16,6 +16,7 @@ using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Map; using Robust.Shared.Map.Components; +using Robust.Shared.Player; using Robust.Shared.Threading; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -36,7 +37,7 @@ namespace Content.Server.Decals [Dependency] private readonly MapSystem _mapSystem = default!; private readonly Dictionary> _dirtyChunks = new(); - private readonly Dictionary>> _previousSentChunks = new(); + private readonly Dictionary>> _previousSentChunks = new(); private static readonly Vector2 _boundsMinExpansion = new(0.01f, 0.01f); private static readonly Vector2 _boundsMaxExpansion = new(1.01f, 1.01f); @@ -197,7 +198,7 @@ namespace Content.Server.Decals private void OnDecalPlacementRequest(RequestDecalPlacementEvent ev, EntitySessionEventArgs eventArgs) { - if (eventArgs.SenderSession is not IPlayerSession session) + if (eventArgs.SenderSession is not { } session) return; // bad @@ -226,7 +227,7 @@ namespace Content.Server.Decals private void OnDecalRemovalRequest(RequestDecalRemovalEvent ev, EntitySessionEventArgs eventArgs) { - if (eventArgs.SenderSession is not IPlayerSession session) + if (eventArgs.SenderSession is not { } session) return; // bad @@ -427,7 +428,7 @@ namespace Content.Server.Decals if (PvsEnabled) { - var players = _playerManager.ServerSessions.Where(x => x.Status == SessionStatus.InGame).ToArray(); + var players = _playerManager.Sessions.Where(x => x.Status == SessionStatus.InGame).ToArray(); var opts = new ParallelOptions { MaxDegreeOfParallelism = _parMan.ParallelProcessCount }; Parallel.ForEach(players, opts, UpdatePlayer); } @@ -435,7 +436,7 @@ namespace Content.Server.Decals _dirtyChunks.Clear(); } - public void UpdatePlayer(IPlayerSession player) + public void UpdatePlayer(ICommonSession player) { var chunksInRange = _chunking.GetChunksForSession(player, ChunkSize, _chunkIndexPool, _chunkViewerPool); var staleChunks = _chunkViewerPool.Get(); @@ -530,7 +531,7 @@ namespace Content.Server.Decals } private void SendChunkUpdates( - IPlayerSession session, + ICommonSession session, Dictionary> updatedChunks, Dictionary> staleChunks) { diff --git a/Content.Server/Disposal/TubeConnectionsCommand.cs b/Content.Server/Disposal/TubeConnectionsCommand.cs index 7895dcbca6..55e6465937 100644 --- a/Content.Server/Disposal/TubeConnectionsCommand.cs +++ b/Content.Server/Disposal/TubeConnectionsCommand.cs @@ -2,7 +2,6 @@ using Content.Server.Administration; using Content.Server.Disposal.Tube; using Content.Server.Disposal.Tube.Components; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Disposal @@ -18,7 +17,7 @@ namespace Content.Server.Disposal public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player?.AttachedEntity == null) { shell.WriteLine(Loc.GetString("shell-only-players-can-run-this-command")); diff --git a/Content.Server/EUI/BaseEui.cs b/Content.Server/EUI/BaseEui.cs index 4a41ad40a5..70cbfc3775 100644 --- a/Content.Server/EUI/BaseEui.cs +++ b/Content.Server/EUI/BaseEui.cs @@ -1,6 +1,6 @@ using Content.Shared.Eui; using Robust.Shared.Network; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.EUI { diff --git a/Content.Server/EUI/EuiManager.cs b/Content.Server/EUI/EuiManager.cs index 4d99719525..fe8e486b68 100644 --- a/Content.Server/EUI/EuiManager.cs +++ b/Content.Server/EUI/EuiManager.cs @@ -2,7 +2,7 @@ using Robust.Server.Player; using Robust.Shared.Enums; using Robust.Shared.Network; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Server.EUI diff --git a/Content.Server/EntityList/SpawnEntityListCommand.cs b/Content.Server/EntityList/SpawnEntityListCommand.cs index 0891bbd12a..027d25dc2c 100644 --- a/Content.Server/EntityList/SpawnEntityListCommand.cs +++ b/Content.Server/EntityList/SpawnEntityListCommand.cs @@ -1,7 +1,6 @@ using Content.Server.Administration; using Content.Shared.Administration; using Content.Shared.EntityList; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Prototypes; @@ -22,7 +21,7 @@ namespace Content.Server.EntityList return; } - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError("You must be a player to run this command."); return; diff --git a/Content.Server/Examine/ExamineSystem.cs b/Content.Server/Examine/ExamineSystem.cs index 98aa806885..3447810896 100644 --- a/Content.Server/Examine/ExamineSystem.cs +++ b/Content.Server/Examine/ExamineSystem.cs @@ -4,7 +4,6 @@ using Content.Shared.Examine; using Content.Shared.Verbs; using JetBrains.Annotations; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Utility; namespace Content.Server.Examine @@ -46,7 +45,7 @@ namespace Content.Server.Examine private void ExamineInfoRequest(ExamineSystemMessages.RequestExamineInfoMessage request, EntitySessionEventArgs eventArgs) { - var player = (IPlayerSession) eventArgs.SenderSession; + var player = eventArgs.SenderSession; var session = eventArgs.SenderSession; var channel = player.ConnectedClient; var entity = GetEntity(request.NetEntity); diff --git a/Content.Server/Fluids/EntitySystems/PuddleDebugDebugOverlaySystem.cs b/Content.Server/Fluids/EntitySystems/PuddleDebugDebugOverlaySystem.cs index 59f0a13695..c17eea684d 100644 --- a/Content.Server/Fluids/EntitySystems/PuddleDebugDebugOverlaySystem.cs +++ b/Content.Server/Fluids/EntitySystems/PuddleDebugDebugOverlaySystem.cs @@ -1,9 +1,9 @@ using System.Numerics; using Content.Shared.Fluids; using Content.Shared.Fluids.Components; -using Robust.Server.Player; using Robust.Shared.Map; using Robust.Shared.Map.Components; +using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.Fluids.EntitySystems; @@ -14,10 +14,10 @@ public sealed class PuddleDebugDebugOverlaySystem : SharedPuddleDebugOverlaySyst [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly PuddleSystem _puddle = default!; - private readonly HashSet _playerObservers = new(); + private readonly HashSet _playerObservers = new(); private List> _grids = new(); - public bool ToggleObserver(IPlayerSession observer) + public bool ToggleObserver(ICommonSession observer) { NextTick ??= _timing.CurTime + Cooldown; @@ -31,7 +31,7 @@ public sealed class PuddleDebugDebugOverlaySystem : SharedPuddleDebugOverlaySyst return true; } - private void RemoveObserver(IPlayerSession observer) + private void RemoveObserver(ICommonSession observer) { if (!_playerObservers.Remove(observer)) { diff --git a/Content.Server/Fluids/ShowFluidsCommand.cs b/Content.Server/Fluids/ShowFluidsCommand.cs index f122eadea7..71ac273a45 100644 --- a/Content.Server/Fluids/ShowFluidsCommand.cs +++ b/Content.Server/Fluids/ShowFluidsCommand.cs @@ -1,7 +1,6 @@ using Content.Server.Administration; using Content.Server.Fluids.EntitySystems; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Fluids; @@ -15,7 +14,7 @@ public sealed class ShowFluidsCommand : IConsoleCommand public string Help => $"Usage: {Command}"; public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("You must be a player to use this command."); diff --git a/Content.Server/GameTicking/Commands/JoinGameCommand.cs b/Content.Server/GameTicking/Commands/JoinGameCommand.cs index 366e6c4e77..3276b91200 100644 --- a/Content.Server/GameTicking/Commands/JoinGameCommand.cs +++ b/Content.Server/GameTicking/Commands/JoinGameCommand.cs @@ -2,7 +2,6 @@ using Content.Server.Station.Systems; using Content.Shared.Administration; using Content.Shared.GameTicking; using Content.Shared.Roles; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Prototypes; @@ -30,7 +29,7 @@ namespace Content.Server.GameTicking.Commands return; } - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { diff --git a/Content.Server/GameTicking/Commands/ObserveCommand.cs b/Content.Server/GameTicking/Commands/ObserveCommand.cs index d608dda9c1..747e54e28b 100644 --- a/Content.Server/GameTicking/Commands/ObserveCommand.cs +++ b/Content.Server/GameTicking/Commands/ObserveCommand.cs @@ -1,6 +1,5 @@ using Content.Shared.Administration; using Content.Shared.GameTicking; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.GameTicking.Commands @@ -14,7 +13,7 @@ namespace Content.Server.GameTicking.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { return; } diff --git a/Content.Server/GameTicking/Commands/RespawnCommand.cs b/Content.Server/GameTicking/Commands/RespawnCommand.cs index 057572297f..4f101d0939 100644 --- a/Content.Server/GameTicking/Commands/RespawnCommand.cs +++ b/Content.Server/GameTicking/Commands/RespawnCommand.cs @@ -14,7 +14,7 @@ namespace Content.Server.GameTicking.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (args.Length > 1) { shell.WriteLine("Must provide <= 1 argument."); diff --git a/Content.Server/GameTicking/Commands/ToggleReadyCommand.cs b/Content.Server/GameTicking/Commands/ToggleReadyCommand.cs index e68c4c5fa7..df418c27ee 100644 --- a/Content.Server/GameTicking/Commands/ToggleReadyCommand.cs +++ b/Content.Server/GameTicking/Commands/ToggleReadyCommand.cs @@ -1,5 +1,4 @@ using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.GameTicking.Commands @@ -13,7 +12,7 @@ namespace Content.Server.GameTicking.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (args.Length != 1) { shell.WriteError(Loc.GetString("shell-wrong-arguments-number")); diff --git a/Content.Server/GameTicking/GameTicker.GamePreset.cs b/Content.Server/GameTicking/GameTicker.GamePreset.cs index a5e6d7a605..2d7539bd0f 100644 --- a/Content.Server/GameTicking/GameTicker.GamePreset.cs +++ b/Content.Server/GameTicking/GameTicker.GamePreset.cs @@ -11,7 +11,7 @@ using Content.Shared.Ghost; using Content.Shared.Mind; using Content.Shared.Mobs.Components; using JetBrains.Annotations; -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.GameTicking { @@ -29,7 +29,7 @@ namespace Content.Server.GameTicking /// public GamePresetPrototype? CurrentPreset { get; private set; } - private bool StartPreset(IPlayerSession[] origReadyPlayers, bool force) + private bool StartPreset(ICommonSession[] origReadyPlayers, bool force) { var startAttempt = new RoundStartAttemptEvent(origReadyPlayers, force); RaiseLocalEvent(startAttempt); @@ -214,7 +214,7 @@ namespace Content.Server.GameTicking { if (mind.Session != null) // Logging is suppressed to prevent spam from ghost attempts caused by movement attempts { - _chatManager.DispatchServerMessage((IPlayerSession) mind.Session, Loc.GetString("comp-mind-ghosting-prevented"), + _chatManager.DispatchServerMessage(mind.Session, Loc.GetString("comp-mind-ghosting-prevented"), true); } diff --git a/Content.Server/GameTicking/GameTicker.Lobby.cs b/Content.Server/GameTicking/GameTicker.Lobby.cs index b7b6a29a5a..1943a82617 100644 --- a/Content.Server/GameTicking/GameTicker.Lobby.cs +++ b/Content.Server/GameTicking/GameTicker.Lobby.cs @@ -1,10 +1,8 @@ using System.Linq; using Content.Shared.GameTicking; using Content.Server.Station.Components; -using Robust.Server.Player; using Robust.Shared.Network; using Robust.Shared.Player; -using Robust.Shared.Players; using System.Text; namespace Content.Server.GameTicking @@ -79,7 +77,7 @@ namespace Content.Server.GameTicking ("roundId", RoundId), ("playerCount", playerCount), ("readyCount", readyCount), ("mapName", stationNames.ToString()),("gmTitle", gmTitle),("desc", desc)); } - private TickerLobbyStatusEvent GetStatusMsg(IPlayerSession session) + private TickerLobbyStatusEvent GetStatusMsg(ICommonSession session) { _playerGameStatuses.TryGetValue(session.UserId, out var status); return new TickerLobbyStatusEvent(RunLevel != GameRunLevel.PreRoundLobby, LobbySong, LobbyBackground,status == PlayerGameStatus.ReadyToPlay, _roundStartTime, RoundPreloadTime, _roundStartTimeSpan, Paused); @@ -87,7 +85,7 @@ namespace Content.Server.GameTicking private void SendStatusToAll() { - foreach (var player in _playerManager.ServerSessions) + foreach (var player in _playerManager.Sessions) { RaiseNetworkEvent(GetStatusMsg(player), player.ConnectedClient); } @@ -148,7 +146,7 @@ namespace Content.Server.GameTicking } } - public void ToggleReady(IPlayerSession player, bool ready) + public void ToggleReady(ICommonSession player, bool ready) { if (!_playerGameStatuses.ContainsKey(player.UserId)) return; diff --git a/Content.Server/GameTicking/GameTicker.Player.cs b/Content.Server/GameTicking/GameTicker.Player.cs index 3aef1bbe78..334af3f4fd 100644 --- a/Content.Server/GameTicking/GameTicker.Player.cs +++ b/Content.Server/GameTicking/GameTicker.Player.cs @@ -1,5 +1,4 @@ using Content.Server.Database; -using Content.Server.Players; using Content.Shared.GameTicking; using Content.Shared.GameWindow; using Content.Shared.Players; @@ -7,6 +6,7 @@ using Content.Shared.Preferences; using JetBrains.Annotations; using Robust.Server.Player; using Robust.Shared.Enums; +using Robust.Shared.Player; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -49,14 +49,14 @@ namespace Content.Server.GameTicking // Always make sure the client has player data. if (session.Data.ContentDataUncast == null) { - var data = new PlayerData(session.UserId, args.Session.Name); + var data = new ContentPlayerData(session.UserId, args.Session.Name); data.Mind = mindId; session.Data.ContentDataUncast = data; } // Make the player actually join the game. // timer time must be > tick length - Timer.Spawn(0, args.Session.JoinGame); + Timer.Spawn(0, () => _playerManager.JoinGame(args.Session)); var record = await _dbManager.GetPlayerRecordByUserId(args.Session.UserId); var firstConnection = record != null && @@ -100,8 +100,7 @@ namespace Content.Server.GameTicking } else { - // Simply re-attach to existing entity. - session.AttachToEntity(mind.CurrentEntity); + _playerManager.SetAttachedEntity(session, mind.CurrentEntity); PlayerJoinGame(session); } @@ -146,12 +145,12 @@ namespace Content.Server.GameTicking } } - private HumanoidCharacterProfile GetPlayerProfile(IPlayerSession p) + private HumanoidCharacterProfile GetPlayerProfile(ICommonSession p) { return (HumanoidCharacterProfile) _prefsManager.GetPreferences(p.UserId).SelectedCharacter; } - public void PlayerJoinGame(IPlayerSession session, bool silent = false) + public void PlayerJoinGame(ICommonSession session, bool silent = false) { if (!silent) _chatManager.DispatchServerMessage(session, Loc.GetString("game-ticker-player-join-game-message")); @@ -162,7 +161,7 @@ namespace Content.Server.GameTicking RaiseNetworkEvent(new TickerJoinGameEvent(), session.ConnectedClient); } - private void PlayerJoinLobby(IPlayerSession session) + private void PlayerJoinLobby(ICommonSession session) { _playerGameStatuses[session.UserId] = LobbyEnabled ? PlayerGameStatus.NotReadyToPlay : PlayerGameStatus.ReadyToPlay; _db.AddRoundPlayers(RoundId, session.UserId); @@ -182,9 +181,9 @@ namespace Content.Server.GameTicking public sealed class PlayerJoinedLobbyEvent : EntityEventArgs { - public readonly IPlayerSession PlayerSession; + public readonly ICommonSession PlayerSession; - public PlayerJoinedLobbyEvent(IPlayerSession playerSession) + public PlayerJoinedLobbyEvent(ICommonSession playerSession) { PlayerSession = playerSession; } diff --git a/Content.Server/GameTicking/GameTicker.RoundFlow.cs b/Content.Server/GameTicking/GameTicker.RoundFlow.cs index df2aafa901..85f833bd1c 100644 --- a/Content.Server/GameTicking/GameTicker.RoundFlow.cs +++ b/Content.Server/GameTicking/GameTicker.RoundFlow.cs @@ -12,7 +12,6 @@ using Content.Shared.Preferences; using JetBrains.Annotations; using Prometheus; using Robust.Server.Maps; -using Robust.Server.Player; using Robust.Shared.Asynchronous; using Robust.Shared.Audio; using Robust.Shared.Map; @@ -205,7 +204,7 @@ namespace Content.Server.GameTicking var startingEvent = new RoundStartingEvent(RoundId); RaiseLocalEvent(startingEvent); - var readyPlayers = new List(); + var readyPlayers = new List(); var readyPlayerProfiles = new Dictionary(); foreach (var (userId, status) in _playerGameStatuses) @@ -344,7 +343,7 @@ namespace Content.Server.GameTicking { connected = true; } - PlayerData? contentPlayerData = null; + ContentPlayerData? contentPlayerData = null; if (userId != null && _playerManager.TryGetPlayerData(userId.Value, out var playerData)) { contentPlayerData = playerData.ContentData(); @@ -360,8 +359,7 @@ namespace Content.Server.GameTicking else if (mind.CurrentEntity != null && TryName(mind.CurrentEntity.Value, out var icName)) playerIcName = icName; - var entity = mind.OriginalOwnedEntity; - if (Exists(entity)) + if (TryGetEntity(mind.OriginalOwnedEntity, out var entity)) _pvsOverride.AddGlobalOverride(entity.Value, recursive: true); var roles = _roles.MindGetAllRoles(mindId); @@ -494,7 +492,7 @@ namespace Content.Server.GameTicking private void ResettingCleanup() { // Move everybody currently in the server to lobby. - foreach (var player in _playerManager.ServerSessions) + foreach (var player in _playerManager.Sessions) { PlayerJoinLobby(player); } @@ -542,7 +540,7 @@ namespace Content.Server.GameTicking DisallowLateJoin = false; _playerGameStatuses.Clear(); - foreach (var session in _playerManager.ServerSessions) + foreach (var session in _playerManager.Sessions) { _playerGameStatuses[session.UserId] = LobbyEnabled ? PlayerGameStatus.NotReadyToPlay : PlayerGameStatus.ReadyToPlay; } @@ -736,10 +734,10 @@ namespace Content.Server.GameTicking /// public sealed class RoundStartAttemptEvent : CancellableEntityEventArgs { - public IPlayerSession[] Players { get; } + public ICommonSession[] Players { get; } public bool Forced { get; } - public RoundStartAttemptEvent(IPlayerSession[] players, bool forced) + public RoundStartAttemptEvent(ICommonSession[] players, bool forced) { Players = players; Forced = forced; @@ -758,11 +756,11 @@ namespace Content.Server.GameTicking /// If you want to handle a specific player being spawned, remove it from this list and do what you need. /// /// If you spawn a player by yourself from this event, don't forget to call on them. - public List PlayerPool { get; } + public List PlayerPool { get; } public IReadOnlyDictionary Profiles { get; } public bool Forced { get; } - public RulePlayerSpawningEvent(List playerPool, IReadOnlyDictionary profiles, bool forced) + public RulePlayerSpawningEvent(List playerPool, IReadOnlyDictionary profiles, bool forced) { PlayerPool = playerPool; Profiles = profiles; @@ -776,11 +774,11 @@ namespace Content.Server.GameTicking /// public sealed class RulePlayerJobsAssignedEvent { - public IPlayerSession[] Players { get; } + public ICommonSession[] Players { get; } public IReadOnlyDictionary Profiles { get; } public bool Forced { get; } - public RulePlayerJobsAssignedEvent(IPlayerSession[] players, IReadOnlyDictionary profiles, bool forced) + public RulePlayerJobsAssignedEvent(ICommonSession[] players, IReadOnlyDictionary profiles, bool forced) { Players = players; Profiles = profiles; diff --git a/Content.Server/GameTicking/GameTicker.Spawning.cs b/Content.Server/GameTicking/GameTicker.Spawning.cs index 0c59f93bb0..c2bf523657 100644 --- a/Content.Server/GameTicking/GameTicker.Spawning.cs +++ b/Content.Server/GameTicking/GameTicker.Spawning.cs @@ -3,20 +3,20 @@ using System.Linq; using System.Numerics; using Content.Server.Administration.Managers; using Content.Server.Ghost; -using Content.Server.Players; using Content.Server.Spawners.Components; using Content.Server.Speech.Components; using Content.Server.Station.Components; using Content.Shared.CCVar; using Content.Shared.Database; +using Content.Shared.Players; using Content.Shared.Preferences; using Content.Shared.Roles; using Content.Shared.Roles.Jobs; using JetBrains.Annotations; -using Robust.Server.Player; using Robust.Shared.Map; using Robust.Shared.Map.Components; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Utility; @@ -29,7 +29,7 @@ namespace Content.Server.GameTicking [Dependency] private readonly SharedJobSystem _jobs = default!; [ValidatePrototypeId] - private const string ObserverPrototypeName = "MobObserver"; + public const string ObserverPrototypeName = "MobObserver"; /// /// How many players have joined the round through normal methods. @@ -52,7 +52,7 @@ namespace Content.Server.GameTicking return spawnableStations; } - private void SpawnPlayers(List readyPlayers, Dictionary profiles, bool force) + private void SpawnPlayers(List readyPlayers, Dictionary profiles, bool force) { // Allow game rules to spawn players by themselves if needed. (For example, nuke ops or wizard) RaiseLocalEvent(new RulePlayerSpawningEvent(readyPlayers, profiles, force)); @@ -116,7 +116,7 @@ namespace Content.Server.GameTicking RaiseLocalEvent(new RulePlayerJobsAssignedEvent(assignedJobs.Keys.Select(x => _playerManager.GetSessionByUserId(x)).ToArray(), profiles, force)); } - private void SpawnPlayer(IPlayerSession player, EntityUid station, string? jobId = null, bool lateJoin = true, bool silent = false) + private void SpawnPlayer(ICommonSession player, EntityUid station, string? jobId = null, bool lateJoin = true, bool silent = false) { var character = GetPlayerProfile(player); @@ -129,7 +129,7 @@ namespace Content.Server.GameTicking SpawnPlayer(player, character, station, jobId, lateJoin, silent); } - private void SpawnPlayer(IPlayerSession player, HumanoidCharacterProfile character, EntityUid station, string? jobId = null, bool lateJoin = true, bool silent = false) + private void SpawnPlayer(ICommonSession player, HumanoidCharacterProfile character, EntityUid station, string? jobId = null, bool lateJoin = true, bool silent = false) { // Can't spawn players with a dummy ticker! if (DummyTicker) @@ -271,7 +271,7 @@ namespace Content.Server.GameTicking RaiseLocalEvent(mob, aev, true); } - public void Respawn(IPlayerSession player) + public void Respawn(ICommonSession player) { _mind.WipeMind(player); _adminLogger.Add(LogType.Respawn, LogImpact.Medium, $"Player {player} was respawned."); @@ -289,7 +289,7 @@ namespace Content.Server.GameTicking /// The station they're spawning on /// An optional job for them to spawn as /// Whether or not the player should be greeted upon joining - public void MakeJoinGame(IPlayerSession player, EntityUid station, string? jobId = null, bool silent = false) + public void MakeJoinGame(ICommonSession player, EntityUid station, string? jobId = null, bool silent = false) { if (!_playerGameStatuses.ContainsKey(player.UserId)) return; @@ -303,7 +303,7 @@ namespace Content.Server.GameTicking /// /// Causes the given player to join the current game as observer ghost. See also /// - public void JoinAsObserver(IPlayerSession player) + public void JoinAsObserver(ICommonSession player) { // Can't spawn players with a dummy ticker! if (DummyTicker) @@ -317,7 +317,7 @@ namespace Content.Server.GameTicking /// Spawns an observer ghost and attaches the given player to it. If the player does not yet have a mind, the /// player is given a new mind with the observer role. Otherwise, the current mind is transferred to the ghost. /// - public void SpawnObserver(IPlayerSession player) + public void SpawnObserver(ICommonSession player) { if (DummyTicker) return; @@ -430,13 +430,13 @@ namespace Content.Server.GameTicking [PublicAPI] public sealed class PlayerBeforeSpawnEvent : HandledEntityEventArgs { - public IPlayerSession Player { get; } + public ICommonSession Player { get; } public HumanoidCharacterProfile Profile { get; } public string? JobId { get; } public bool LateJoin { get; } public EntityUid Station { get; } - public PlayerBeforeSpawnEvent(IPlayerSession player, HumanoidCharacterProfile profile, string? jobId, bool lateJoin, EntityUid station) + public PlayerBeforeSpawnEvent(ICommonSession player, HumanoidCharacterProfile profile, string? jobId, bool lateJoin, EntityUid station) { Player = player; Profile = profile; @@ -455,7 +455,7 @@ namespace Content.Server.GameTicking public sealed class PlayerSpawnCompleteEvent : EntityEventArgs { public EntityUid Mob { get; } - public IPlayerSession Player { get; } + public ICommonSession Player { get; } public string? JobId { get; } public bool LateJoin { get; } public EntityUid Station { get; } @@ -464,7 +464,7 @@ namespace Content.Server.GameTicking // Ex. If this is the 27th person to join, this will be 27. public int JoinOrder { get; } - public PlayerSpawnCompleteEvent(EntityUid mob, IPlayerSession player, string? jobId, bool lateJoin, int joinOrder, EntityUid station, HumanoidCharacterProfile profile) + public PlayerSpawnCompleteEvent(EntityUid mob, ICommonSession player, string? jobId, bool lateJoin, int joinOrder, EntityUid station, HumanoidCharacterProfile profile) { Mob = mob; Player = player; diff --git a/Content.Server/GameTicking/Rules/Components/TraitorRuleComponent.cs b/Content.Server/GameTicking/Rules/Components/TraitorRuleComponent.cs index 883abef52f..7af87179d6 100644 --- a/Content.Server/GameTicking/Rules/Components/TraitorRuleComponent.cs +++ b/Content.Server/GameTicking/Rules/Components/TraitorRuleComponent.cs @@ -1,7 +1,7 @@ using Content.Shared.Preferences; using Content.Shared.Roles; -using Robust.Server.Player; using Robust.Shared.Audio; +using Robust.Shared.Player; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Server.GameTicking.Rules.Components; @@ -26,7 +26,7 @@ public sealed partial class TraitorRuleComponent : Component public SelectionState SelectionStatus = SelectionState.WaitingForSpawn; public TimeSpan AnnounceAt = TimeSpan.Zero; - public Dictionary StartCandidates = new(); + public Dictionary StartCandidates = new(); /// /// Path to antagonist alert sound. diff --git a/Content.Server/GameTicking/Rules/InactivityTimeRestartRuleSystem.cs b/Content.Server/GameTicking/Rules/InactivityTimeRestartRuleSystem.cs index c2e91ba4a5..b775b7af56 100644 --- a/Content.Server/GameTicking/Rules/InactivityTimeRestartRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/InactivityTimeRestartRuleSystem.cs @@ -2,6 +2,7 @@ using System.Threading; using Content.Server.Chat.Managers; using Content.Server.GameTicking.Rules.Components; using Robust.Server.Player; +using Robust.Shared.Player; using Timer = Robust.Shared.Timing.Timer; namespace Content.Server.GameTicking.Rules; diff --git a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs index 13d4ed71c8..4d3eee81e2 100644 --- a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs @@ -602,11 +602,11 @@ public sealed class NukeopsRuleSystem : GameRuleSystem var maxOperatives = nukeops.MaxOps; // Dear lord what is happening HERE. - var everyone = new List(ev.PlayerPool); - var prefList = new List(); - var medPrefList = new List(); - var cmdrPrefList = new List(); - var operatives = new List(); + var everyone = new List(ev.PlayerPool); + var prefList = new List(); + var medPrefList = new List(); + var cmdrPrefList = new List(); + var operatives = new List(); // The LINQ expression ReSharper keeps suggesting is completely unintelligible so I'm disabling it // ReSharper disable once ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator @@ -637,7 +637,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem for (var i = 0; i < numNukies; i++) { // TODO: Please fix this if you touch it. - IPlayerSession nukeOp; + ICommonSession nukeOp; // Only one commander, so we do it at the start if (i == 0) { @@ -908,7 +908,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem _npcFaction.AddFaction(mob, "Syndicate"); } - private void SpawnOperatives(int spawnCount, List sessions, bool addSpawnPoints, NukeopsRuleComponent component) + private void SpawnOperatives(int spawnCount, List sessions, bool addSpawnPoints, NukeopsRuleComponent component) { if (component.NukieOutpost == null) return; @@ -987,10 +987,10 @@ public sealed class NukeopsRuleSystem : GameRuleSystem var playersPerOperative = component.PlayersPerOperative; var maxOperatives = component.MaxOps; - var playerPool = _playerManager.ServerSessions.ToList(); + var playerPool = _playerManager.Sessions.ToList(); var numNukies = MathHelper.Clamp(playerPool.Count / playersPerOperative, 1, maxOperatives); - var operatives = new List(); + var operatives = new List(); SpawnOperatives(numNukies, operatives, true, component); } diff --git a/Content.Server/GameTicking/Rules/PiratesRuleSystem.cs b/Content.Server/GameTicking/Rules/PiratesRuleSystem.cs index b223161c10..0785d81d09 100644 --- a/Content.Server/GameTicking/Rules/PiratesRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/PiratesRuleSystem.cs @@ -15,10 +15,10 @@ using Content.Shared.Preferences; using Content.Shared.Roles; using Robust.Server.GameObjects; using Robust.Server.Maps; -using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Map; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Utility; @@ -141,7 +141,7 @@ public sealed class PiratesRuleSystem : GameRuleSystem (int) Math.Min( Math.Floor((double) ev.PlayerPool.Count / _cfg.GetCVar(CCVars.PiratesPlayersPerOp)), _cfg.GetCVar(CCVars.PiratesMaxOps))); - var ops = new IPlayerSession[numOps]; + var ops = new ICommonSession[numOps]; for (var i = 0; i < numOps; i++) { ops[i] = _random.PickAndTake(ev.PlayerPool); diff --git a/Content.Server/GameTicking/Rules/RespawnRuleSystem.cs b/Content.Server/GameTicking/Rules/RespawnRuleSystem.cs index a286808623..738883fff3 100644 --- a/Content.Server/GameTicking/Rules/RespawnRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/RespawnRuleSystem.cs @@ -6,6 +6,7 @@ using Content.Shared.Chat; using Content.Shared.Interaction.Events; using Content.Shared.Mind; using Content.Shared.Mobs; +using Content.Shared.Players; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Network; diff --git a/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs b/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs index 01317dbfc1..ef949d09fc 100644 --- a/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs @@ -17,9 +17,8 @@ using Content.Shared.PDA; using Content.Shared.Preferences; using Content.Shared.Roles; using Content.Shared.Roles.Jobs; -using Robust.Server.Player; using Robust.Shared.Configuration; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -151,9 +150,9 @@ public sealed class TraitorRuleSystem : GameRuleSystem } } - private List FindPotentialTraitors(in Dictionary candidates, TraitorRuleComponent component) + private List FindPotentialTraitors(in Dictionary candidates, TraitorRuleComponent component) { - var list = new List(); + var list = new List(); var pendingQuery = GetEntityQuery(); foreach (var player in candidates.Keys) @@ -171,7 +170,7 @@ public sealed class TraitorRuleSystem : GameRuleSystem list.Add(player); } - var prefList = new List(); + var prefList = new List(); foreach (var player in list) { @@ -189,9 +188,9 @@ public sealed class TraitorRuleSystem : GameRuleSystem return prefList; } - private List PickTraitors(int traitorCount, List prefList) + private List PickTraitors(int traitorCount, List prefList) { - var results = new List(traitorCount); + var results = new List(traitorCount); if (prefList.Count == 0) { Log.Info("Insufficient ready players to fill up with traitors, stopping the selection."); diff --git a/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs b/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs index 82ae4b8fa6..a4febc385c 100644 --- a/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs @@ -23,7 +23,7 @@ using Content.Shared.Zombies; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Configuration; -using Robust.Shared.Prototypes; +using Robust.Shared.Player; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -264,9 +264,9 @@ public sealed class ZombieRuleSystem : GameRuleSystem return; component.InfectedChosen = true; - var allPlayers = _playerManager.ServerSessions.ToList(); - var playerList = new List(); - var prefList = new List(); + var allPlayers = _playerManager.Sessions.ToList(); + var playerList = new List(); + var prefList = new List(); foreach (var player in allPlayers) { if (player.AttachedEntity == null || !HasComp(player.AttachedEntity) || HasComp(player.AttachedEntity)) @@ -288,7 +288,7 @@ public sealed class ZombieRuleSystem : GameRuleSystem var totalInfected = 0; while (totalInfected < numInfected) { - IPlayerSession zombie; + ICommonSession zombie; if (prefList.Count == 0) { if (playerList.Count == 0) diff --git a/Content.Server/Ghost/Ghost.cs b/Content.Server/Ghost/Ghost.cs index d04b1197af..1453bf3faa 100644 --- a/Content.Server/Ghost/Ghost.cs +++ b/Content.Server/Ghost/Ghost.cs @@ -1,7 +1,6 @@ using Content.Server.GameTicking; using Content.Shared.Administration; using Content.Shared.Mind; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Ghost @@ -17,7 +16,7 @@ namespace Content.Server.Ghost public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("You have no session, you can't ghost."); diff --git a/Content.Server/Ghost/Roles/Components/TakeGhostRoleEvent.cs b/Content.Server/Ghost/Roles/Components/TakeGhostRoleEvent.cs index c97e3be9dc..16d46871fe 100644 --- a/Content.Server/Ghost/Roles/Components/TakeGhostRoleEvent.cs +++ b/Content.Server/Ghost/Roles/Components/TakeGhostRoleEvent.cs @@ -1,4 +1,4 @@ -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.Ghost.Roles.Components; diff --git a/Content.Server/Ghost/Roles/GhostRoleSystem.cs b/Content.Server/Ghost/Roles/GhostRoleSystem.cs index 5a4cc176f2..f372cb4f62 100644 --- a/Content.Server/Ghost/Roles/GhostRoleSystem.cs +++ b/Content.Server/Ghost/Roles/GhostRoleSystem.cs @@ -4,7 +4,6 @@ using Content.Server.Ghost.Roles.Components; using Content.Server.Ghost.Roles.Events; using Content.Server.Ghost.Roles.UI; using Content.Server.Mind.Commands; -using Content.Server.Players; using Content.Shared.Administration; using Content.Shared.Database; using Content.Shared.Follower; @@ -14,13 +13,14 @@ using Content.Shared.Ghost.Roles; using Content.Shared.Mind; using Content.Shared.Mind.Components; using Content.Shared.Mobs; +using Content.Shared.Players; using Content.Shared.Roles; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Random; using Robust.Shared.Utility; @@ -97,7 +97,7 @@ namespace Content.Server.Ghost.Roles return unchecked(_nextRoleIdentifier++); } - public void OpenEui(IPlayerSession session) + public void OpenEui(ICommonSession session) { if (session.AttachedEntity is not {Valid: true} attached || !EntityManager.HasComponent(attached)) @@ -111,7 +111,7 @@ namespace Content.Server.Ghost.Roles eui.StateDirty(); } - public void OpenMakeGhostRoleEui(IPlayerSession session, EntityUid uid) + public void OpenMakeGhostRoleEui(ICommonSession session, EntityUid uid) { if (session.AttachedEntity == null) return; @@ -420,7 +420,7 @@ namespace Content.Server.Ghost.Roles public void Execute(IConsoleShell shell, string argStr, string[] args) { if(shell.Player != null) - EntitySystem.Get().OpenEui((IPlayerSession)shell.Player); + EntitySystem.Get().OpenEui(shell.Player); else shell.WriteLine("You can only open the ghost roles UI on a client."); } diff --git a/Content.Server/Gravity/GravityGeneratorSystem.cs b/Content.Server/Gravity/GravityGeneratorSystem.cs index 48002fb823..0bd159f61a 100644 --- a/Content.Server/Gravity/GravityGeneratorSystem.cs +++ b/Content.Server/Gravity/GravityGeneratorSystem.cs @@ -6,7 +6,7 @@ using Content.Shared.Database; using Content.Shared.Gravity; using Content.Shared.Interaction; using Robust.Server.GameObjects; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.Gravity { @@ -139,7 +139,7 @@ namespace Content.Server.Gravity return; if (session is { AttachedEntity: { } }) - _adminLogger.Add(LogType.Action, on ? LogImpact.Medium : LogImpact.High, $"{ToPrettyString(session.AttachedEntity.Value):player} set ${ToPrettyString(uid):target} to {(on ? "on" : "off")}"); + _adminLogger.Add(LogType.Action, on ? LogImpact.Medium : LogImpact.High, $"{session:player} set ${ToPrettyString(uid):target} to {(on ? "on" : "off")}"); component.SwitchedOn = on; UpdatePowerState(component, powerReceiver); diff --git a/Content.Server/Hands/Systems/HandsSystem.cs b/Content.Server/Hands/Systems/HandsSystem.cs index b5b01ac001..e3e6699537 100644 --- a/Content.Server/Hands/Systems/HandsSystem.cs +++ b/Content.Server/Hands/Systems/HandsSystem.cs @@ -18,12 +18,11 @@ using Content.Shared.Pulling.Components; using Content.Shared.Stacks; using Content.Shared.Storage; using Content.Shared.Throwing; -using Robust.Server.Player; using Robust.Shared.Containers; using Robust.Shared.GameStates; using Robust.Shared.Input.Binding; using Robust.Shared.Map; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Server.Hands.Systems @@ -159,9 +158,9 @@ namespace Content.Server.Hands.Systems #endregion #region interactions - private bool HandleThrowItem(ICommonSession? session, EntityCoordinates coordinates, EntityUid entity) + private bool HandleThrowItem(ICommonSession? playerSession, EntityCoordinates coordinates, EntityUid entity) { - if (session is not IPlayerSession playerSession) + if (playerSession == null) return false; if (playerSession.AttachedEntity is not {Valid: true} player || @@ -220,7 +219,7 @@ namespace Content.Server.Hands.Systems // TODO: move to storage or inventory private void HandleSmartEquip(ICommonSession? session, string equipmentSlot) { - if (session is not IPlayerSession playerSession) + if (session is not { } playerSession) return; if (playerSession.AttachedEntity is not {Valid: true} plyEnt || !Exists(plyEnt)) diff --git a/Content.Server/Humanoid/Systems/HumanoidAppearanceSystem.Modifier.cs b/Content.Server/Humanoid/Systems/HumanoidAppearanceSystem.Modifier.cs index 7c0bb7383b..b47fe71714 100644 --- a/Content.Server/Humanoid/Systems/HumanoidAppearanceSystem.Modifier.cs +++ b/Content.Server/Humanoid/Systems/HumanoidAppearanceSystem.Modifier.cs @@ -3,7 +3,6 @@ using Content.Shared.Administration; using Content.Shared.Humanoid; using Content.Shared.Verbs; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Utility; namespace Content.Server.Humanoid; @@ -48,7 +47,7 @@ public sealed partial class HumanoidAppearanceSystem private void OnBaseLayersSet(EntityUid uid, HumanoidAppearanceComponent component, HumanoidMarkingModifierBaseLayersSetMessage message) { - if (message.Session is not IPlayerSession player + if (message.Session is not { } player || !_adminManager.HasAdminFlag(player, AdminFlags.Fun)) { return; @@ -81,7 +80,7 @@ public sealed partial class HumanoidAppearanceSystem private void OnMarkingsSet(EntityUid uid, HumanoidAppearanceComponent component, HumanoidMarkingModifierMarkingSetMessage message) { - if (message.Session is not IPlayerSession player + if (message.Session is not { } player || !_adminManager.HasAdminFlag(player, AdminFlags.Fun)) { return; diff --git a/Content.Server/Instruments/InstrumentComponent.cs b/Content.Server/Instruments/InstrumentComponent.cs index 810d265314..4302ab6791 100644 --- a/Content.Server/Instruments/InstrumentComponent.cs +++ b/Content.Server/Instruments/InstrumentComponent.cs @@ -1,7 +1,7 @@ using Content.Server.UserInterface; using Content.Shared.Instruments; using Robust.Server.GameObjects; -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Instruments; @@ -17,7 +17,7 @@ public sealed partial class InstrumentComponent : SharedInstrumentComponent [ViewVariables] public uint LastSequencerTick = 0; // TODO Instruments: Make this ECS - public IPlayerSession? InstrumentPlayer => + public ICommonSession? InstrumentPlayer => _entMan.GetComponentOrNull(Owner)?.CurrentSingleUser ?? _entMan.GetComponentOrNull(Owner)?.PlayerSession; } diff --git a/Content.Server/Instruments/InstrumentSystem.cs b/Content.Server/Instruments/InstrumentSystem.cs index ec23382105..6f8369182c 100644 --- a/Content.Server/Instruments/InstrumentSystem.cs +++ b/Content.Server/Instruments/InstrumentSystem.cs @@ -9,12 +9,12 @@ using Content.Shared.Physics; using Content.Shared.Popups; using JetBrains.Annotations; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Audio.Midi; using Robust.Shared.Collections; using Robust.Shared.Configuration; using Robust.Shared.Console; using Robust.Shared.GameStates; +using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.Instruments; @@ -385,7 +385,7 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem var nearby = GetBands(entity); _bui.TrySendUiMessage(entity, request.UiKey, new InstrumentBandResponseBuiMessage(nearby), - (IPlayerSession)request.Session); + request.Session); } _bandRequestQueue.Clear(); @@ -447,7 +447,7 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem } } - public void ToggleInstrumentUi(EntityUid uid, IPlayerSession session, InstrumentComponent? component = null) + public void ToggleInstrumentUi(EntityUid uid, ICommonSession session, InstrumentComponent? component = null) { if (!Resolve(uid, ref component)) return; diff --git a/Content.Server/Interaction/InteractionSystem.cs b/Content.Server/Interaction/InteractionSystem.cs index a612b73840..9237a1f7dd 100644 --- a/Content.Server/Interaction/InteractionSystem.cs +++ b/Content.Server/Interaction/InteractionSystem.cs @@ -13,7 +13,6 @@ using Robust.Server.GameObjects; using Robust.Shared.Containers; using Robust.Shared.Input.Binding; using Robust.Shared.Map; -using Robust.Shared.Players; using Robust.Shared.Random; namespace Content.Server.Interaction diff --git a/Content.Server/Interaction/TilePryCommand.cs b/Content.Server/Interaction/TilePryCommand.cs index 4fe3599df9..fa75b6d9e4 100644 --- a/Content.Server/Interaction/TilePryCommand.cs +++ b/Content.Server/Interaction/TilePryCommand.cs @@ -1,10 +1,7 @@ using System.Numerics; using Content.Server.Administration; -using Content.Server.Tools.Components; using Content.Shared.Administration; using Content.Shared.Maps; -using Content.Shared.Tools.Components; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; @@ -24,7 +21,7 @@ namespace Content.Server.Interaction public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player?.AttachedEntity is not {} attached) { return; diff --git a/Content.Server/MagicMirror/MagicMirrorSystem.cs b/Content.Server/MagicMirror/MagicMirrorSystem.cs index 90a0b19b7d..a599a2c868 100644 --- a/Content.Server/MagicMirror/MagicMirrorSystem.cs +++ b/Content.Server/MagicMirror/MagicMirrorSystem.cs @@ -5,8 +5,7 @@ using Content.Shared.Humanoid; using Content.Shared.Humanoid.Markings; using Content.Shared.MagicMirror; using Robust.Server.GameObjects; -using Robust.Server.Player; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.MagicMirror; @@ -147,7 +146,7 @@ public sealed class MagicMirrorSystem : EntitySystem private void UpdateInterface(EntityUid uid, EntityUid playerUid, ICommonSession session, HumanoidAppearanceComponent? humanoid = null) { - if (!Resolve(playerUid, ref humanoid) || session is not IPlayerSession player) + if (!Resolve(playerUid, ref humanoid) || session is not { } player) { return; } diff --git a/Content.Server/Mapping/MappingCommand.cs b/Content.Server/Mapping/MappingCommand.cs index e4a4cd8942..d72a5c4178 100644 --- a/Content.Server/Mapping/MappingCommand.cs +++ b/Content.Server/Mapping/MappingCommand.cs @@ -40,7 +40,7 @@ namespace Content.Server.Mapping public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError(Loc.GetString("cmd-savemap-server")); return; diff --git a/Content.Server/Maps/GridDraggingSystem.cs b/Content.Server/Maps/GridDraggingSystem.cs index 90770af1ad..7d7b61955b 100644 --- a/Content.Server/Maps/GridDraggingSystem.cs +++ b/Content.Server/Maps/GridDraggingSystem.cs @@ -1,10 +1,9 @@ using Content.Shared.Maps; using Robust.Server.Console; -using Robust.Server.Player; -using Robust.Shared.Players; using Robust.Shared.Utility; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; +using Robust.Shared.Player; namespace Content.Server.Maps; @@ -27,7 +26,7 @@ public sealed class GridDraggingSystem : SharedGridDraggingSystem public void Toggle(ICommonSession session) { - if (session is not IPlayerSession pSession) + if (session is not { } pSession) return; DebugTools.Assert(_admin.CanCommand(pSession, CommandName)); @@ -52,7 +51,7 @@ public sealed class GridDraggingSystem : SharedGridDraggingSystem { var grid = GetEntity(ev.Grid); - if (args.SenderSession is not IPlayerSession playerSession || + if (args.SenderSession is not { } playerSession || !_admin.CanCommand(playerSession, CommandName) || !Exists(grid) || Deleted(grid)) @@ -69,7 +68,7 @@ public sealed class GridDraggingSystem : SharedGridDraggingSystem { var grid = GetEntity(msg.Grid); - if (args.SenderSession is not IPlayerSession playerSession || + if (args.SenderSession is not { } playerSession || !_admin.CanCommand(playerSession, CommandName) || !Exists(grid) || Deleted(grid)) diff --git a/Content.Server/Medical/DefibrillatorSystem.cs b/Content.Server/Medical/DefibrillatorSystem.cs index 4ffa9f558d..d041f8ee9d 100644 --- a/Content.Server/Medical/DefibrillatorSystem.cs +++ b/Content.Server/Medical/DefibrillatorSystem.cs @@ -18,7 +18,7 @@ using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; using Content.Shared.Timing; using Content.Shared.Toggleable; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.Medical; diff --git a/Content.Server/Mind/Commands/RenameCommand.cs b/Content.Server/Mind/Commands/RenameCommand.cs index 5674da4ffd..2d65adc508 100644 --- a/Content.Server/Mind/Commands/RenameCommand.cs +++ b/Content.Server/Mind/Commands/RenameCommand.cs @@ -54,6 +54,7 @@ public sealed class RenameCommand : IConsoleCommand { // Mind mind.CharacterName = name; + _entManager.Dirty(mindId, mind); } // Id Cards diff --git a/Content.Server/Mind/MindSystem.cs b/Content.Server/Mind/MindSystem.cs index 373007fd1b..f23e9b6407 100644 --- a/Content.Server/Mind/MindSystem.cs +++ b/Content.Server/Mind/MindSystem.cs @@ -1,6 +1,7 @@ using System.Diagnostics.CodeAnalysis; using Content.Server.Administration.Logs; using Content.Server.GameTicking; +using Content.Server.Mind.Commands; using Content.Shared.Database; using Content.Shared.Ghost; using Content.Shared.Mind; @@ -10,7 +11,9 @@ using Robust.Server.GameObjects; using Robust.Server.GameStates; using Robust.Server.Player; using Robust.Shared.Map; +using Robust.Shared.Map.Components; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -46,20 +49,14 @@ public sealed class MindSystem : SharedMindSystem mind.UserId = null; } - if (!TryComp(mind.OwnedEntity, out MetaDataComponent? meta) || meta.EntityLifeStage >= EntityLifeStage.Terminating) - return; + if (mind.OwnedEntity != null && !TerminatingOrDeleted(mind.OwnedEntity.Value)) + TransferTo(uid, null, mind: mind, createGhost: false); - RaiseLocalEvent(mind.OwnedEntity.Value, new MindRemovedMessage(uid, mind), true); mind.OwnedEntity = null; - mind.OwnedComponent = null; } private void OnMindContainerTerminating(EntityUid uid, MindContainerComponent component, ref EntityTerminatingEvent args) { - // Let's not create ghosts if not in the middle of the round. - if (_gameTicker.RunLevel == GameRunLevel.PreRoundLobby) - return; - if (!TryGetMind(uid, out var mindId, out var mind, component)) return; @@ -76,46 +73,45 @@ public sealed class MindSystem : SharedMindSystem } TransferTo(mindId, null, createGhost: false, mind: mind); + DebugTools.AssertNull(mind.OwnedEntity); - if (component.GhostOnShutdown && mind.Session != null) + if (!component.GhostOnShutdown || mind.Session == null || _gameTicker.RunLevel == GameRunLevel.PreRoundLobby) + return; + + var xform = Transform(uid); + var gridId = xform.GridUid; + var spawnPosition = Transform(uid).Coordinates; + + // Use a regular timer here because the entity has probably been deleted. + Timer.Spawn(0, () => { - var xform = Transform(uid); - var gridId = xform.GridUid; - var spawnPosition = Transform(uid).Coordinates; + // Make extra sure the round didn't end between spawning the timer and it being executed. + if (_gameTicker.RunLevel == GameRunLevel.PreRoundLobby) + return; - // Use a regular timer here because the entity has probably been deleted. - Timer.Spawn(0, () => + // Async this so that we don't throw if the grid we're on is being deleted. + if (!HasComp(gridId)) + spawnPosition = _gameTicker.GetObserverSpawnPoint(); + + // TODO refactor observer spawning. + // please. + if (!spawnPosition.IsValid(EntityManager)) { - // Make extra sure the round didn't end between spawning the timer and it being executed. - if (_gameTicker.RunLevel == GameRunLevel.PreRoundLobby) - return; + // This should be an error, if it didn't cause tests to start erroring when they delete a player. + Log.Warning($"Entity \"{ToPrettyString(uid)}\" for {mind.CharacterName} was deleted, and no applicable spawn location is available."); + TransferTo(mindId, null, createGhost: false, mind: mind); + return; + } - // Async this so that we don't throw if the grid we're on is being deleted. - if (!_maps.GridExists(gridId)) - spawnPosition = _gameTicker.GetObserverSpawnPoint(); + var ghost = Spawn(GameTicker.ObserverPrototypeName, spawnPosition); + var ghostComponent = Comp(ghost); + _ghosts.SetCanReturnToBody(ghostComponent, false); - // TODO refactor observer spawning. - // please. - if (!spawnPosition.IsValid(EntityManager)) - { - // This should be an error, if it didn't cause tests to start erroring when they delete a player. - Log.Warning($"Entity \"{ToPrettyString(uid)}\" for {mind.CharacterName} was deleted, and no applicable spawn location is available."); - TransferTo(mindId, null, createGhost: false, mind: mind); - return; - } - - var ghost = Spawn("MobObserver", spawnPosition); - var ghostComponent = Comp(ghost); - _ghosts.SetCanReturnToBody(ghostComponent, false); - - // Log these to make sure they're not causing the GameTicker round restart bugs... - Log.Debug($"Entity \"{ToPrettyString(uid)}\" for {mind.CharacterName} was deleted, spawned \"{ToPrettyString(ghost)}\"."); - - var val = mind.CharacterName ?? string.Empty; - _metaData.SetEntityName(ghost, val); - TransferTo(mindId, ghost, mind: mind); - }); - } + // Log these to make sure they're not causing the GameTicker round restart bugs... + Log.Debug($"Entity \"{ToPrettyString(uid)}\" for {mind.CharacterName} was deleted, spawned \"{ToPrettyString(ghost)}\"."); + _metaData.SetEntityName(ghost, mind.CharacterName ?? string.Empty); + TransferTo(mindId, ghost, mind: mind); + }); } public override bool TryGetMind(NetUserId user, [NotNullWhen(true)] out EntityUid? mindId, [NotNullWhen(true)] out MindComponent? mind) @@ -130,18 +126,18 @@ public sealed class MindSystem : SharedMindSystem return false; } - public bool TryGetSession(EntityUid? mindId, [NotNullWhen(true)] out IPlayerSession? session) + public bool TryGetSession(EntityUid? mindId, [NotNullWhen(true)] out ICommonSession? session) { session = null; - return TryComp(mindId, out MindComponent? mind) && (session = (IPlayerSession?) mind.Session) != null; + return TryComp(mindId, out MindComponent? mind) && (session = mind.Session) != null; } - public IPlayerSession? GetSession(MindComponent mind) + public ICommonSession? GetSession(MindComponent mind) { - return (IPlayerSession?) mind.Session; + return mind.Session; } - public bool TryGetSession(MindComponent mind, [NotNullWhen(true)] out IPlayerSession? session) + public bool TryGetSession(MindComponent mind, [NotNullWhen(true)] out ICommonSession? session) { return (session = GetSession(mind)) != null; } @@ -179,7 +175,9 @@ public sealed class MindSystem : SharedMindSystem return; } - GetSession(mind)?.AttachToEntity(entity); + if (GetSession(mind) is { } session) + _actor.Attach(entity, session); + mind.VisitingEntity = entity; // EnsureComp instead of AddComp to deal with deferred deletions. @@ -198,13 +196,14 @@ public sealed class MindSystem : SharedMindSystem if (mind.VisitingEntity == null) return; - RemoveVisitingEntity(mind); + RemoveVisitingEntity(mindId, mind); if (mind.Session == null || mind.Session.AttachedEntity == mind.VisitingEntity) return; var owned = mind.OwnedEntity; - GetSession(mind)?.AttachToEntity(owned); + if (GetSession(mind) is { } session) + _actor.Attach(owned, session); if (owned.HasValue) { @@ -219,11 +218,10 @@ public sealed class MindSystem : SharedMindSystem if (mind == null && !Resolve(mindId, ref mind)) return; - base.TransferTo(mindId, entity, ghostCheckOverride, createGhost, mind); - if (entity == mind.OwnedEntity) return; + Dirty(mindId, mind); MindContainerComponent? component = null; var alreadyAttached = false; @@ -247,27 +245,33 @@ public sealed class MindSystem : SharedMindSystem } else if (createGhost) { + // TODO remove this option. + // Transfer-to-null should just detach a mind. + // If people want to create a ghost, that should be done explicitly via some TransferToGhost() method, not + // not implicitly via optional arguments. + var position = Deleted(mind.OwnedEntity) ? _gameTicker.GetObserverSpawnPoint().ToMap(EntityManager, _transform) : Transform(mind.OwnedEntity.Value).MapPosition; entity = Spawn("MobObserver", position); + component = EnsureComp(entity.Value); var ghostComponent = Comp(entity.Value); _ghosts.SetCanReturnToBody(ghostComponent, false); } - var oldComp = mind.OwnedComponent; var oldEntity = mind.OwnedEntity; - if (oldComp != null && oldEntity != null) + if (TryComp(oldEntity, out MindContainerComponent? oldContainer)) { - if (oldComp.Mind != null) - _pvsOverride.ClearOverride(oldComp.Mind.Value); - oldComp.Mind = null; - RaiseLocalEvent(oldEntity.Value, new MindRemovedMessage(oldEntity.Value, mind), true); + oldContainer.Mind = null; + mind.OwnedEntity = null; + Entity mindEnt = (mindId, mind); + Entity containerEnt = (oldEntity.Value, oldContainer); + RaiseLocalEvent(oldEntity.Value, new MindRemovedMessage(mindEnt, containerEnt)); + RaiseLocalEvent(mindId, new MindGotRemovedEvent(mindEnt, containerEnt)); + Dirty(oldEntity.Value, oldContainer); } - SetOwnedEntity(mind, entity, component); - // Don't do the full deletion cleanup if we're transferring to our VisitingEntity if (alreadyAttached) { @@ -281,7 +285,7 @@ public sealed class MindSystem : SharedMindSystem || !TryComp(mind.VisitingEntity!, out GhostComponent? ghostComponent) // visiting entity is not a Ghost || !ghostComponent.CanReturnToBody)) // it is a ghost, but cannot return to body anyway, so it's okay { - RemoveVisitingEntity(mind); + RemoveVisitingEntity(mindId, mind); } // Player is CURRENTLY connected. @@ -289,14 +293,20 @@ public sealed class MindSystem : SharedMindSystem if (session != null && !alreadyAttached && mind.VisitingEntity == null) { _actor.Attach(entity, session, true); + DebugTools.Assert(session.AttachedEntity == entity, $"Failed to attach entity."); Log.Info($"Session {session.Name} transferred to entity {entity}."); } - if (mind.OwnedComponent != null) + if (entity != null) { - mind.OwnedComponent.Mind = mindId; - RaiseLocalEvent(mind.OwnedEntity!.Value, new MindAddedMessage(), true); - mind.OriginalOwnedEntity ??= mind.OwnedEntity; + component!.Mind = mindId; + mind.OwnedEntity = entity; + mind.OriginalOwnedEntity ??= GetNetEntity(mind.OwnedEntity); + Entity mindEnt = (mindId, mind); + Entity containerEnt = (entity.Value, component); + RaiseLocalEvent(entity.Value, new MindAddedMessage(mindEnt, containerEnt)); + RaiseLocalEvent(mindId, new MindGotAddedEvent(mindEnt, containerEnt)); + Dirty(entity.Value, component); } } @@ -313,6 +323,7 @@ public sealed class MindSystem : SharedMindSystem if (mind.UserId == userId) return; + Dirty(mindId, mind); _pvsOverride.ClearOverride(mindId); if (userId != null && !_players.TryGetPlayerData(userId.Value, out _)) { @@ -363,4 +374,27 @@ public sealed class MindSystem : SharedMindSystem if (_players.GetPlayerData(userId.Value).ContentData() is { } data) data.Mind = mindId; } + + public void ControlMob(EntityUid user, EntityUid target) + { + if (TryComp(user, out ActorComponent? actor)) + ControlMob(actor.PlayerSession.UserId, target); + } + + public void ControlMob(NetUserId user, EntityUid target) + { + var (mindId, mind) = GetOrCreateMind(user); + + if (mind.CurrentEntity == target) + return; + + if (mind.OwnedEntity == target) + { + UnVisit(mindId, mind); + return; + } + + MakeSentientCommand.MakeSentient(target, EntityManager); + TransferTo(mindId, target, ghostCheckOverride: true, mind: mind); + } } diff --git a/Content.Server/Mind/Toolshed/MindCommand.cs b/Content.Server/Mind/Toolshed/MindCommand.cs index b53f9a6a9c..917e6fb7f1 100644 --- a/Content.Server/Mind/Toolshed/MindCommand.cs +++ b/Content.Server/Mind/Toolshed/MindCommand.cs @@ -1,5 +1,5 @@ using Content.Shared.Mind; -using Robust.Server.Player; +using Robust.Shared.Player; using Robust.Shared.Toolshed; using Robust.Shared.Toolshed.Errors; using Robust.Shared.Toolshed.Syntax; @@ -15,7 +15,7 @@ public sealed class MindCommand : ToolshedCommand private SharedMindSystem? _mind; [CommandImplementation("get")] - public MindComponent? Get([PipedArgument] IPlayerSession session) + public MindComponent? Get([PipedArgument] ICommonSession session) { _mind ??= GetSys(); return _mind.TryGetMind(session, out _, out var mind) ? mind : null; @@ -32,7 +32,7 @@ public sealed class MindCommand : ToolshedCommand public EntityUid Control( [CommandInvocationContext] IInvocationContext ctx, [PipedArgument] EntityUid target, - [CommandArgument] ValueRef playerRef) + [CommandArgument] ValueRef playerRef) { _mind ??= GetSys(); diff --git a/Content.Server/Motd/MOTDCommand.cs b/Content.Server/Motd/MOTDCommand.cs index a1aa4d2df5..9e59589b95 100644 --- a/Content.Server/Motd/MOTDCommand.cs +++ b/Content.Server/Motd/MOTDCommand.cs @@ -1,6 +1,5 @@ using Content.Server.Administration.Managers; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Motd; @@ -14,10 +13,10 @@ internal sealed class MOTDCommand : LocalizedCommands [Dependency] private readonly IAdminManager _adminManager = default!; public override string Command => "motd"; - + public override void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = (IPlayerSession?)shell.Player; + var player = shell.Player; if (args.Length < 1 || (player != null && _adminManager is AdminManager aMan && !aMan.CanCommand(player, "set-motd"))) shell.ConsoleHost.ExecuteCommand(shell.Player, "get-motd"); else @@ -26,7 +25,7 @@ internal sealed class MOTDCommand : LocalizedCommands public override CompletionResult GetCompletion(IConsoleShell shell, string[] args) { - var player = (IPlayerSession?)shell.Player; + var player = shell.Player; if (player != null && _adminManager is AdminManager aMan && !aMan.CanCommand(player, "set-motd")) return CompletionResult.Empty; if (args.Length == 1) diff --git a/Content.Server/Motd/MOTDSystem.cs b/Content.Server/Motd/MOTDSystem.cs index e749fe48f3..39d780f108 100644 --- a/Content.Server/Motd/MOTDSystem.cs +++ b/Content.Server/Motd/MOTDSystem.cs @@ -2,9 +2,9 @@ using Content.Server.Chat.Managers; using Content.Server.GameTicking; using Content.Shared.CCVar; using Content.Shared.Chat; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Configuration; +using Robust.Shared.Player; namespace Content.Server.Motd; @@ -41,7 +41,7 @@ public sealed class MOTDSystem : EntitySystem { if (string.IsNullOrEmpty(_messageOfTheDay)) return; - + var wrappedMessage = Loc.GetString("motd-wrap-message", ("motd", _messageOfTheDay)); _chatManager.ChatMessageToAll(ChatChannel.Server, _messageOfTheDay, wrappedMessage, source: EntityUid.Invalid, hideChat: false, recordReplay: true); } @@ -49,11 +49,11 @@ public sealed class MOTDSystem : EntitySystem /// /// Sends the Message Of The Day, if any, to a specific player. /// - public void TrySendMOTD(IPlayerSession player) + public void TrySendMOTD(ICommonSession player) { if (string.IsNullOrEmpty(_messageOfTheDay)) return; - + var wrappedMessage = Loc.GetString("motd-wrap-message", ("motd", _messageOfTheDay)); _chatManager.ChatMessageToOne(ChatChannel.Server, _messageOfTheDay, wrappedMessage, source: EntityUid.Invalid, hideChat: false, client: player.ConnectedClient); } @@ -68,10 +68,10 @@ public sealed class MOTDSystem : EntitySystem { if (string.IsNullOrEmpty(_messageOfTheDay)) return; - + var wrappedMessage = Loc.GetString("motd-wrap-message", ("motd", _messageOfTheDay)); shell.WriteLine(wrappedMessage); - if (shell.Player is IPlayerSession player) + if (shell.Player is { } player) _chatManager.ChatMessageToOne(ChatChannel.Server, _messageOfTheDay, wrappedMessage, source: EntityUid.Invalid, hideChat: false, client: player.ConnectedClient); } @@ -92,7 +92,7 @@ public sealed class MOTDSystem : EntitySystem { if (val == _messageOfTheDay) return; - + _messageOfTheDay = val; TrySendMOTD(); } diff --git a/Content.Server/Motd/SetMOTDCommand.cs b/Content.Server/Motd/SetMOTDCommand.cs index f3f52b0670..9678781c87 100644 --- a/Content.Server/Motd/SetMOTDCommand.cs +++ b/Content.Server/Motd/SetMOTDCommand.cs @@ -4,7 +4,6 @@ using Content.Shared.Administration; using Content.Shared.Database; using Content.Shared.CCVar; using Content.Server.Chat.Managers; -using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Console; @@ -21,18 +20,18 @@ public sealed class SetMotdCommand : LocalizedCommands [Dependency] private readonly IConfigurationManager _configurationManager = default!; public override string Command => "set-motd"; - + public override void Execute(IConsoleShell shell, string argStr, string[] args) { string motd = ""; - var player = (IPlayerSession?)shell.Player; + var player = shell.Player; if (args.Length > 0) { motd = string.Join(" ", args).Trim(); if (player != null && _chatManager.MessageCharacterLimit(player, motd)) return; // check function prints its own error response } - + _configurationManager.SetCVar(CCVars.MOTD, motd); // A hook in MOTDSystem broadcasts changes to the MOTD to everyone so we don't need to do it here. if (string.IsNullOrEmpty(motd)) { diff --git a/Content.Server/Movement/Systems/LagCompensationSystem.cs b/Content.Server/Movement/Systems/LagCompensationSystem.cs index 64965c2fee..0576fe8f25 100644 --- a/Content.Server/Movement/Systems/LagCompensationSystem.cs +++ b/Content.Server/Movement/Systems/LagCompensationSystem.cs @@ -1,7 +1,7 @@ using Content.Server.Movement.Components; using Robust.Server.Player; using Robust.Shared.Map; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.Movement.Systems; diff --git a/Content.Server/NPC/Commands/NPCCommand.cs b/Content.Server/NPC/Commands/NPCCommand.cs index 57fe223b66..7f9e56b8ca 100644 --- a/Content.Server/NPC/Commands/NPCCommand.cs +++ b/Content.Server/NPC/Commands/NPCCommand.cs @@ -2,7 +2,6 @@ using Content.Server.Administration; using Content.Server.EUI; using Content.Server.NPC.UI; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.NPC.Commands; @@ -15,7 +14,7 @@ public sealed class NPCCommand : IConsoleCommand public string Help => $"{Command}"; public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession playerSession) + if (shell.Player is not { } playerSession) { return; } diff --git a/Content.Server/NPC/HTN/HTNSystem.cs b/Content.Server/NPC/HTN/HTNSystem.cs index 2c1dadb127..a7689fbabe 100644 --- a/Content.Server/NPC/HTN/HTNSystem.cs +++ b/Content.Server/NPC/HTN/HTNSystem.cs @@ -4,17 +4,14 @@ using System.Threading; using Content.Server.Administration.Managers; using Robust.Shared.CPUJob.JobQueues; using Robust.Shared.CPUJob.JobQueues.Queues; -using Content.Server.NPC.Components; using Content.Server.NPC.HTN.PrimitiveTasks; using Content.Server.NPC.Systems; using Content.Shared.Administration; using Content.Shared.Mobs; using Content.Shared.NPC; -using Content.Shared.NPC; using JetBrains.Annotations; using Robust.Server.GameObjects; -using Robust.Server.Player; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Utility; @@ -48,7 +45,7 @@ public sealed class HTNSystem : EntitySystem private void OnHTNMessage(RequestHTNMessage msg, EntitySessionEventArgs args) { - if (!_admin.HasAdminFlag((IPlayerSession) args.SenderSession, AdminFlags.Debug)) + if (!_admin.HasAdminFlag(args.SenderSession, AdminFlags.Debug)) { _subscribers.Remove(args.SenderSession); return; diff --git a/Content.Server/NPC/Pathfinding/PathfindingSystem.cs b/Content.Server/NPC/Pathfinding/PathfindingSystem.cs index bb0eff7b39..1b1f6f5476 100644 --- a/Content.Server/NPC/Pathfinding/PathfindingSystem.cs +++ b/Content.Server/NPC/Pathfinding/PathfindingSystem.cs @@ -13,7 +13,7 @@ using Robust.Shared.Enums; using Robust.Shared.Map; using Robust.Shared.Physics; using Robust.Shared.Physics.Systems; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Random; using Robust.Shared.Threading; using Robust.Shared.Timing; @@ -528,7 +528,7 @@ namespace Content.Server.NPC.Pathfinding private void OnBreadcrumbs(RequestPathfindingDebugMessage msg, EntitySessionEventArgs args) { - var pSession = (IPlayerSession) args.SenderSession; + var pSession = args.SenderSession; if (!_adminManager.HasAdminFlag(pSession, AdminFlags.Debug)) { diff --git a/Content.Server/NPC/Systems/NPCSteeringSystem.cs b/Content.Server/NPC/Systems/NPCSteeringSystem.cs index 61b43df6f0..e5b62acfe8 100644 --- a/Content.Server/NPC/Systems/NPCSteeringSystem.cs +++ b/Content.Server/NPC/Systems/NPCSteeringSystem.cs @@ -17,14 +17,12 @@ using Content.Shared.NPC; using Content.Shared.NPC.Events; using Content.Shared.Physics; using Content.Shared.Weapons.Melee; -using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Map; using Robust.Shared.Physics; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; using Robust.Shared.Player; -using Robust.Shared.Players; using Robust.Shared.Random; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -147,7 +145,7 @@ public sealed partial class NPCSteeringSystem : SharedNPCSteeringSystem private void OnDebugRequest(RequestNPCSteeringDebugEvent msg, EntitySessionEventArgs args) { - if (!_admin.IsAdmin((IPlayerSession)args.SenderSession)) + if (!_admin.IsAdmin(args.SenderSession)) return; if (msg.Enabled) diff --git a/Content.Server/NodeContainer/EntitySystems/NodeGroupSystem.cs b/Content.Server/NodeContainer/EntitySystems/NodeGroupSystem.cs index e4bd303150..9ee9702c5b 100644 --- a/Content.Server/NodeContainer/EntitySystems/NodeGroupSystem.cs +++ b/Content.Server/NodeContainer/EntitySystems/NodeGroupSystem.cs @@ -9,6 +9,7 @@ using JetBrains.Annotations; using Robust.Server.Player; using Robust.Shared.Enums; using Robust.Shared.Map; +using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Server.NodeContainer.EntitySystems @@ -29,7 +30,7 @@ namespace Content.Server.NodeContainer.EntitySystems private readonly List _visDeletes = new(); private readonly List _visSends = new(); - private readonly HashSet _visPlayers = new(); + private readonly HashSet _visPlayers = new(); private readonly HashSet _toRemake = new(); private readonly HashSet _nodeGroups = new(); private readonly HashSet _toRemove = new(); @@ -74,7 +75,7 @@ namespace Content.Server.NodeContainer.EntitySystems private void HandleEnableMsg(NodeVis.MsgEnable msg, EntitySessionEventArgs args) { - var session = (IPlayerSession) args.SenderSession; + var session = args.SenderSession; if (!_adminManager.HasAdminFlag(session, AdminFlags.Debug)) return; @@ -397,7 +398,7 @@ namespace Content.Server.NodeContainer.EntitySystems } } - private void VisSendFullStateImmediate(IPlayerSession player) + private void VisSendFullStateImmediate(ICommonSession player) { var msg = new NodeVis.MsgData(); diff --git a/Content.Server/Nutrition/Hungry.cs b/Content.Server/Nutrition/Hungry.cs index c27f302a8d..ae68dcd2fd 100644 --- a/Content.Server/Nutrition/Hungry.cs +++ b/Content.Server/Nutrition/Hungry.cs @@ -1,9 +1,7 @@ using Content.Server.Administration; -using Content.Server.Nutrition.Components; using Content.Shared.Administration; using Content.Shared.Nutrition.Components; using Content.Shared.Nutrition.EntitySystems; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Nutrition @@ -19,7 +17,7 @@ namespace Content.Server.Nutrition public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("You cannot use this command unless you are a player."); diff --git a/Content.Server/Objectives/Commands/ListObjectivesCommand.cs b/Content.Server/Objectives/Commands/ListObjectivesCommand.cs index 93dec3fa44..97fc943269 100644 --- a/Content.Server/Objectives/Commands/ListObjectivesCommand.cs +++ b/Content.Server/Objectives/Commands/ListObjectivesCommand.cs @@ -18,7 +18,7 @@ namespace Content.Server.Objectives.Commands public override void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null || !_players.TryGetSessionByUsername(args[0], out player)) { shell.WriteError(LocalizationManager.GetString("shell-target-player-does-not-exist")); diff --git a/Content.Server/PDA/PdaSystem.cs b/Content.Server/PDA/PdaSystem.cs index 6c506dc3dd..44e2659841 100644 --- a/Content.Server/PDA/PdaSystem.cs +++ b/Content.Server/PDA/PdaSystem.cs @@ -4,9 +4,6 @@ using Content.Server.DeviceNetwork.Components; using Content.Server.Instruments; using Content.Server.Light.EntitySystems; using Content.Server.Light.Events; -using Content.Server.MassMedia.Components; -using Content.Server.MassMedia.Systems; -using Content.Server.Mind; using Content.Server.PDA.Ringer; using Content.Server.Station.Systems; using Content.Server.Store.Components; @@ -16,7 +13,6 @@ using Content.Shared.CartridgeLoader; using Content.Shared.Light.Components; using Content.Shared.PDA; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Containers; namespace Content.Server.PDA @@ -180,7 +176,7 @@ namespace Content.Server.PDA return; if (HasComp(uid)) - _ringer.ToggleRingerUI(uid, (IPlayerSession) msg.Session); + _ringer.ToggleRingerUI(uid, msg.Session); } private void OnUiMessage(EntityUid uid, PdaComponent pda, PdaShowMusicMessage msg) @@ -189,7 +185,7 @@ namespace Content.Server.PDA return; if (TryComp(uid, out var instrument)) - _instrument.ToggleInstrumentUi(uid, (IPlayerSession) msg.Session, instrument); + _instrument.ToggleInstrumentUi(uid, msg.Session, instrument); } private void OnUiMessage(EntityUid uid, PdaComponent pda, PdaShowUplinkMessage msg) diff --git a/Content.Server/PDA/Ringer/RingerSystem.cs b/Content.Server/PDA/Ringer/RingerSystem.cs index a772e76bc4..7494d5e12c 100644 --- a/Content.Server/PDA/Ringer/RingerSystem.cs +++ b/Content.Server/PDA/Ringer/RingerSystem.cs @@ -7,7 +7,6 @@ using Content.Shared.PDA.Ringer; using Content.Shared.Popups; using Content.Shared.Store; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Audio; using Robust.Shared.Network; using Robust.Shared.Player; @@ -182,7 +181,7 @@ namespace Content.Server.PDA.Ringer _ui.SetUiState(bui, new RingerUpdateState(isPlaying, ringer.Ringtone)); } - public bool ToggleRingerUI(EntityUid uid, IPlayerSession session) + public bool ToggleRingerUI(EntityUid uid, ICommonSession session) { if (_ui.TryGetUi(uid, RingerUiKey.Key, out var bui)) _ui.ToggleUi(bui, session); diff --git a/Content.Server/Paper/PaperSystem.cs b/Content.Server/Paper/PaperSystem.cs index f38013e14d..553bcaa0a2 100644 --- a/Content.Server/Paper/PaperSystem.cs +++ b/Content.Server/Paper/PaperSystem.cs @@ -4,15 +4,11 @@ using Content.Server.Popups; using Content.Server.UserInterface; using Content.Shared.Database; using Content.Shared.Examine; -using Content.Shared.IdentityManagement; using Content.Shared.Interaction; using Content.Shared.Paper; using Content.Shared.Tag; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Player; -using Robust.Shared.Utility; -using Robust.Shared.Audio; using static Content.Shared.Paper.SharedPaperComponent; namespace Content.Server.Paper @@ -207,7 +203,7 @@ namespace Content.Server.Paper _appearance.SetData(uid, PaperVisuals.Status, status, appearance); } - public void UpdateUserInterface(EntityUid uid, PaperComponent? paperComp = null, IPlayerSession? session = null) + public void UpdateUserInterface(EntityUid uid, PaperComponent? paperComp = null, ICommonSession? session = null) { if (!Resolve(uid, ref paperComp)) return; diff --git a/Content.Server/Parallax/BiomeSystem.cs b/Content.Server/Parallax/BiomeSystem.cs index a9d78afa86..c9017ac821 100644 --- a/Content.Server/Parallax/BiomeSystem.cs +++ b/Content.Server/Parallax/BiomeSystem.cs @@ -282,9 +282,8 @@ public sealed partial class BiomeSystem : SharedBiomeSystem } // Get chunks in range - foreach (var client in Filter.GetAllPlayers(_playerManager)) + foreach (var pSession in Filter.GetAllPlayers(_playerManager)) { - var pSession = (IPlayerSession) client; if (xformQuery.TryGetComponent(pSession.AttachedEntity, out var xform) && _handledEntities.Add(pSession.AttachedEntity.Value) && diff --git a/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.ControlBox.cs b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.ControlBox.cs index 20ed276967..f200c991d7 100644 --- a/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.ControlBox.cs +++ b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.ControlBox.cs @@ -2,11 +2,10 @@ using Content.Server.ParticleAccelerator.Components; using Content.Server.Power.Components; using Content.Shared.Database; using Content.Shared.Singularity.Components; -using Robust.Server.Player; -using Robust.Server.GameObjects; using Robust.Shared.Utility; using System.Diagnostics; using Content.Shared.CCVar; +using Robust.Shared.Player; namespace Content.Server.ParticleAccelerator.EntitySystems; @@ -60,7 +59,7 @@ public sealed partial class ParticleAcceleratorSystem FireEmitter(comp.StarboardEmitter!.Value, strength); } - public void SwitchOn(EntityUid uid, IPlayerSession? user = null, ParticleAcceleratorControlBoxComponent? comp = null) + public void SwitchOn(EntityUid uid, ICommonSession? user = null, ParticleAcceleratorControlBoxComponent? comp = null) { if (!Resolve(uid, ref comp)) return; @@ -83,7 +82,7 @@ public sealed partial class ParticleAcceleratorSystem UpdateUI(uid, comp); } - public void SwitchOff(EntityUid uid, IPlayerSession? user = null, ParticleAcceleratorControlBoxComponent? comp = null) + public void SwitchOff(EntityUid uid, ICommonSession? user = null, ParticleAcceleratorControlBoxComponent? comp = null) { if (!Resolve(uid, ref comp)) return; @@ -131,7 +130,7 @@ public sealed partial class ParticleAcceleratorSystem UpdateUI(uid, comp); } - public void SetStrength(EntityUid uid, ParticleAcceleratorPowerState strength, IPlayerSession? user = null, ParticleAcceleratorControlBoxComponent? comp = null) + public void SetStrength(EntityUid uid, ParticleAcceleratorPowerState strength, ICommonSession? user = null, ParticleAcceleratorControlBoxComponent? comp = null) { if (!Resolve(uid, ref comp)) return; @@ -347,10 +346,10 @@ public sealed partial class ParticleAcceleratorSystem if (msg.Enabled) { if (comp.Assembled) - SwitchOn(uid, (IPlayerSession?) msg.Session, comp); + SwitchOn(uid, msg.Session, comp); } else - SwitchOff(uid, (IPlayerSession?) msg.Session, comp); + SwitchOff(uid, msg.Session, comp); UpdateUI(uid, comp); } @@ -364,7 +363,7 @@ public sealed partial class ParticleAcceleratorSystem if (TryComp(uid, out var apcPower) && !apcPower.Powered) return; - SetStrength(uid, msg.State, (IPlayerSession?) msg.Session, comp); + SetStrength(uid, msg.State, msg.Session, comp); UpdateUI(uid, comp); } @@ -378,7 +377,7 @@ public sealed partial class ParticleAcceleratorSystem if (TryComp(uid, out var apcPower) && !apcPower.Powered) return; - RescanParts(uid, (IPlayerSession?) msg.Session, comp); + RescanParts(uid, msg.Session, comp); UpdateUI(uid, comp); } diff --git a/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Parts.cs b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Parts.cs index 271d17a0c4..abc68543ff 100644 --- a/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Parts.cs +++ b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Parts.cs @@ -2,9 +2,9 @@ using System.Diagnostics.CodeAnalysis; using System.Numerics; using Content.Server.ParticleAccelerator.Components; using JetBrains.Annotations; -using Robust.Server.Player; using Robust.Shared.Map.Components; using Robust.Shared.Physics.Events; +using Robust.Shared.Player; namespace Content.Server.ParticleAccelerator.EntitySystems; @@ -18,7 +18,7 @@ public sealed partial class ParticleAcceleratorSystem SubscribeLocalEvent(BodyTypeChanged); } - public void RescanParts(EntityUid uid, IPlayerSession? user = null, ParticleAcceleratorControlBoxComponent? controller = null) + public void RescanParts(EntityUid uid, ICommonSession? user = null, ParticleAcceleratorControlBoxComponent? controller = null) { if (!Resolve(uid, ref controller)) return; diff --git a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingManager.cs b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingManager.cs index 50c64e718c..bcc6f211ed 100644 --- a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingManager.cs +++ b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingManager.cs @@ -5,18 +5,18 @@ using System.Threading.Tasks; using Content.Server.Database; using Content.Shared.CCVar; using Content.Shared.Players.PlayTimeTracking; -using Robust.Server.Player; using Robust.Shared.Asynchronous; using Robust.Shared.Collections; using Robust.Shared.Configuration; using Robust.Shared.Exceptions; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Timing; using Robust.Shared.Utility; namespace Content.Server.Players.PlayTimeTracking; -public delegate void CalcPlayTimeTrackersCallback(IPlayerSession player, HashSet trackers); +public delegate void CalcPlayTimeTrackersCallback(ICommonSession player, HashSet trackers); /// /// Tracks play time for players, across all roles. @@ -66,7 +66,7 @@ public sealed class PlayTimeTrackingManager private ISawmill _sawmill = default!; // List of players that need some kind of update (refresh timers or resend). - private ValueList _playersDirty; + private ValueList _playersDirty; // DB auto-saving logic. private TimeSpan _saveInterval; @@ -76,7 +76,7 @@ public sealed class PlayTimeTrackingManager // We must block server shutdown on these to avoid losing data. private readonly List _pendingSaveTasks = new(); - private readonly Dictionary _playTimeData = new(); + private readonly Dictionary _playTimeData = new(); public event CalcPlayTimeTrackersCallback? CalcTrackers; @@ -139,7 +139,7 @@ public sealed class PlayTimeTrackingManager _playersDirty.Clear(); } - private void RefreshSingleTracker(IPlayerSession dirty, PlayTimeData data, TimeSpan time) + private void RefreshSingleTracker(ICommonSession dirty, PlayTimeData data, TimeSpan time) { DebugTools.Assert(data.Initialized); @@ -181,7 +181,7 @@ public sealed class PlayTimeTrackingManager /// so APIs like return up-to-date info. /// /// - public void FlushTracker(IPlayerSession player) + public void FlushTracker(ICommonSession player) { var time = _timing.RealTime; var data = _playTimeData[player]; @@ -201,7 +201,7 @@ public sealed class PlayTimeTrackingManager } } - private void SendPlayTimes(IPlayerSession pSession) + private void SendPlayTimes(ICommonSession pSession) { var roles = GetTrackerTimes(pSession); @@ -228,7 +228,7 @@ public sealed class PlayTimeTrackingManager /// /// Save all modified time trackers for a player to the database. /// - public async void SaveSession(IPlayerSession session) + public async void SaveSession(ICommonSession session) { // This causes all trackers to refresh, ah well. FlushAllTrackers(); @@ -278,7 +278,7 @@ public sealed class PlayTimeTrackingManager _sawmill.Debug($"Saved {log.Count} trackers"); } - private async Task DoSaveSessionAsync(IPlayerSession session) + private async Task DoSaveSessionAsync(ICommonSession session) { var log = new List(); @@ -299,7 +299,7 @@ public sealed class PlayTimeTrackingManager _sawmill.Debug($"Saved {log.Count} trackers for {session.Name}"); } - public async Task LoadData(IPlayerSession session, CancellationToken cancel) + public async Task LoadData(ICommonSession session, CancellationToken cancel) { var data = new PlayTimeData(); _playTimeData.Add(session, data); @@ -318,14 +318,14 @@ public sealed class PlayTimeTrackingManager QueueSendTimers(session); } - public void ClientDisconnected(IPlayerSession session) + public void ClientDisconnected(ICommonSession session) { SaveSession(session); _playTimeData.Remove(session); } - public void AddTimeToTracker(IPlayerSession id, string tracker, TimeSpan time) + public void AddTimeToTracker(ICommonSession id, string tracker, TimeSpan time) { if (!_playTimeData.TryGetValue(id, out var data) || !data.Initialized) throw new InvalidOperationException("Play time info is not yet loaded for this player!"); @@ -341,17 +341,17 @@ public sealed class PlayTimeTrackingManager data.DbTrackersDirty.Add(tracker); } - public void AddTimeToOverallPlaytime(IPlayerSession id, TimeSpan time) + public void AddTimeToOverallPlaytime(ICommonSession id, TimeSpan time) { AddTimeToTracker(id, PlayTimeTrackingShared.TrackerOverall, time); } - public TimeSpan GetOverallPlaytime(IPlayerSession id) + public TimeSpan GetOverallPlaytime(ICommonSession id) { return GetPlayTimeForTracker(id, PlayTimeTrackingShared.TrackerOverall); } - public bool TryGetTrackerTimes(IPlayerSession id, [NotNullWhen(true)] out Dictionary? time) + public bool TryGetTrackerTimes(ICommonSession id, [NotNullWhen(true)] out Dictionary? time) { time = null; @@ -364,7 +364,7 @@ public sealed class PlayTimeTrackingManager return true; } - public Dictionary GetTrackerTimes(IPlayerSession id) + public Dictionary GetTrackerTimes(ICommonSession id) { if (!_playTimeData.TryGetValue(id, out var data) || !data.Initialized) throw new InvalidOperationException("Play time info is not yet loaded for this player!"); @@ -372,7 +372,7 @@ public sealed class PlayTimeTrackingManager return data.TrackerTimes; } - public TimeSpan GetPlayTimeForTracker(IPlayerSession id, string tracker) + public TimeSpan GetPlayTimeForTracker(ICommonSession id, string tracker) { if (!_playTimeData.TryGetValue(id, out var data) || !data.Initialized) throw new InvalidOperationException("Play time info is not yet loaded for this player!"); @@ -383,7 +383,7 @@ public sealed class PlayTimeTrackingManager /// /// Queue for play time trackers to be refreshed on a player, in case the set of active trackers may have changed. /// - public void QueueRefreshTrackers(IPlayerSession player) + public void QueueRefreshTrackers(ICommonSession player) { if (DirtyPlayer(player) is { } data) data.NeedRefreshTackers = true; @@ -392,13 +392,13 @@ public sealed class PlayTimeTrackingManager /// /// Queue for play time information to be sent to a client, for showing in UIs etc. /// - public void QueueSendTimers(IPlayerSession player) + public void QueueSendTimers(ICommonSession player) { if (DirtyPlayer(player) is { } data) data.NeedSendTimers = true; } - private PlayTimeData? DirtyPlayer(IPlayerSession player) + private PlayTimeData? DirtyPlayer(ICommonSession player) { if (!_playTimeData.TryGetValue(player, out var data) || !data.Initialized) return null; diff --git a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs index 13d0794dd5..f865b25bac 100644 --- a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs +++ b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs @@ -14,6 +14,7 @@ using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Utility; @@ -55,7 +56,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem _tracking.CalcTrackers -= CalcTrackers; } - private void CalcTrackers(IPlayerSession player, HashSet trackers) + private void CalcTrackers(ICommonSession player, HashSet trackers) { if (_afk.IsAfk(player)) return; @@ -67,7 +68,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem trackers.UnionWith(GetTimedRoles(player)); } - private bool IsPlayerAlive(IPlayerSession session) + private bool IsPlayerAlive(ICommonSession session) { var attached = session.AttachedEntity; if (attached == null) @@ -93,7 +94,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem } } - private IEnumerable GetTimedRoles(IPlayerSession session) + private IEnumerable GetTimedRoles(ICommonSession session) { var contentData = _playerManager.GetPlayerData(session.UserId).ContentData(); @@ -156,7 +157,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem _tracking.QueueSendTimers(ev.PlayerSession); } - public bool IsAllowed(IPlayerSession player, string role) + public bool IsAllowed(ICommonSession player, string role) { if (!_prototypes.TryIndex(role, out var job) || job.Requirements == null || @@ -168,7 +169,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem return JobRequirements.TryRequirementsMet(job, playTimes, out _, EntityManager, _prototypes); } - public HashSet GetDisallowedJobs(IPlayerSession player) + public HashSet GetDisallowedJobs(ICommonSession player) { var roles = new HashSet(); if (!_cfg.GetCVar(CCVars.GameRoleTimers)) @@ -230,7 +231,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem } } - public void PlayerRolesChanged(IPlayerSession player) + public void PlayerRolesChanged(ICommonSession player) { _tracking.QueueRefreshTrackers(player); } diff --git a/Content.Server/Players/PlayerData.cs b/Content.Server/Players/PlayerData.cs deleted file mode 100644 index b0ca6f3c18..0000000000 --- a/Content.Server/Players/PlayerData.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Content.Shared.Players; -using Robust.Server.Player; -using Robust.Shared.Players; - -namespace Content.Server.Players -{ - public static class PlayerDataExt - { - /// - /// Gets the correctly cast instance of content player data from an engine player data storage. - /// - public static PlayerData? ContentData(this IPlayerSession session) - { - return session.Data.ContentData(); - } - - public static PlayerData? ContentData(this ICommonSession session) - { - return ((IPlayerSession) session).ContentData(); - } - - /// - /// Gets the mind that is associated with this player. - /// - public static EntityUid? GetMind(this IPlayerSession session) - { - return session.Data.ContentData()?.Mind; - } - } -} diff --git a/Content.Server/Players/PlayerSystem.cs b/Content.Server/Players/PlayerSystem.cs index 0c407aa876..c79683c338 100644 --- a/Content.Server/Players/PlayerSystem.cs +++ b/Content.Server/Players/PlayerSystem.cs @@ -1,11 +1,11 @@ using Content.Shared.Players; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.Players; public sealed class PlayerSystem : SharedPlayerSystem { - public override PlayerData? ContentData(ICommonSession? session) + public override ContentPlayerData? ContentData(ICommonSession? session) { return session?.ContentData(); } diff --git a/Content.Server/Pointing/EntitySystems/PointingSystem.cs b/Content.Server/Pointing/EntitySystems/PointingSystem.cs index b253e32e37..6fcdfcf994 100644 --- a/Content.Server/Pointing/EntitySystems/PointingSystem.cs +++ b/Content.Server/Pointing/EntitySystems/PointingSystem.cs @@ -20,7 +20,6 @@ using Robust.Shared.Enums; using Robust.Shared.Input.Binding; using Robust.Shared.Map; using Robust.Shared.Player; -using Robust.Shared.Players; using Robust.Shared.Replays; using Robust.Shared.Timing; @@ -170,7 +169,7 @@ namespace Content.Server.Pointing.EntitySystems } // Get players that are in range and whose visibility layer matches the arrow's. - bool ViewerPredicate(IPlayerSession playerSession) + bool ViewerPredicate(ICommonSession playerSession) { if (!_minds.TryGetMind(playerSession, out _, out var mind) || mind.CurrentEntity is not { Valid: true } ent || @@ -182,7 +181,7 @@ namespace Content.Server.Pointing.EntitySystems } var viewers = Filter.Empty() - .AddWhere(session1 => ViewerPredicate((IPlayerSession) session1)) + .AddWhere(session1 => ViewerPredicate(session1)) .Recipients; string selfMessage; diff --git a/Content.Server/Popups/PopupSystem.cs b/Content.Server/Popups/PopupSystem.cs index 483d4f3d3f..61ccaf4423 100644 --- a/Content.Server/Popups/PopupSystem.cs +++ b/Content.Server/Popups/PopupSystem.cs @@ -4,7 +4,6 @@ using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Map; using Robust.Shared.Player; -using Robust.Shared.Players; namespace Content.Server.Popups { diff --git a/Content.Server/Prayer/PrayerSystem.cs b/Content.Server/Prayer/PrayerSystem.cs index be6ae80bfd..e20291cc06 100644 --- a/Content.Server/Prayer/PrayerSystem.cs +++ b/Content.Server/Prayer/PrayerSystem.cs @@ -5,12 +5,11 @@ using Content.Server.Chat.Managers; using Content.Server.Popups; using Content.Shared.Database; using Content.Shared.Popups; -using Robust.Server.Player; -using Robust.Shared.Player; using Content.Shared.Chat; using Content.Shared.Prayer; using Content.Shared.Verbs; using Robust.Server.GameObjects; +using Robust.Shared.Player; namespace Content.Server.Prayer; /// @@ -74,7 +73,7 @@ public sealed class PrayerSystem : EntitySystem /// The IPlayerSession that sent the message /// The main message sent to the player via the chatbox /// The popup to notify the player, also prepended to the messageString - public void SendSubtleMessage(IPlayerSession target, IPlayerSession source, string messageString, string popupMessage) + public void SendSubtleMessage(ICommonSession target, ICommonSession source, string messageString, string popupMessage) { if (target.AttachedEntity == null) return; @@ -96,7 +95,7 @@ public sealed class PrayerSystem : EntitySystem /// You may be wondering, "Why the admin chat, specifically? Nobody even reads it!" /// Exactly. /// - public void Pray(IPlayerSession sender, PrayableComponent comp, string message) + public void Pray(ICommonSession sender, PrayableComponent comp, string message) { if (sender.AttachedEntity == null) return; diff --git a/Content.Server/Preferences/Managers/IServerPreferencesManager.cs b/Content.Server/Preferences/Managers/IServerPreferencesManager.cs index 8c06e00ab1..a36b053717 100644 --- a/Content.Server/Preferences/Managers/IServerPreferencesManager.cs +++ b/Content.Server/Preferences/Managers/IServerPreferencesManager.cs @@ -2,8 +2,8 @@ using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; using Content.Shared.Preferences; -using Robust.Server.Player; using Robust.Shared.Network; +using Robust.Shared.Player; namespace Content.Server.Preferences.Managers { @@ -11,12 +11,12 @@ namespace Content.Server.Preferences.Managers { void Init(); - Task LoadData(IPlayerSession session, CancellationToken cancel); - void OnClientDisconnected(IPlayerSession session); + Task LoadData(ICommonSession session, CancellationToken cancel); + void OnClientDisconnected(ICommonSession session); bool TryGetCachedPreferences(NetUserId userId, [NotNullWhen(true)] out PlayerPreferences? playerPreferences); PlayerPreferences GetPreferences(NetUserId userId); IEnumerable> GetSelectedProfilesForPlayers(List userIds); - bool HavePreferencesLoaded(IPlayerSession session); + bool HavePreferencesLoaded(ICommonSession session); } } diff --git a/Content.Server/Preferences/Managers/ServerPreferencesManager.cs b/Content.Server/Preferences/Managers/ServerPreferencesManager.cs index ea04d00e82..a0b5e8ce65 100644 --- a/Content.Server/Preferences/Managers/ServerPreferencesManager.cs +++ b/Content.Server/Preferences/Managers/ServerPreferencesManager.cs @@ -8,9 +8,9 @@ using Content.Shared.CCVar; using Content.Shared.Humanoid.Prototypes; using Content.Shared.Preferences; using Content.Shared.Roles; -using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Prototypes; @@ -167,7 +167,7 @@ namespace Content.Server.Preferences.Managers } // Should only be called via UserDbDataManager. - public async Task LoadData(IPlayerSession session, CancellationToken cancel) + public async Task LoadData(ICommonSession session, CancellationToken cancel) { if (!ShouldStorePrefs(session.ConnectedClient.AuthType)) { @@ -207,12 +207,12 @@ namespace Content.Server.Preferences.Managers } } - public void OnClientDisconnected(IPlayerSession session) + public void OnClientDisconnected(ICommonSession session) { _cachedPlayerPrefs.Remove(session.UserId); } - public bool HavePreferencesLoaded(IPlayerSession session) + public bool HavePreferencesLoaded(ICommonSession session) { return _cachedPlayerPrefs.ContainsKey(session.UserId); } diff --git a/Content.Server/Pulling/PullingSystem.cs b/Content.Server/Pulling/PullingSystem.cs index f7ea0aae57..69bb7c9370 100644 --- a/Content.Server/Pulling/PullingSystem.cs +++ b/Content.Server/Pulling/PullingSystem.cs @@ -4,7 +4,7 @@ using Content.Shared.Pulling.Components; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Shared.Input.Binding; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.Pulling { diff --git a/Content.Server/Radiation/Systems/RadiationSystem.Debug.cs b/Content.Server/Radiation/Systems/RadiationSystem.Debug.cs index 97f2e485ca..56806d8c9c 100644 --- a/Content.Server/Radiation/Systems/RadiationSystem.Debug.cs +++ b/Content.Server/Radiation/Systems/RadiationSystem.Debug.cs @@ -7,7 +7,7 @@ using Content.Shared.Radiation.Systems; using Robust.Shared.Console; using Robust.Shared.Enums; using Robust.Shared.Map.Components; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.Radiation.Systems; diff --git a/Content.Server/Research/Systems/ResearchSystem.Client.cs b/Content.Server/Research/Systems/ResearchSystem.Client.cs index e813f09ff9..135ef8fe88 100644 --- a/Content.Server/Research/Systems/ResearchSystem.Client.cs +++ b/Content.Server/Research/Systems/ResearchSystem.Client.cs @@ -1,7 +1,6 @@ using System.Diagnostics.CodeAnalysis; using Content.Server.Power.EntitySystems; using Content.Shared.Research.Components; -using Robust.Server.Player; namespace Content.Server.Research.Systems; @@ -46,7 +45,7 @@ public sealed partial class ResearchSystem if (!this.IsPowered(uid, EntityManager)) return; - _uiSystem.TryToggleUi(uid, ResearchClientUiKey.Key, (IPlayerSession) args.Session); + _uiSystem.TryToggleUi(uid, ResearchClientUiKey.Key, args.Session); } #endregion diff --git a/Content.Server/Salvage/SalvageRulerCommand.cs b/Content.Server/Salvage/SalvageRulerCommand.cs index b0a64508c5..a1fd609741 100644 --- a/Content.Server/Salvage/SalvageRulerCommand.cs +++ b/Content.Server/Salvage/SalvageRulerCommand.cs @@ -1,6 +1,5 @@ using Content.Server.Administration; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; @@ -26,7 +25,7 @@ sealed class SalvageRulerCommand : IConsoleCommand return; } - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError(Loc.GetString("shell-only-players-can-run-this-command")); return; diff --git a/Content.Server/Sandbox/Commands/ColorNetworkCommand.cs b/Content.Server/Sandbox/Commands/ColorNetworkCommand.cs index 0b9148f0fb..cc20b71946 100644 --- a/Content.Server/Sandbox/Commands/ColorNetworkCommand.cs +++ b/Content.Server/Sandbox/Commands/ColorNetworkCommand.cs @@ -4,7 +4,6 @@ using Content.Server.Atmos.Piping.EntitySystems; using Content.Server.NodeContainer; using Content.Server.NodeContainer.NodeGroups; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Sandbox.Commands @@ -20,7 +19,7 @@ namespace Content.Server.Sandbox.Commands { var sandboxManager = EntitySystem.Get(); var adminManager = IoCManager.Resolve(); - if (shell.IsClient && (!sandboxManager.IsSandboxEnabled && !adminManager.HasAdminFlag((IPlayerSession)shell.Player!, AdminFlags.Mapping))) + if (shell.IsClient && (!sandboxManager.IsSandboxEnabled && !adminManager.HasAdminFlag(shell.Player!, AdminFlags.Mapping))) { shell.WriteError("You are not currently able to use mapping commands."); } diff --git a/Content.Server/Sandbox/SandboxSystem.cs b/Content.Server/Sandbox/SandboxSystem.cs index ec9b1a0c3c..194cf59843 100644 --- a/Content.Server/Sandbox/SandboxSystem.cs +++ b/Content.Server/Sandbox/SandboxSystem.cs @@ -13,6 +13,7 @@ using Robust.Server.Console; using Robust.Server.Placement; using Robust.Server.Player; using Robust.Shared.Enums; +using Robust.Shared.Player; namespace Content.Server.Sandbox { diff --git a/Content.Server/SensorMonitoring/SensorMonitoringConsoleComponent.cs b/Content.Server/SensorMonitoring/SensorMonitoringConsoleComponent.cs index cd4f2ea23b..63b4d9daef 100644 --- a/Content.Server/SensorMonitoring/SensorMonitoringConsoleComponent.cs +++ b/Content.Server/SensorMonitoring/SensorMonitoringConsoleComponent.cs @@ -1,7 +1,7 @@ using Content.Shared.SensorMonitoring; using Robust.Server.Player; using Robust.Shared.Collections; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.SensorMonitoring; diff --git a/Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.UI.cs b/Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.UI.cs index a09badcd59..6c0dddeb26 100644 --- a/Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.UI.cs +++ b/Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.UI.cs @@ -1,7 +1,5 @@ using Content.Server.DeviceNetwork.Components; using Content.Shared.SensorMonitoring; -using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Collections; using ConsoleUIState = Content.Shared.SensorMonitoring.SensorMonitoringConsoleBoundInterfaceState; using IncrementalUIState = Content.Shared.SensorMonitoring.SensorMonitoringIncrementalUpdate; @@ -130,7 +128,7 @@ public sealed partial class SensorMonitoringConsoleSystem if (!args.UiKey.Equals(SensorMonitoringConsoleUiKey.Key)) return; - if (args.Session is not IPlayerSession player) + if (args.Session is not { } player) return; component.InitialUIStateSent.Remove(player); diff --git a/Content.Server/ServerUpdates/ServerUpdateManager.cs b/Content.Server/ServerUpdates/ServerUpdateManager.cs index 769c5d58d7..f4e54984e9 100644 --- a/Content.Server/ServerUpdates/ServerUpdateManager.cs +++ b/Content.Server/ServerUpdates/ServerUpdateManager.cs @@ -6,6 +6,7 @@ using Robust.Server.Player; using Robust.Server.ServerStatus; using Robust.Shared.Configuration; using Robust.Shared.Enums; +using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.ServerUpdates; diff --git a/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs b/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs index 1a1debc9e3..3ef3d97a21 100644 --- a/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs +++ b/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs @@ -20,7 +20,6 @@ using Content.Shared.Tag; using Content.Shared.Tiles; using Robust.Server.GameObjects; using Robust.Server.Maps; -using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Map; using Robust.Shared.Map.Components; @@ -140,7 +139,7 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem /// private void OnShuttleRequestPosition(EmergencyShuttleRequestPositionMessage msg, EntitySessionEventArgs args) { - if (!_admin.IsAdmin((IPlayerSession) args.SenderSession)) + if (!_admin.IsAdmin(args.SenderSession)) return; var player = args.SenderSession.AttachedEntity; diff --git a/Content.Server/Silicons/Borgs/BorgSystem.Modules.cs b/Content.Server/Silicons/Borgs/BorgSystem.Modules.cs index 31d826087d..c080420266 100644 --- a/Content.Server/Silicons/Borgs/BorgSystem.Modules.cs +++ b/Content.Server/Silicons/Borgs/BorgSystem.Modules.cs @@ -229,7 +229,7 @@ public sealed partial class BorgSystem if (!TryComp(chassis, out var hands)) return; - if (LifeStage(uid) >= EntityLifeStage.Terminating) + if (TerminatingOrDeleted(uid)) { foreach (var (hand, item) in component.ProvidedItems) { diff --git a/Content.Server/Silicons/Borgs/BorgSystem.cs b/Content.Server/Silicons/Borgs/BorgSystem.cs index 611dfa6ea2..883cb3b3d8 100644 --- a/Content.Server/Silicons/Borgs/BorgSystem.cs +++ b/Content.Server/Silicons/Borgs/BorgSystem.cs @@ -21,7 +21,7 @@ using Content.Shared.Throwing; using Content.Shared.Wires; using Robust.Server.GameObjects; using Robust.Shared.Containers; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Random; namespace Content.Server.Silicons.Borgs; diff --git a/Content.Server/Silicons/Laws/SiliconLawSystem.cs b/Content.Server/Silicons/Laws/SiliconLawSystem.cs index 1d5c2e35e8..41ddd9651b 100644 --- a/Content.Server/Silicons/Laws/SiliconLawSystem.cs +++ b/Content.Server/Silicons/Laws/SiliconLawSystem.cs @@ -18,7 +18,6 @@ using Content.Shared.Silicons.Laws.Components; using Content.Shared.Stunnable; using Content.Shared.Wires; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Prototypes; using Robust.Shared.Toolshed; @@ -94,7 +93,7 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem HashSet? radioChannels = intrinsicRadio?.Channels; var state = new SiliconLawBuiState(GetLaws(uid), radioChannels); - _userInterface.TrySetUiState(args.Entity, SiliconLawsUiKey.Key, state, (IPlayerSession) args.Session); + _userInterface.TrySetUiState(args.Entity, SiliconLawsUiKey.Key, state, args.Session); } private void OnPlayerSpawnComplete(EntityUid uid, SiliconLawBoundComponent component, PlayerSpawnCompleteEvent args) @@ -170,7 +169,7 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem if (component.AntagonistRole == null) return; - _roles.MindTryRemoveRole(args.OldMindId); + _roles.MindTryRemoveRole(args.Mind); } private void EnsureEmaggedRole(EntityUid uid, EmagSiliconLawComponent component) diff --git a/Content.Server/Station/Systems/StationJobsSystem.cs b/Content.Server/Station/Systems/StationJobsSystem.cs index 2709bc2072..eeaace03b2 100644 --- a/Content.Server/Station/Systems/StationJobsSystem.cs +++ b/Content.Server/Station/Systems/StationJobsSystem.cs @@ -41,7 +41,7 @@ public sealed partial class StationJobsSystem : EntitySystem if (_availableJobsDirty) { _cachedAvailableJobs = GenerateJobsAvailableEvent(); - RaiseNetworkEvent(_cachedAvailableJobs, Filter.Empty().AddPlayers(_playerManager.ServerSessions)); + RaiseNetworkEvent(_cachedAvailableJobs, Filter.Empty().AddPlayers(_playerManager.Sessions)); _availableJobsDirty = false; } } diff --git a/Content.Server/Storage/EntitySystems/StorageSystem.cs b/Content.Server/Storage/EntitySystems/StorageSystem.cs index 3430449957..8b4ae1c76f 100644 --- a/Content.Server/Storage/EntitySystems/StorageSystem.cs +++ b/Content.Server/Storage/EntitySystems/StorageSystem.cs @@ -9,7 +9,6 @@ using Content.Shared.Storage.EntitySystems; using Content.Shared.Timing; using Content.Shared.Verbs; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Map; using Robust.Shared.Player; using Robust.Shared.Prototypes; @@ -135,7 +134,7 @@ public sealed partial class StorageSystem : SharedStorageSystem /// If the user has nested-UIs open (e.g., PDA UI open when pda is in a backpack), close them. /// /// - public void CloseNestedInterfaces(EntityUid uid, IPlayerSession session, StorageComponent? storageComp = null) + public void CloseNestedInterfaces(EntityUid uid, ICommonSession session, StorageComponent? storageComp = null) { if (!Resolve(uid, ref storageComp)) return; diff --git a/Content.Server/Tabletop/TabletopSession.cs b/Content.Server/Tabletop/TabletopSession.cs index d94b4fd657..5e7c6ac02e 100644 --- a/Content.Server/Tabletop/TabletopSession.cs +++ b/Content.Server/Tabletop/TabletopSession.cs @@ -1,6 +1,6 @@ using System.Numerics; -using Robust.Server.Player; using Robust.Shared.Map; +using Robust.Shared.Player; namespace Content.Server.Tabletop { @@ -17,7 +17,7 @@ namespace Content.Server.Tabletop /// /// The set of players currently playing this tabletop game. /// - public readonly Dictionary Players = new(); + public readonly Dictionary Players = new(); /// /// All entities bound to this session. If you create an entity for this session, you have to add it here. diff --git a/Content.Server/Tabletop/TabletopSystem.Session.cs b/Content.Server/Tabletop/TabletopSystem.Session.cs index e9dea0c66a..8f1bc7005d 100644 --- a/Content.Server/Tabletop/TabletopSystem.Session.cs +++ b/Content.Server/Tabletop/TabletopSystem.Session.cs @@ -1,7 +1,7 @@ using System.Numerics; using Content.Server.Tabletop.Components; using Content.Shared.Tabletop.Events; -using Robust.Server.Player; +using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Server.Tabletop @@ -66,7 +66,7 @@ namespace Content.Server.Tabletop /// /// The player session in question. /// The UID of the tabletop game entity. - public void OpenSessionFor(IPlayerSession player, EntityUid uid) + public void OpenSessionFor(ICommonSession player, EntityUid uid) { if (!EntityManager.TryGetComponent(uid, out TabletopGameComponent? tabletop) || player.AttachedEntity is not {Valid: true} attachedEntity) return; @@ -98,7 +98,7 @@ namespace Content.Server.Tabletop /// The player in question. /// The UID of the tabletop game entity. /// Whether to remove the from the player's attached entity. - public void CloseSessionFor(IPlayerSession player, EntityUid uid, bool removeGamerComponent = true) + public void CloseSessionFor(ICommonSession player, EntityUid uid, bool removeGamerComponent = true) { if (!EntityManager.TryGetComponent(uid, out TabletopGameComponent? tabletop) || tabletop.Session is not { } session) return; @@ -129,7 +129,7 @@ namespace Content.Server.Tabletop /// The player in question. /// An offset from the tabletop position for the camera. Zero by default. /// The UID of the camera entity. - private EntityUid CreateCamera(TabletopGameComponent tabletop, IPlayerSession player, Vector2 offset = default) + private EntityUid CreateCamera(TabletopGameComponent tabletop, ICommonSession player, Vector2 offset = default) { DebugTools.AssertNotNull(tabletop.Session); diff --git a/Content.Server/Tabletop/TabletopSystem.cs b/Content.Server/Tabletop/TabletopSystem.cs index 2e271080d0..b81331d62e 100644 --- a/Content.Server/Tabletop/TabletopSystem.cs +++ b/Content.Server/Tabletop/TabletopSystem.cs @@ -9,7 +9,6 @@ using Content.Shared.Tabletop.Events; using Content.Shared.Verbs; using JetBrains.Annotations; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Enums; using Robust.Shared.Map; using Robust.Shared.Utility; @@ -42,7 +41,7 @@ namespace Content.Server.Tabletop private void OnTabletopRequestTakeOut(TabletopRequestTakeOut msg, EntitySessionEventArgs args) { - if (args.SenderSession is not IPlayerSession playerSession) + if (args.SenderSession is not { } playerSession) return; var table = GetEntity(msg.TableUid); @@ -105,7 +104,7 @@ namespace Content.Server.Tabletop protected override void OnTabletopMove(TabletopMoveEvent msg, EntitySessionEventArgs args) { - if (args.SenderSession is not IPlayerSession playerSession) + if (args.SenderSession is not { } playerSession) return; if (!TryComp(GetEntity(msg.TableUid), out TabletopGameComponent? tabletop) || tabletop.Session is not { } session) @@ -155,7 +154,7 @@ namespace Content.Server.Tabletop private void OnStopPlaying(TabletopStopPlayingEvent msg, EntitySessionEventArgs args) { - CloseSessionFor((IPlayerSession)args.SenderSession, GetEntity(msg.TableUid)); + CloseSessionFor(args.SenderSession, GetEntity(msg.TableUid)); } private void OnPlayerDetached(EntityUid uid, TabletopGamerComponent component, PlayerDetachedEvent args) diff --git a/Content.Server/Toolshed/Commands/AdminDebug/ACmdCommand.cs b/Content.Server/Toolshed/Commands/AdminDebug/ACmdCommand.cs index d2b3cc261c..f113e49655 100644 --- a/Content.Server/Toolshed/Commands/AdminDebug/ACmdCommand.cs +++ b/Content.Server/Toolshed/Commands/AdminDebug/ACmdCommand.cs @@ -1,7 +1,7 @@ using Content.Server.Administration; using Content.Server.Administration.Managers; using Content.Shared.Administration; -using Robust.Server.Player; +using Robust.Shared.Player; using Robust.Shared.Toolshed; using Robust.Shared.Toolshed.Syntax; @@ -25,7 +25,7 @@ public sealed class ACmdCommand : ToolshedCommand public bool CanInvoke( [CommandInvocationContext] IInvocationContext ctx, [PipedArgument] CommandSpec command, - [CommandArgument] ValueRef player + [CommandArgument] ValueRef player ) { // Deliberately discard the error. diff --git a/Content.Server/Toolshed/Commands/VisualizeCommand.cs b/Content.Server/Toolshed/Commands/VisualizeCommand.cs index 4ef08a91bf..2225bfaf44 100644 --- a/Content.Server/Toolshed/Commands/VisualizeCommand.cs +++ b/Content.Server/Toolshed/Commands/VisualizeCommand.cs @@ -4,7 +4,6 @@ using Content.Server.EUI; using Content.Shared.Administration; using Content.Shared.Bql; using Content.Shared.Eui; -using Robust.Server.Player; using Robust.Shared.Toolshed; using Robust.Shared.Toolshed.Errors; @@ -30,7 +29,7 @@ public sealed class VisualizeCommand : ToolshedCommand var ui = new ToolshedVisualizeEui( input.Select(e => (EntName(e), EntityManager.GetNetEntity(e))).ToArray() ); - _euiManager.OpenEui(ui, (IPlayerSession) ctx.Session); + _euiManager.OpenEui(ui, ctx.Session); _euiManager.QueueStateUpdate(ui); } } diff --git a/Content.Server/Traitor/Uplink/Commands/AddUplinkCommand.cs b/Content.Server/Traitor/Uplink/Commands/AddUplinkCommand.cs index 1feab11b99..fd656a9f71 100644 --- a/Content.Server/Traitor/Uplink/Commands/AddUplinkCommand.cs +++ b/Content.Server/Traitor/Uplink/Commands/AddUplinkCommand.cs @@ -5,6 +5,7 @@ using Content.Shared.FixedPoint; using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Console; +using Robust.Shared.Player; namespace Content.Server.Traitor.Uplink.Commands { @@ -36,7 +37,7 @@ namespace Content.Server.Traitor.Uplink.Commands return; } - IPlayerSession? session; + ICommonSession? session; if (args.Length > 0) { // Get player entity @@ -48,7 +49,7 @@ namespace Content.Server.Traitor.Uplink.Commands } else { - session = (IPlayerSession?) shell.Player; + session = shell.Player; } if (session?.AttachedEntity is not { } user) diff --git a/Content.Server/UserInterface/ActivatableUIComponent.cs b/Content.Server/UserInterface/ActivatableUIComponent.cs index bb020608e2..34f9c0f397 100644 --- a/Content.Server/UserInterface/ActivatableUIComponent.cs +++ b/Content.Server/UserInterface/ActivatableUIComponent.cs @@ -1,4 +1,4 @@ -using Robust.Server.Player; +using Robust.Shared.Player; using Robust.Shared.Reflection; using Robust.Shared.Serialization; @@ -65,7 +65,7 @@ namespace Content.Server.UserInterface /// NOTE: DO NOT DIRECTLY SET, USE ActivatableUISystem.SetCurrentSingleUser /// [ViewVariables] - public IPlayerSession? CurrentSingleUser; + public ICommonSession? CurrentSingleUser; void ISerializationHooks.AfterDeserialization() { diff --git a/Content.Server/UserInterface/ActivatableUISystem.cs b/Content.Server/UserInterface/ActivatableUISystem.cs index 59086415b4..adeeed7c19 100644 --- a/Content.Server/UserInterface/ActivatableUISystem.cs +++ b/Content.Server/UserInterface/ActivatableUISystem.cs @@ -8,7 +8,7 @@ using Content.Shared.Interaction.Events; using Content.Shared.UserInterface; using Content.Shared.Verbs; using Robust.Server.GameObjects; -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.UserInterface; @@ -173,7 +173,7 @@ public sealed partial class ActivatableUISystem : EntitySystem return true; } - public void SetCurrentSingleUser(EntityUid uid, IPlayerSession? v, ActivatableUIComponent? aui = null) + public void SetCurrentSingleUser(EntityUid uid, ICommonSession? v, ActivatableUIComponent? aui = null) { if (!Resolve(uid, ref aui)) return; @@ -231,9 +231,9 @@ public sealed class UserOpenActivatableUIAttemptEvent : CancellableEntityEventAr public sealed class AfterActivatableUIOpenEvent : EntityEventArgs { public EntityUid User { get; } - public readonly IPlayerSession Session; + public readonly ICommonSession Session; - public AfterActivatableUIOpenEvent(EntityUid who, IPlayerSession session) + public AfterActivatableUIOpenEvent(EntityUid who, ICommonSession session) { User = who; Session = session; diff --git a/Content.Server/UserInterface/StatValuesCommand.cs b/Content.Server/UserInterface/StatValuesCommand.cs index b13b596323..fe2ee380fe 100644 --- a/Content.Server/UserInterface/StatValuesCommand.cs +++ b/Content.Server/UserInterface/StatValuesCommand.cs @@ -8,7 +8,6 @@ using Content.Shared.Materials; using Content.Shared.Research.Prototypes; using Content.Shared.UserInterface; using Content.Shared.Weapons.Melee; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Prototypes; @@ -27,7 +26,7 @@ public sealed class StatValuesCommand : IConsoleCommand public string Help => $"{Command} "; public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession pSession) + if (shell.Player is not { } pSession) { shell.WriteError(Loc.GetString("stat-values-server")); return; diff --git a/Content.Server/Verbs/VerbSystem.cs b/Content.Server/Verbs/VerbSystem.cs index 6d12b08e86..e304c6b4af 100644 --- a/Content.Server/Verbs/VerbSystem.cs +++ b/Content.Server/Verbs/VerbSystem.cs @@ -6,7 +6,6 @@ using Content.Shared.Administration.Logs; using Content.Shared.Database; using Content.Shared.Hands.Components; using Content.Shared.Verbs; -using Robust.Server.Player; namespace Content.Server.Verbs { @@ -25,7 +24,7 @@ namespace Content.Server.Verbs private void HandleVerbRequest(RequestServerVerbsEvent args, EntitySessionEventArgs eventArgs) { - var player = (IPlayerSession) eventArgs.SenderSession; + var player = eventArgs.SenderSession; if (!EntityManager.EntityExists(GetEntity(args.EntityUid))) { @@ -43,7 +42,7 @@ namespace Content.Server.Verbs // this, and some verbs (e.g. view variables) won't even care about whether an entity is accessible through // the entity menu or not. - var force = args.AdminRequest && eventArgs.SenderSession is IPlayerSession playerSession && + var force = args.AdminRequest && eventArgs.SenderSession is { } playerSession && _adminMgr.HasAdminFlag(playerSession, AdminFlags.Admin); List verbTypes = new(); diff --git a/Content.Server/Voting/IVoteHandle.cs b/Content.Server/Voting/IVoteHandle.cs index 13f64e6ef8..869f2017d7 100644 --- a/Content.Server/Voting/IVoteHandle.cs +++ b/Content.Server/Voting/IVoteHandle.cs @@ -1,5 +1,5 @@ using Content.Server.Voting.Managers; -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Voting { @@ -75,7 +75,7 @@ namespace Content.Server.Voting /// /// is not a valid option ID. /// - void CastVote(IPlayerSession session, int? optionId); + void CastVote(ICommonSession session, int? optionId); /// /// Cancel this vote. diff --git a/Content.Server/Voting/Managers/IVoteManager.cs b/Content.Server/Voting/Managers/IVoteManager.cs index 6a92e70fff..d95fac9ae9 100644 --- a/Content.Server/Voting/Managers/IVoteManager.cs +++ b/Content.Server/Voting/Managers/IVoteManager.cs @@ -1,6 +1,6 @@ using System.Diagnostics.CodeAnalysis; using Content.Shared.Voting; -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Voting.Managers { @@ -41,7 +41,7 @@ namespace Content.Server.Voting.Managers /// True if can start votes right now, /// and if provided if they can start votes of type . /// - bool CanCallVote(IPlayerSession initiator, StandardVoteType? voteType = null); + bool CanCallVote(ICommonSession initiator, StandardVoteType? voteType = null); /// /// Initiate a standard vote such as restart round, that can be initiated by players. @@ -51,7 +51,7 @@ namespace Content.Server.Voting.Managers /// If null it is assumed to be an automatic vote by the server. /// /// The type of standard vote to make. - void CreateStandardVote(IPlayerSession? initiator, StandardVoteType voteType); + void CreateStandardVote(ICommonSession? initiator, StandardVoteType voteType); /// /// Create a non-standard vote with special parameters. diff --git a/Content.Server/Voting/Managers/VoteManager.DefaultVotes.cs b/Content.Server/Voting/Managers/VoteManager.DefaultVotes.cs index 55e88e2a8c..e1bffa769d 100644 --- a/Content.Server/Voting/Managers/VoteManager.DefaultVotes.cs +++ b/Content.Server/Voting/Managers/VoteManager.DefaultVotes.cs @@ -6,8 +6,8 @@ using Content.Server.RoundEnd; using Content.Shared.CCVar; using Content.Shared.Database; using Content.Shared.Voting; -using Robust.Server.Player; using Robust.Shared.Configuration; +using Robust.Shared.Player; using Robust.Shared.Random; namespace Content.Server.Voting.Managers @@ -21,7 +21,7 @@ namespace Content.Server.Voting.Managers {StandardVoteType.Map, CCVars.VoteMapEnabled}, }; - public void CreateStandardVote(IPlayerSession? initiator, StandardVoteType voteType) + public void CreateStandardVote(ICommonSession? initiator, StandardVoteType voteType) { if (initiator != null) _adminLogger.Add(LogType.Vote, LogImpact.Medium, $"{initiator} initiated a {voteType.ToString()} vote"); @@ -47,7 +47,7 @@ namespace Content.Server.Voting.Managers TimeoutStandardVote(voteType); } - private void CreateRestartVote(IPlayerSession? initiator) + private void CreateRestartVote(ICommonSession? initiator) { var alone = _playerManager.PlayerCount == 1 && initiator != null; var options = new VoteOptions @@ -100,7 +100,7 @@ namespace Content.Server.Voting.Managers vote.CastVote(initiator, 0); } - foreach (var player in _playerManager.ServerSessions) + foreach (var player in _playerManager.Sessions) { if (player != initiator) { @@ -110,7 +110,7 @@ namespace Content.Server.Voting.Managers } } - private void CreatePresetVote(IPlayerSession? initiator) + private void CreatePresetVote(ICommonSession? initiator) { var presets = GetGamePresets(); @@ -156,7 +156,7 @@ namespace Content.Server.Voting.Managers }; } - private void CreateMapVote(IPlayerSession? initiator) + private void CreateMapVote(ICommonSession? initiator) { var maps = _gameMapManager.CurrentlyEligibleMaps().ToDictionary(map => map, map => map.MapName); diff --git a/Content.Server/Voting/Managers/VoteManager.cs b/Content.Server/Voting/Managers/VoteManager.cs index 98ad8d8341..90089afb54 100644 --- a/Content.Server/Voting/Managers/VoteManager.cs +++ b/Content.Server/Voting/Managers/VoteManager.cs @@ -16,6 +16,7 @@ using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -45,7 +46,7 @@ namespace Content.Server.Voting.Managers private readonly Dictionary _standardVoteTimeout = new(); private readonly Dictionary _voteTimeout = new(); - private readonly HashSet _playerCanCallVoteDirty = new(); + private readonly HashSet _playerCanCallVoteDirty = new(); private readonly StandardVoteType[] _standardVoteTypeValues = Enum.GetValues(); public void Initialize() @@ -106,7 +107,7 @@ namespace Content.Server.Voting.Managers } } - private void CastVote(VoteReg v, IPlayerSession player, int? option) + private void CastVote(VoteReg v, ICommonSession player, int? option) { if (!IsValidOption(v, option)) throw new ArgumentOutOfRangeException(nameof(option), "Invalid vote option ID"); @@ -228,7 +229,7 @@ namespace Content.Server.Voting.Managers private void SendUpdates(VoteReg v) { - foreach (var player in _playerManager.ServerSessions) + foreach (var player in _playerManager.Sessions) { SendSingleUpdate(v, player); } @@ -237,7 +238,7 @@ namespace Content.Server.Voting.Managers v.Dirty = false; } - private void SendSingleUpdate(VoteReg v, IPlayerSession player) + private void SendSingleUpdate(VoteReg v, ICommonSession player) { var msg = new MsgVoteData(); @@ -277,10 +278,10 @@ namespace Content.Server.Voting.Managers private void DirtyCanCallVoteAll() { - _playerCanCallVoteDirty.UnionWith(_playerManager.ServerSessions); + _playerCanCallVoteDirty.UnionWith(_playerManager.Sessions); } - private void SendUpdateCanCallVote(IPlayerSession player) + private void SendUpdateCanCallVote(ICommonSession player) { var msg = new MsgVoteCanCall(); msg.CanCall = CanCallVote(player, null, out var isAdmin, out var timeSpan); @@ -306,7 +307,7 @@ namespace Content.Server.Voting.Managers } private bool CanCallVote( - IPlayerSession initiator, + ICommonSession initiator, StandardVoteType? voteType, out bool isAdmin, out TimeSpan timeSpan) @@ -353,7 +354,7 @@ namespace Content.Server.Voting.Managers return !_voteTimeout.TryGetValue(initiator.UserId, out timeSpan); } - public bool CanCallVote(IPlayerSession initiator, StandardVoteType? voteType = null) + public bool CanCallVote(ICommonSession initiator, StandardVoteType? voteType = null) { return CanCallVote(initiator, voteType, out _, out _); } @@ -406,14 +407,14 @@ namespace Content.Server.Voting.Managers return false; } - private void DirtyCanCallVote(IPlayerSession player) + private void DirtyCanCallVote(ICommonSession player) { _playerCanCallVoteDirty.Add(player); } #region Preset Votes - private void WirePresetVoteInitiator(VoteOptions options, IPlayerSession? player) + private void WirePresetVoteInitiator(VoteOptions options, ICommonSession? player) { if (player != null) { @@ -432,13 +433,13 @@ namespace Content.Server.Voting.Managers private sealed class VoteReg { public readonly int Id; - public readonly Dictionary CastVotes = new(); + public readonly Dictionary CastVotes = new(); public readonly VoteEntry[] Entries; public readonly string Title; public readonly string InitiatorText; public readonly TimeSpan StartTime; public readonly TimeSpan EndTime; - public readonly HashSet VotesDirty = new(); + public readonly HashSet VotesDirty = new(); public bool Cancelled; public bool Finished; @@ -446,10 +447,10 @@ namespace Content.Server.Voting.Managers public VoteFinishedEventHandler? OnFinished; public VoteCancelledEventHandler? OnCancelled; - public IPlayerSession? Initiator { get; } + public ICommonSession? Initiator { get; } public VoteReg(int id, VoteEntry[] entries, string title, string initiatorText, - IPlayerSession? initiator, TimeSpan start, TimeSpan end) + ICommonSession? initiator, TimeSpan start, TimeSpan end) { Id = id; Entries = entries; @@ -517,7 +518,7 @@ namespace Content.Server.Voting.Managers return _mgr.IsValidOption(_reg, optionId); } - public void CastVote(IPlayerSession session, int? optionId) + public void CastVote(ICommonSession session, int? optionId) { _mgr.CastVote(_reg, session, optionId); } diff --git a/Content.Server/Voting/VoteCommands.cs b/Content.Server/Voting/VoteCommands.cs index cb296a7d58..498c9d0494 100644 --- a/Content.Server/Voting/VoteCommands.cs +++ b/Content.Server/Voting/VoteCommands.cs @@ -6,7 +6,6 @@ using Content.Server.Voting.Managers; using Content.Shared.Administration; using Content.Shared.Database; using Content.Shared.Voting; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Voting @@ -36,14 +35,14 @@ namespace Content.Server.Voting var mgr = IoCManager.Resolve(); - if (shell.Player != null && !mgr.CanCallVote((IPlayerSession) shell.Player, type)) + if (shell.Player != null && !mgr.CanCallVote(shell.Player, type)) { _adminLogger.Add(LogType.Vote, LogImpact.Medium, $"{shell.Player} failed to start {type.ToString()} vote"); shell.WriteError(Loc.GetString("cmd-createvote-cannot-call-vote-now")); return; } - mgr.CreateStandardVote((IPlayerSession?) shell.Player, type); + mgr.CreateStandardVote(shell.Player, type); } public CompletionResult GetCompletion(IConsoleShell shell, string[] args) @@ -92,7 +91,7 @@ namespace Content.Server.Voting options.Options.Add((args[i], i)); } - options.SetInitiatorOrServer((IPlayerSession?) shell.Player); + options.SetInitiatorOrServer(shell.Player); if (shell.Player != null) _adminLogger.Add(LogType.Vote, LogImpact.Medium, $"{shell.Player} initiated a custom vote: {options.Title} - {string.Join("; ", options.Options.Select(x => x.text))}"); @@ -187,7 +186,7 @@ namespace Content.Server.Voting return; } - vote.CastVote((IPlayerSession) shell.Player!, optionN); + vote.CastVote(shell.Player!, optionN); } } diff --git a/Content.Server/Voting/VoteOptions.cs b/Content.Server/Voting/VoteOptions.cs index 6e6d0465ed..5475d10d32 100644 --- a/Content.Server/Voting/VoteOptions.cs +++ b/Content.Server/Voting/VoteOptions.cs @@ -1,4 +1,4 @@ -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Voting @@ -16,7 +16,7 @@ namespace Content.Server.Voting /// /// The player that started the vote. Used to keep track of player cooldowns to avoid vote spam. /// - public IPlayerSession? InitiatorPlayer { get; set; } + public ICommonSession? InitiatorPlayer { get; set; } /// /// The shown title of the vote. @@ -43,13 +43,13 @@ namespace Content.Server.Voting /// Sets and /// by setting the latter to the player's name. /// - public void SetInitiator(IPlayerSession player) + public void SetInitiator(ICommonSession player) { InitiatorPlayer = player; InitiatorText = player.Name; } - public void SetInitiatorOrServer(IPlayerSession? player) + public void SetInitiatorOrServer(ICommonSession? player) { if (player != null) { diff --git a/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs b/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs index 1b6b2ebef1..3d9c3e8219 100644 --- a/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs +++ b/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs @@ -24,11 +24,9 @@ using Content.Shared.StatusEffect; using Content.Shared.Tag; using Content.Shared.Weapons.Melee; using Content.Shared.Weapons.Melee.Events; -using Robust.Server.Player; using Robust.Shared.Audio; using Robust.Shared.Map; using Robust.Shared.Player; -using Robust.Shared.Players; using Robust.Shared.Random; namespace Content.Server.Weapons.Melee; @@ -174,7 +172,7 @@ public sealed class MeleeWeaponSystem : SharedMeleeWeaponSystem EntityCoordinates targetCoordinates; Angle targetLocalAngle; - if (session is IPlayerSession pSession) + if (session is { } pSession) { (targetCoordinates, targetLocalAngle) = _lag.GetCoordinatesAngle(target, pSession); } diff --git a/Content.Server/Wires/WiresSystem.cs b/Content.Server/Wires/WiresSystem.cs index e75ad0a9ef..b6452efa8a 100644 --- a/Content.Server/Wires/WiresSystem.cs +++ b/Content.Server/Wires/WiresSystem.cs @@ -16,7 +16,7 @@ using Content.Shared.Tools; using Content.Shared.Tools.Components; using Content.Shared.Wires; using Robust.Server.GameObjects; -using Robust.Server.Player; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; @@ -616,7 +616,7 @@ public sealed class WiresSystem : SharedWiresSystem wires.WireSeed), ui: ui); } - public void OpenUserInterface(EntityUid uid, IPlayerSession player) + public void OpenUserInterface(EntityUid uid, ICommonSession player) { if (_uiSystem.TryGetUi(uid, WiresUiKey.Key, out var ui)) _uiSystem.OpenUi(ui, player); diff --git a/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs b/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs index 49036fb19d..9200928d66 100644 --- a/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs +++ b/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs @@ -17,7 +17,6 @@ using Content.Shared.Xenoarchaeology.Equipment; using Content.Shared.Xenoarchaeology.XenoArtifacts; using JetBrains.Annotations; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Audio; using Robust.Shared.Prototypes; using Robust.Shared.Timing; @@ -229,7 +228,7 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem /// private void OnServerSelectionMessage(EntityUid uid, AnalysisConsoleComponent component, AnalysisConsoleServerSelectionMessage args) { - _ui.TryOpen(uid, ResearchClientUiKey.Key, (IPlayerSession) args.Session); + _ui.TryOpen(uid, ResearchClientUiKey.Key, args.Session); } /// diff --git a/Content.Shared/Administration/Managers/ISharedAdminManager.cs b/Content.Shared/Administration/Managers/ISharedAdminManager.cs index 7e01c81433..22d918d4a3 100644 --- a/Content.Shared/Administration/Managers/ISharedAdminManager.cs +++ b/Content.Shared/Administration/Managers/ISharedAdminManager.cs @@ -1,4 +1,4 @@ -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Shared.Administration.Managers; diff --git a/Content.Shared/Buckle/SharedBuckleSystem.cs b/Content.Shared/Buckle/SharedBuckleSystem.cs index 7edf2448ae..1441745b5d 100644 --- a/Content.Shared/Buckle/SharedBuckleSystem.cs +++ b/Content.Shared/Buckle/SharedBuckleSystem.cs @@ -11,7 +11,7 @@ using Robust.Shared.Containers; using Robust.Shared.Map; using Robust.Shared.Network; using Robust.Shared.Physics.Systems; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Shared.Buckle; diff --git a/Content.Shared/Hands/EntitySystems/SharedHandsSystem.Interactions.cs b/Content.Shared/Hands/EntitySystems/SharedHandsSystem.Interactions.cs index d0c3be3b31..dfa72fcfb7 100644 --- a/Content.Shared/Hands/EntitySystems/SharedHandsSystem.Interactions.cs +++ b/Content.Shared/Hands/EntitySystems/SharedHandsSystem.Interactions.cs @@ -6,7 +6,7 @@ using Content.Shared.Input; using Content.Shared.Localizations; using Robust.Shared.Input.Binding; using Robust.Shared.Map; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Shared.Hands.EntitySystems; diff --git a/Content.Shared/Interaction/SharedInteractionSystem.cs b/Content.Shared/Interaction/SharedInteractionSystem.cs index 4a9a43ca2c..7981deaee6 100644 --- a/Content.Shared/Interaction/SharedInteractionSystem.cs +++ b/Content.Shared/Interaction/SharedInteractionSystem.cs @@ -34,7 +34,7 @@ using Robust.Shared.Network; using Robust.Shared.Physics; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Random; using Robust.Shared.Serialization; using Robust.Shared.Timing; diff --git a/Content.Shared/Mind/Components/MindContainerComponent.cs b/Content.Shared/Mind/Components/MindContainerComponent.cs index ca0f14d994..62b26cbd35 100644 --- a/Content.Shared/Mind/Components/MindContainerComponent.cs +++ b/Content.Shared/Mind/Components/MindContainerComponent.cs @@ -1,24 +1,25 @@ using System.Diagnostics.CodeAnalysis; +using Robust.Shared.GameStates; namespace Content.Shared.Mind.Components { /// - /// Stores a on a mob. + /// This component indicates that this entity may have mind, which is simply an entity with a . + /// The mind entity is not actually stored in a "container", but is simply stored in nullspace. /// - [RegisterComponent, Access(typeof(SharedMindSystem))] + [RegisterComponent, Access(typeof(SharedMindSystem)), NetworkedComponent, AutoGenerateComponentState] public sealed partial class MindContainerComponent : Component { /// /// The mind controlling this mob. Can be null. /// - [ViewVariables] + [DataField, AutoNetworkedField] [Access(typeof(SharedMindSystem), Other = AccessPermissions.ReadWriteExecute)] // FIXME Friends public EntityUid? Mind { get; set; } /// /// True if we have a mind, false otherwise. /// - [ViewVariables] [MemberNotNullWhen(true, nameof(Mind))] public bool HasMind => Mind != null; @@ -26,7 +27,7 @@ namespace Content.Shared.Mind.Components /// Whether examining should show information about the mind or not. /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("showExamineInfo")] + [DataField("showExamineInfo"), AutoNetworkedField] public bool ShowExamineInfo { get; set; } /// @@ -38,19 +39,59 @@ namespace Content.Shared.Mind.Components public bool GhostOnShutdown { get; set; } = true; } - public sealed class MindRemovedMessage : EntityEventArgs + public abstract class MindEvent : EntityEventArgs { - public EntityUid OldMindId; - public MindComponent OldMind; + public readonly Entity Mind; + public readonly Entity Container; - public MindRemovedMessage(EntityUid oldMindId, MindComponent oldMind) + public MindEvent(Entity mind, Entity container) { - OldMindId = oldMindId; - OldMind = oldMind; + Mind = mind; + Container = container; } } - public sealed class MindAddedMessage : EntityEventArgs + /// + /// Event raised directed at a mind-container when a mind gets removed. + /// + public sealed class MindRemovedMessage : MindEvent { + public MindRemovedMessage(Entity mind, Entity container) + : base(mind, container) + { + } + } + + /// + /// Event raised directed at a mind when it gets removed from a mind-container. + /// + public sealed class MindGotRemovedEvent : MindEvent + { + public MindGotRemovedEvent(Entity mind, Entity container) + : base(mind, container) + { + } + } + + /// + /// Event raised directed at a mind-container when a mind gets added. + /// + public sealed class MindAddedMessage : MindEvent + { + public MindAddedMessage(Entity mind, Entity container) + : base(mind, container) + { + } + } + + /// + /// Event raised directed at a mind when it gets added to a mind-container. + /// + public sealed class MindGotAddedEvent : MindEvent + { + public MindGotAddedEvent(Entity mind, Entity container) + : base(mind, container) + { + } } } diff --git a/Content.Shared/Mind/MindComponent.cs b/Content.Shared/Mind/MindComponent.cs index 3ea92c3ce7..b147a2dbbe 100644 --- a/Content.Shared/Mind/MindComponent.cs +++ b/Content.Shared/Mind/MindComponent.cs @@ -1,84 +1,86 @@ using Content.Shared.GameTicking; using Content.Shared.Mind.Components; +using Robust.Shared.GameStates; using Robust.Shared.Network; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Shared.Mind { /// - /// This is added as a component to mind entities, not to player entities. - /// for the one that is added to players. - /// A mind represents the IC "mind" of a player. - /// Roles are attached as components to its owning entity. + /// This component stores information about a player/mob mind. The component will be attached to a mind-entity + /// which is stored in null-space. The entity that is currently "possessed" by the mind will have a + /// . /// /// + /// Roles are attached as components on the mind-entity entity. /// Think of it like this: if a player is supposed to have their memories, /// their mind follows along. /// /// Things such as respawning do not follow, because you're a new character. /// Getting borged, cloned, turned into a catbeast, etc... will keep it following you. + /// + /// Minds are stored in null-space, and are thus generally not set to players unless that player is the owner + /// of the mind. As a result it should be safe to network "secret" information like roles & objectives /// - [RegisterComponent] + [RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] public sealed partial class MindComponent : Component { - internal readonly List Objectives = new(); + [DataField, AutoNetworkedField] + public List Objectives = new(); /// /// The session ID of the player owning this mind. /// - [ViewVariables, Access(typeof(SharedMindSystem))] + [DataField, AutoNetworkedField, Access(typeof(SharedMindSystem))] public NetUserId? UserId { get; set; } /// /// The session ID of the original owner, if any. /// May end up used for round-end information (as the owner may have abandoned Mind since) /// - [ViewVariables, Access(typeof(SharedMindSystem))] + [DataField, AutoNetworkedField, Access(typeof(SharedMindSystem))] public NetUserId? OriginalOwnerUserId { get; set; } /// - /// Entity UID for the first entity that this mind controlled. Used for round end. + /// The first entity that this mind controlled. Used for round end information. /// Might be relevant if the player has ghosted since. /// - [ViewVariables] public EntityUid? OriginalOwnedEntity; + [DataField, AutoNetworkedField] + public NetEntity? OriginalOwnedEntity; + // This is a net entity, because this field currently ddoes not get set to null when this entity is deleted. + // This is a lazy way to ensure that people check that the entity still exists. + // TODO MIND Fix this properly by adding an OriginalMindContainerComponent or something like that. [ViewVariables] public bool IsVisitingEntity => VisitingEntity != null; - [ViewVariables, Access(typeof(SharedMindSystem))] + [DataField, AutoNetworkedField, Access(typeof(SharedMindSystem))] public EntityUid? VisitingEntity { get; set; } [ViewVariables] public EntityUid? CurrentEntity => VisitingEntity ?? OwnedEntity; - [ViewVariables(VVAccess.ReadWrite)] + [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)] public string? CharacterName { get; set; } /// /// The time of death for this Mind. /// Can be null - will be null if the Mind is not considered "dead". /// - [ViewVariables] + [DataField] public TimeSpan? TimeOfDeath { get; set; } - /// - /// The component currently owned by this mind. - /// Can be null. - /// - [ViewVariables] public MindContainerComponent? OwnedComponent; - /// /// The entity currently owned by this mind. /// Can be null. /// - [ViewVariables, Access(typeof(SharedMindSystem))] + [DataField, AutoNetworkedField, Access(typeof(SharedMindSystem))] public EntityUid? OwnedEntity { get; set; } - // TODO move objectives out of mind component /// /// An enumerable over all the objective entities this mind has. /// - [ViewVariables] + [ViewVariables, Obsolete("Use Objectives field")] public IEnumerable AllObjectives => Objectives; /// @@ -100,6 +102,7 @@ namespace Content.Shared.Mind /// Can be null, in which case the player is currently not logged in. /// [ViewVariables, Access(typeof(SharedMindSystem), typeof(SharedGameTicker))] + // TODO remove this after moving IPlayerManager functions to shared public ICommonSession? Session { get; set; } } } diff --git a/Content.Shared/Mind/SharedMindSystem.cs b/Content.Shared/Mind/SharedMindSystem.cs index cc4ac4af23..66a0325963 100644 --- a/Content.Shared/Mind/SharedMindSystem.cs +++ b/Content.Shared/Mind/SharedMindSystem.cs @@ -1,4 +1,5 @@ using System.Diagnostics.CodeAnalysis; +using System.Linq; using Content.Shared.Administration.Logs; using Content.Shared.Database; using Content.Shared.Examine; @@ -12,7 +13,7 @@ using Content.Shared.Objectives.Systems; using Content.Shared.Players; using Robust.Shared.Map; using Robust.Shared.Network; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Shared.Mind; @@ -25,7 +26,7 @@ public abstract class SharedMindSystem : EntitySystem [Dependency] private readonly SharedPlayerSystem _player = default!; [Dependency] private readonly MetaDataSystem _metadata = default!; - // This is dictionary is required to track the minds of disconnected players that may have had their entity deleted. + [ViewVariables] protected readonly Dictionary UserMinds = new(); public override void Initialize() @@ -36,6 +37,7 @@ public abstract class SharedMindSystem : EntitySystem SubscribeLocalEvent(OnSuicide); SubscribeLocalEvent(OnVisitingTerminating); SubscribeLocalEvent(OnReset); + SubscribeLocalEvent(OnMindStartup); } public override void Shutdown() @@ -44,6 +46,29 @@ public abstract class SharedMindSystem : EntitySystem WipeAllMinds(); } + private void OnMindStartup(EntityUid uid, MindComponent component, ComponentStartup args) + { + if (component.UserId == null) + return; + + if (UserMinds.TryAdd(component.UserId.Value, uid)) + return; + + var existing = UserMinds[component.UserId.Value]; + if (existing == uid) + return; + + if (!Exists(existing)) + { + Log.Error($"Found deleted entity in mind dictionary while initializing mind {ToPrettyString(uid)}"); + UserMinds[component.UserId.Value] = uid; + return; + } + + Log.Error($"Encountered a user {component.UserId} that is already assigned to a mind while initializing mind {ToPrettyString(uid)}. Ignoring user field."); + component.UserId = null; + } + private void OnReset(RoundRestartCleanupEvent ev) { WipeAllMinds(); @@ -51,12 +76,22 @@ public abstract class SharedMindSystem : EntitySystem public virtual void WipeAllMinds() { - foreach (var mind in UserMinds.Values) + Log.Info($"Wiping all minds"); + foreach (var mind in UserMinds.Values.ToArray()) { WipeMind(mind); } - DebugTools.Assert(UserMinds.Count == 0); + if (UserMinds.Count == 0) + return; + + foreach (var mind in UserMinds.Values) + { + if (Exists(mind)) + Log.Error($"Failed to wipe mind: {ToPrettyString(mind)}"); + } + + UserMinds.Clear(); } public EntityUid? GetMind(NetUserId user) @@ -80,6 +115,26 @@ public abstract class SharedMindSystem : EntitySystem return false; } + public bool TryGetMind(NetUserId user, [NotNullWhen(true)] out Entity? mind) + { + if (!TryGetMind(user, out var mindId, out var mindComp)) + { + mind = null; + return false; + } + + mind = (mindId.Value, mindComp); + return true; + } + + public Entity GetOrCreateMind(NetUserId user) + { + if (!TryGetMind(user, out var mind)) + mind = CreateMind(user); + + return mind.Value; + } + private void OnVisitingTerminating(EntityUid uid, VisitingMindComponent component, ref EntityTerminatingEvent args) { if (component.MindId != null) @@ -128,7 +183,7 @@ public abstract class SharedMindSystem : EntitySystem return null; } - public EntityUid CreateMind(NetUserId? userId, string? name = null) + public Entity CreateMind(NetUserId? userId, string? name = null) { var mindId = Spawn(null, MapCoordinates.Nullspace); _metadata.SetEntityName(mindId, name == null ? "mind" : $"mind ({name})"); @@ -136,7 +191,7 @@ public abstract class SharedMindSystem : EntitySystem mind.CharacterName = name; SetUserId(mindId, userId, mind); - return mindId; + return (mindId, mind); } /// @@ -195,7 +250,7 @@ public abstract class SharedMindSystem : EntitySystem /// Cleans up the VisitingEntity. /// /// - protected void RemoveVisitingEntity(MindComponent mind) + protected void RemoveVisitingEntity(EntityUid mindId, MindComponent mind) { if (mind.VisitingEntity == null) return; @@ -210,6 +265,7 @@ public abstract class SharedMindSystem : EntitySystem RemCompDeferred(oldVisitingEnt, visitComp); } + Dirty(mindId, mind); RaiseLocalEvent(oldVisitingEnt, new MindUnvisitedMessage(), true); } @@ -228,7 +284,7 @@ public abstract class SharedMindSystem : EntitySystem if (mindId == null || !Resolve(mindId.Value, ref mind, false)) return; - TransferTo(mindId.Value, null, mind: mind); + TransferTo(mindId.Value, null, createGhost:false, mind: mind); SetUserId(mindId.Value, null, mind: mind); } @@ -353,11 +409,11 @@ public abstract class SharedMindSystem : EntitySystem } public bool TryGetMind( - PlayerData player, + ContentPlayerData contentPlayer, out EntityUid mindId, [NotNullWhen(true)] out MindComponent? mind) { - mindId = player.Mind ?? default; + mindId = contentPlayer.Mind ?? default; return TryComp(mindId, out mind); } @@ -391,21 +447,6 @@ public abstract class SharedMindSystem : EntitySystem return TryComp(mindContainer.Mind, out role); } - /// - /// Sets the Mind's OwnedComponent and OwnedEntity - /// - /// Mind to set OwnedComponent and OwnedEntity on - /// Entity owned by - /// MindContainerComponent owned by - protected void SetOwnedEntity(MindComponent mind, EntityUid? uid, MindContainerComponent? mindContainerComponent) - { - if (uid != null) - Resolve(uid.Value, ref mindContainerComponent); - - mind.OwnedEntity = uid; - mind.OwnedComponent = mindContainerComponent; - } - /// /// Sets the Mind's UserId, Session, and updates the player's PlayerData. This should have no direct effect on the /// entity that any mind is connected to, except as a side effect of the fact that it may change a player's diff --git a/Content.Shared/Movement/Events/MoveInputEvent.cs b/Content.Shared/Movement/Events/MoveInputEvent.cs index 8e1b43f8bd..89e5636acd 100644 --- a/Content.Shared/Movement/Events/MoveInputEvent.cs +++ b/Content.Shared/Movement/Events/MoveInputEvent.cs @@ -1,5 +1,3 @@ -using Robust.Shared.Players; - namespace Content.Shared.Movement.Events; /// diff --git a/Content.Shared/Movement/Systems/SharedContentEyeSystem.cs b/Content.Shared/Movement/Systems/SharedContentEyeSystem.cs index 27e0080c87..4b81619fd0 100644 --- a/Content.Shared/Movement/Systems/SharedContentEyeSystem.cs +++ b/Content.Shared/Movement/Systems/SharedContentEyeSystem.cs @@ -5,7 +5,7 @@ using Content.Shared.Ghost; using Content.Shared.Input; using Content.Shared.Movement.Components; using Robust.Shared.Input.Binding; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Serialization; namespace Content.Shared.Movement.Systems; diff --git a/Content.Shared/Movement/Systems/SharedMoverController.Input.cs b/Content.Shared/Movement/Systems/SharedMoverController.Input.cs index 425322408e..1d323a9187 100644 --- a/Content.Shared/Movement/Systems/SharedMoverController.Input.cs +++ b/Content.Shared/Movement/Systems/SharedMoverController.Input.cs @@ -6,7 +6,7 @@ using Content.Shared.Movement.Components; using Content.Shared.Movement.Events; using Robust.Shared.Input; using Robust.Shared.Input.Binding; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Serialization; using Robust.Shared.Timing; using Robust.Shared.Utility; diff --git a/Content.Shared/Players/PlayerData.cs b/Content.Shared/Players/ContentPlayerData.cs similarity index 73% rename from Content.Shared/Players/PlayerData.cs rename to Content.Shared/Players/ContentPlayerData.cs index c6274c950b..7545eb58fc 100644 --- a/Content.Shared/Players/PlayerData.cs +++ b/Content.Shared/Players/ContentPlayerData.cs @@ -1,16 +1,15 @@ using Content.Shared.GameTicking; using Content.Shared.Mind; using Robust.Shared.Network; -using Robust.Shared.Player; namespace Content.Shared.Players; /// /// Content side for all data that tracks a player session. -/// Use to retrieve this from an . +/// Use to retrieve this from an . /// Not currently used on the client. /// -public sealed class PlayerData +public sealed class ContentPlayerData { /// /// The session ID of the player owning this data. @@ -38,21 +37,9 @@ public sealed class PlayerData /// public bool ExplicitlyDeadminned { get; set; } - public PlayerData(NetUserId userId, string name) + public ContentPlayerData(NetUserId userId, string name) { UserId = userId; Name = name; } -} - - -public static class PlayerDataExt -{ - /// - /// Gets the correctly cast instance of content player data from an engine player data storage. - /// - public static PlayerData? ContentData(this IPlayerData data) - { - return (PlayerData?) data.ContentDataUncast; - } -} +} \ No newline at end of file diff --git a/Content.Shared/Players/PlayerDataExt.cs b/Content.Shared/Players/PlayerDataExt.cs new file mode 100644 index 0000000000..eba4d8339d --- /dev/null +++ b/Content.Shared/Players/PlayerDataExt.cs @@ -0,0 +1,30 @@ +using Robust.Shared.Player; + +namespace Content.Shared.Players; + +public static class PlayerDataExt +{ + /// + /// Gets the correctly cast instance of content player data from an engine player data storage. + /// + public static ContentPlayerData? ContentData(this SessionData data) + { + return (ContentPlayerData?) data.ContentDataUncast; + } + + /// + /// Gets the correctly cast instance of content player data from an engine player data storage. + /// + public static ContentPlayerData? ContentData(this ICommonSession session) + { + return session.Data.ContentData(); + } + + /// + /// Gets the mind that is associated with this player. + /// + public static EntityUid? GetMind(this ICommonSession session) + { + return session.Data.ContentData()?.Mind; + } +} \ No newline at end of file diff --git a/Content.Shared/Players/SharedPlayerSystem.cs b/Content.Shared/Players/SharedPlayerSystem.cs index 6fc7ad6a40..7271c5688a 100644 --- a/Content.Shared/Players/SharedPlayerSystem.cs +++ b/Content.Shared/Players/SharedPlayerSystem.cs @@ -1,4 +1,4 @@ -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Shared.Players; @@ -8,5 +8,5 @@ namespace Content.Shared.Players; /// public abstract class SharedPlayerSystem : EntitySystem { - public abstract PlayerData? ContentData(ICommonSession? session); + public abstract ContentPlayerData? ContentData(ICommonSession? session); } diff --git a/Content.Shared/Popups/SharedPopupSystem.cs b/Content.Shared/Popups/SharedPopupSystem.cs index 50013a5435..e4565b90e8 100644 --- a/Content.Shared/Popups/SharedPopupSystem.cs +++ b/Content.Shared/Popups/SharedPopupSystem.cs @@ -1,6 +1,5 @@ using Robust.Shared.Map; using Robust.Shared.Player; -using Robust.Shared.Players; using Robust.Shared.Serialization; namespace Content.Shared.Popups diff --git a/Content.Shared/Pulling/Systems/SharedPullingSystem.cs b/Content.Shared/Pulling/Systems/SharedPullingSystem.cs index 6f19d048b4..0c139ee9e3 100644 --- a/Content.Shared/Pulling/Systems/SharedPullingSystem.cs +++ b/Content.Shared/Pulling/Systems/SharedPullingSystem.cs @@ -12,7 +12,7 @@ using Robust.Shared.Map; using Robust.Shared.Physics; using Robust.Shared.Physics.Events; using Robust.Shared.Physics.Systems; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Shared.Pulling { diff --git a/Content.Shared/Roles/Jobs/SharedJobSystem.cs b/Content.Shared/Roles/Jobs/SharedJobSystem.cs index ac18d04e9c..af97ea1350 100644 --- a/Content.Shared/Roles/Jobs/SharedJobSystem.cs +++ b/Content.Shared/Roles/Jobs/SharedJobSystem.cs @@ -2,7 +2,7 @@ using System.Linq; using Content.Shared.Players; using Content.Shared.Players.PlayTimeTracking; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Utility; diff --git a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs index 4b740b8d3c..62af6067d0 100644 --- a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs +++ b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs @@ -23,7 +23,7 @@ using Robust.Shared.Audio; using Robust.Shared.Map; using Robust.Shared.Physics; using Robust.Shared.Physics.Systems; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Timing; From b98b0d9d36634dafbe8f335558c74702b8fe30d9 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Tue, 24 Oct 2023 20:24:50 +1100 Subject: [PATCH 023/102] Update submodule to 172.0.0 (#21222) --- RobustToolbox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RobustToolbox b/RobustToolbox index 554e0777b1..9750b113c8 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit 554e0777b1ba6ba096d8f4407d5c35ecc7b0f22f +Subproject commit 9750b113c81e7535d892326568760bc976072436 From ba6aaa5ff8c833520c7983f307e94782dbfbabff Mon Sep 17 00:00:00 2001 From: Vasilis Date: Tue, 24 Oct 2023 11:28:31 +0200 Subject: [PATCH 024/102] Make stuttering less common with the trait (#21207) --- Resources/Prototypes/Traits/inconveniences.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Resources/Prototypes/Traits/inconveniences.yml b/Resources/Prototypes/Traits/inconveniences.yml index f8e932c9b9..657781d1b5 100644 --- a/Resources/Prototypes/Traits/inconveniences.yml +++ b/Resources/Prototypes/Traits/inconveniences.yml @@ -12,7 +12,7 @@ description: trait-socialanxiety-desc components: - type: StutteringAccent - matchRandomProb: 0.2 + matchRandomProb: 0.1 fourRandomProb: 0 - threeRandomProb: 0.3 + threeRandomProb: 0 cutRandomProb: 0 From ea0459fe6c4b5efcc51f1c2ff8820caee4159dae Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 24 Oct 2023 05:29:36 -0400 Subject: [PATCH 025/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 259437e311..d385c00de2 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,9 +1,4 @@ Entries: -- author: Potato1234_x - changes: - - {message: Vending machine sprites have been polished up., type: Tweak} - id: 4548 - time: '2023-08-13T07:15:13.0000000+00:00' - author: Ilya246 changes: - {message: 'Blood-red magboots now slow you down less and have jetpack functionality, @@ -2908,3 +2903,8 @@ Entries: hijacking, type: Add} id: 5047 time: '2023-10-24T07:55:47.0000000+00:00' +- author: VasilisThePikachu + changes: + - {message: Stuttering trait stutters less common., type: Fix} + id: 5048 + time: '2023-10-24T09:28:31.0000000+00:00' From 4701b853ef3cc2aac4a777f194ac26760d2235be Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Tue, 24 Oct 2023 21:44:09 +1100 Subject: [PATCH 026/102] Fix 0-length climbs (#21224) --- .../Climbing/Systems/ClimbSystem.cs | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Content.Shared/Climbing/Systems/ClimbSystem.cs b/Content.Shared/Climbing/Systems/ClimbSystem.cs index 511149f8f9..46255e4337 100644 --- a/Content.Shared/Climbing/Systems/ClimbSystem.cs +++ b/Content.Shared/Climbing/Systems/ClimbSystem.cs @@ -257,15 +257,25 @@ public sealed partial class ClimbSystem : VirtualController // Need direction relative to climber's parent. var localDirection = (-parentRot).RotateVec(worldDirection); - climbing.IsClimbing = true; - var climbDuration = TimeSpan.FromSeconds(distance / climbing.TransitionRate); - climbing.NextTransition = _timing.CurTime + climbDuration; + // On top of it already so just do it in place. + if (localDirection.LengthSquared() < 0.01f) + { + climbing.NextTransition = null; + } + // VirtualController over to the thing. + else + { + var climbDuration = TimeSpan.FromSeconds(distance / climbing.TransitionRate); + climbing.NextTransition = _timing.CurTime + climbDuration; - climbing.Direction = localDirection.Normalized() * climbing.TransitionRate; + climbing.Direction = localDirection.Normalized() * climbing.TransitionRate; + _actionBlockerSystem.UpdateCanMove(uid); + } + + climbing.IsClimbing = true; Dirty(uid, climbing); _audio.PlayPredicted(comp.FinishClimbSound, climbable, user); - _actionBlockerSystem.UpdateCanMove(uid); var startEv = new StartClimbEvent(climbable); var climbedEv = new ClimbedOnEvent(uid, user); From 517aea8bc3989c7b19fbc166c09133382ba35de3 Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 24 Oct 2023 06:45:17 -0400 Subject: [PATCH 027/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index d385c00de2..2d5a514f05 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,10 +1,4 @@ Entries: -- author: Ilya246 - changes: - - {message: 'Blood-red magboots now slow you down less and have jetpack functionality, - but cost more.', type: Tweak} - id: 4549 - time: '2023-08-13T07:17:10.0000000+00:00' - author: brainfood1183 changes: - {message: Syndicate clowns may now purchase a holoclown injector via their syndicate @@ -2908,3 +2902,9 @@ Entries: - {message: Stuttering trait stutters less common., type: Fix} id: 5048 time: '2023-10-24T09:28:31.0000000+00:00' +- author: metalgearsloth + changes: + - {message: Fix climbing in the same position (e.g. exiting from medical scanners) + sending you to the farplanes., type: Fix} + id: 5049 + time: '2023-10-24T10:44:09.0000000+00:00' From a2bbda43cc1669596942048c60b4ca80c00bbe6b Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Tue, 24 Oct 2023 21:55:20 +1100 Subject: [PATCH 028/102] Revert "Update submodule to 172.0.0 (#21222)" (#21225) --- Content.Client/Actions/ActionsSystem.cs | 9 +- .../Managers/ClientAdminManager.cs | 2 +- .../UI/Tabs/AdminTab/TeleportWindow.xaml.cs | 1 + Content.Client/Alerts/ClientAlertsSystem.cs | 9 +- .../CharacterInfo/CharacterInfoSystem.cs | 12 ++ .../Construction/ConstructionSystem.cs | 6 +- Content.Client/Drugs/DrugOverlaySystem.cs | 9 +- Content.Client/Drunk/DrunkSystem.cs | 9 +- Content.Client/Eye/Blinding/BlindingSystem.cs | 18 +- .../Eye/Blinding/BlurryVisionSystem.cs | 11 +- Content.Client/Eye/EyeLerpingSystem.cs | 4 +- Content.Client/Fullscreen/FullscreenHook.cs | 2 +- Content.Client/Gameplay/GameplayStateBase.cs | 2 +- Content.Client/Ghost/GhostSystem.cs | 12 +- Content.Client/Hands/Systems/HandsSystem.cs | 8 +- .../HealthOverlay/HealthOverlaySystem.cs | 13 +- .../Inventory/ClientInventorySystem.cs | 9 +- Content.Client/Mind/MindSystem.cs | 20 --- Content.Client/Overlays/EquipmentHudSystem.cs | 9 +- .../Physics/Controllers/MoverController.cs | 17 +- Content.Client/Players/PlayerSystem.cs | 4 +- Content.Client/Popups/PopupSystem.cs | 1 + .../ReplaySpectatorSystem.Movement.cs | 2 +- .../ReplaySpectatorSystem.Position.cs | 12 +- .../ReplaySpectatorSystem.Spectate.cs | 14 +- .../Replay/Spectator/ReplaySpectatorSystem.cs | 3 +- Content.Client/Sandbox/SandboxSystem.cs | 2 +- Content.Client/Traits/ParacusiaSystem.cs | 6 +- .../Character/CharacterUIController.cs | 8 +- .../Systems/Chat/ChatUIController.cs | 29 +++- .../DamageOverlayUiController.cs | 10 +- .../Systems/Sandbox/SandboxUIController.cs | 2 +- .../Weapons/Melee/MeleeWeaponSystem.cs | 3 +- Content.IntegrationTests/Pair/TestPair.cs | 8 +- .../Tests/Actions/ActionsAddedTest.cs | 4 +- .../Tests/Administration/Logs/AddTests.cs | 8 +- .../Tests/Administration/Logs/QueryTests.cs | 5 +- .../Tests/Cleanup/EuiManagerTest.cs | 2 +- .../Tests/Interaction/InteractionTest.cs | 5 +- .../Tests/Minds/GhostRoleTests.cs | 3 +- .../Tests/Minds/MindTests.EntityDeletion.cs | 13 +- .../Tests/Minds/MindTests.Helpers.cs | 20 +-- .../Tests/Minds/MindTests.ReconnectTests.cs | 9 +- .../Tests/Minds/MindTests.cs | 30 ++-- .../Tests/Toolshed/ToolshedTest.cs | 7 +- Content.MapRenderer/Painters/MapPainter.cs | 2 +- .../AdminPermsChangedEventArgs.cs | 6 +- .../Administration/Commands/AGhost.cs | 3 +- .../Commands/AdminWhoCommand.cs | 3 +- .../Commands/AnnounceUiCommand.cs | 3 +- .../Administration/Commands/BanCommand.cs | 11 +- .../Administration/Commands/BanListCommand.cs | 4 +- .../Commands/BanPanelCommand.cs | 8 +- .../Administration/Commands/ControlMob.cs | 14 +- .../Administration/Commands/DSay.cs | 4 +- .../Administration/Commands/DeAdminCommand.cs | 4 +- .../Commands/ExplosionCommand.cs | 3 +- .../Administration/Commands/FaxUiCommand.cs | 3 +- .../Commands/OpenAdminLogsCommand.cs | 3 +- .../Commands/OpenAdminNotesCommand.cs | 4 +- .../Commands/OpenPermissionsCommand.cs | 4 +- .../Commands/OpenUserVisibleNotesCommand.cs | 3 +- .../Administration/Commands/PardonCommand.cs | 3 +- .../Commands/PlayGlobalSoundCommand.cs | 1 + .../Administration/Commands/ReAdminCommand.cs | 4 +- .../Administration/Commands/SetAdminOOC.cs | 4 +- .../Administration/Commands/SetMindCommand.cs | 1 - .../Commands/SetOutfitCommand.cs | 3 +- .../Administration/Commands/WarpCommand.cs | 4 +- .../ContentNetworkResourceManager.cs | 4 +- .../Logs/AdminLogManager.Json.cs | 6 +- .../Logs/Converters/PlayerSessionConverter.cs | 6 +- .../Administration/Managers/AdminManager.cs | 52 +++--- .../Administration/Managers/BanManager.cs | 3 +- .../Administration/Managers/IAdminManager.cs | 15 +- .../Administration/Managers/IBanManager.cs | 4 +- .../Administration/Notes/AdminNotesManager.cs | 2 +- .../Administration/Notes/AdminNotesSystem.cs | 2 +- .../Notes/IAdminNotesManager.cs | 2 +- .../QuickDialogSystem.OpenDialog.cs | 10 +- .../Administration/QuickDialogSystem.cs | 7 +- .../Administration/Systems/AdminSystem.cs | 8 +- .../Systems/AdminTestArenaSystem.cs | 4 +- .../Administration/Systems/AdminVerbSystem.cs | 18 +- .../Administration/Systems/BwoinkSystem.cs | 5 +- .../Administration/Toolshed/AdminsCommand.cs | 6 +- Content.Server/Afk/AFKSystem.cs | 9 +- Content.Server/Afk/AfkManager.cs | 15 +- Content.Server/Afk/Events/AFKEvent.cs | 6 +- Content.Server/Afk/Events/UnAFKEvent.cs | 6 +- Content.Server/Alert/Commands/ClearAlert.cs | 3 +- Content.Server/Alert/Commands/ShowAlert.cs | 3 +- .../Commands/SetAlertLevelCommand.cs | 5 +- Content.Server/Antag/AntagSelectionSystem.cs | 9 +- .../Arcade/BlockGame/BlockGame.Ui.cs | 20 +-- .../BlockGame/BlockGameArcadeComponent.cs | 6 +- .../Arcade/BlockGame/BlockGameArcadeSystem.cs | 6 +- .../Atmos/Commands/DeleteGasCommand.cs | 3 +- .../Atmos/Commands/ShowAtmosCommand.cs | 3 +- .../EntitySystems/AtmosDebugOverlaySystem.cs | 11 +- .../Atmos/EntitySystems/GasTankSystem.cs | 7 + .../EntitySystems/GasTileOverlaySystem.cs | 7 +- .../Body/Commands/AddHandCommand.cs | 3 +- .../Body/Commands/AttachBodyPartCommand.cs | 4 +- .../Body/Commands/DestroyMechanismCommand.cs | 3 +- .../Body/Commands/RemoveHandCommand.cs | 3 +- Content.Server/Body/Systems/BodySystem.cs | 2 +- .../Cargo/Systems/CargoSystem.Orders.cs | 2 +- .../CartridgeLoader/CartridgeLoaderSystem.cs | 6 +- .../Chat/Commands/AdminChatCommand.cs | 3 +- Content.Server/Chat/Commands/LOOCCommand.cs | 3 +- Content.Server/Chat/Commands/MeCommand.cs | 3 +- Content.Server/Chat/Commands/OOCCommand.cs | 3 +- Content.Server/Chat/Commands/SayCommand.cs | 3 +- .../Chat/Commands/SuicideCommand.cs | 3 +- .../Chat/Commands/WhisperCommand.cs | 3 +- Content.Server/Chat/Managers/ChatManager.cs | 16 +- Content.Server/Chat/Managers/IChatManager.cs | 12 +- Content.Server/Chat/Systems/ChatSystem.cs | 21 +-- .../EntitySystems/ChemistryGuideDataSystem.cs | 1 - Content.Server/Chunking/ChunkingSystem.cs | 6 +- Content.Server/Commands/CommandUtils.cs | 7 +- .../Commands/FixRotationsCommand.cs | 3 +- .../Commands/TileReplaceCommand.cs | 3 +- .../Construction/Commands/TileWallsCommand.cs | 5 +- .../ConstructionSystem.Initial.cs | 2 +- .../CrewManifest/CrewManifestSystem.cs | 17 +- .../Damage/Commands/GodModeCommand.cs | 4 +- .../Damage/ForceSay/DamageForceSaySystem.cs | 1 + Content.Server/Database/UserDbDataManager.cs | 14 +- Content.Server/Decals/DecalSystem.cs | 13 +- .../Disposal/TubeConnectionsCommand.cs | 3 +- Content.Server/EUI/BaseEui.cs | 2 +- Content.Server/EUI/EuiManager.cs | 2 +- .../EntityList/SpawnEntityListCommand.cs | 3 +- Content.Server/Examine/ExamineSystem.cs | 3 +- .../PuddleDebugDebugOverlaySystem.cs | 8 +- Content.Server/Fluids/ShowFluidsCommand.cs | 3 +- .../GameTicking/Commands/JoinGameCommand.cs | 3 +- .../GameTicking/Commands/ObserveCommand.cs | 3 +- .../GameTicking/Commands/RespawnCommand.cs | 2 +- .../Commands/ToggleReadyCommand.cs | 3 +- .../GameTicking/GameTicker.GamePreset.cs | 6 +- .../GameTicking/GameTicker.Lobby.cs | 8 +- .../GameTicking/GameTicker.Player.cs | 19 +- .../GameTicking/GameTicker.RoundFlow.cs | 24 +-- .../GameTicking/GameTicker.Spawning.cs | 28 +-- .../Rules/Components/TraitorRuleComponent.cs | 4 +- .../Rules/InactivityTimeRestartRuleSystem.cs | 1 - .../GameTicking/Rules/NukeopsRuleSystem.cs | 18 +- .../GameTicking/Rules/PiratesRuleSystem.cs | 4 +- .../GameTicking/Rules/RespawnRuleSystem.cs | 1 - .../GameTicking/Rules/TraitorRuleSystem.cs | 13 +- .../GameTicking/Rules/ZombieRuleSystem.cs | 10 +- Content.Server/Ghost/Ghost.cs | 3 +- .../Roles/Components/TakeGhostRoleEvent.cs | 2 +- Content.Server/Ghost/Roles/GhostRoleSystem.cs | 10 +- .../Gravity/GravityGeneratorSystem.cs | 4 +- Content.Server/Hands/Systems/HandsSystem.cs | 9 +- .../HumanoidAppearanceSystem.Modifier.cs | 5 +- .../Instruments/InstrumentComponent.cs | 4 +- .../Instruments/InstrumentSystem.cs | 6 +- .../Interaction/InteractionSystem.cs | 1 + Content.Server/Interaction/TilePryCommand.cs | 5 +- .../MagicMirror/MagicMirrorSystem.cs | 5 +- Content.Server/Mapping/MappingCommand.cs | 2 +- Content.Server/Maps/GridDraggingSystem.cs | 9 +- Content.Server/Medical/DefibrillatorSystem.cs | 2 +- Content.Server/Mind/Commands/RenameCommand.cs | 1 - Content.Server/Mind/MindSystem.cs | 164 +++++++----------- Content.Server/Mind/Toolshed/MindCommand.cs | 6 +- Content.Server/Motd/MOTDCommand.cs | 7 +- Content.Server/Motd/MOTDSystem.cs | 14 +- Content.Server/Motd/SetMOTDCommand.cs | 7 +- .../Movement/Systems/LagCompensationSystem.cs | 2 +- Content.Server/NPC/Commands/NPCCommand.cs | 3 +- Content.Server/NPC/HTN/HTNSystem.cs | 7 +- .../NPC/Pathfinding/PathfindingSystem.cs | 4 +- .../NPC/Systems/NPCSteeringSystem.cs | 4 +- .../EntitySystems/NodeGroupSystem.cs | 7 +- Content.Server/Nutrition/Hungry.cs | 4 +- .../Commands/ListObjectivesCommand.cs | 2 +- Content.Server/PDA/PdaSystem.cs | 8 +- Content.Server/PDA/Ringer/RingerSystem.cs | 3 +- Content.Server/Paper/PaperSystem.cs | 6 +- Content.Server/Parallax/BiomeSystem.cs | 3 +- .../ParticleAcceleratorSystem.ControlBox.cs | 17 +- .../ParticleAcceleratorSystem.Parts.cs | 4 +- .../PlayTimeTrackingManager.cs | 40 ++--- .../PlayTimeTrackingSystem.cs | 13 +- Content.Server/Players/PlayerData.cs | 30 ++++ Content.Server/Players/PlayerSystem.cs | 4 +- .../Pointing/EntitySystems/PointingSystem.cs | 5 +- Content.Server/Popups/PopupSystem.cs | 1 + Content.Server/Prayer/PrayerSystem.cs | 7 +- .../Managers/IServerPreferencesManager.cs | 8 +- .../Managers/ServerPreferencesManager.cs | 8 +- Content.Server/Pulling/PullingSystem.cs | 2 +- .../Systems/RadiationSystem.Debug.cs | 2 +- .../Research/Systems/ResearchSystem.Client.cs | 3 +- Content.Server/Salvage/SalvageRulerCommand.cs | 3 +- .../Sandbox/Commands/ColorNetworkCommand.cs | 3 +- Content.Server/Sandbox/SandboxSystem.cs | 1 - .../SensorMonitoringConsoleComponent.cs | 2 +- .../SensorMonitoringConsoleSystem.UI.cs | 4 +- .../ServerUpdates/ServerUpdateManager.cs | 1 - .../Systems/EmergencyShuttleSystem.cs | 3 +- .../Silicons/Borgs/BorgSystem.Modules.cs | 2 +- Content.Server/Silicons/Borgs/BorgSystem.cs | 2 +- .../Silicons/Laws/SiliconLawSystem.cs | 5 +- .../Station/Systems/StationJobsSystem.cs | 2 +- .../Storage/EntitySystems/StorageSystem.cs | 3 +- Content.Server/Tabletop/TabletopSession.cs | 4 +- .../Tabletop/TabletopSystem.Session.cs | 8 +- Content.Server/Tabletop/TabletopSystem.cs | 7 +- .../Commands/AdminDebug/ACmdCommand.cs | 4 +- .../Toolshed/Commands/VisualizeCommand.cs | 3 +- .../Uplink/Commands/AddUplinkCommand.cs | 5 +- .../UserInterface/ActivatableUIComponent.cs | 4 +- .../UserInterface/ActivatableUISystem.cs | 8 +- .../UserInterface/StatValuesCommand.cs | 3 +- Content.Server/Verbs/VerbSystem.cs | 5 +- Content.Server/Voting/IVoteHandle.cs | 4 +- .../Voting/Managers/IVoteManager.cs | 6 +- .../Managers/VoteManager.DefaultVotes.cs | 12 +- Content.Server/Voting/Managers/VoteManager.cs | 31 ++-- Content.Server/Voting/VoteCommands.cs | 9 +- Content.Server/Voting/VoteOptions.cs | 8 +- .../Weapons/Melee/MeleeWeaponSystem.cs | 4 +- Content.Server/Wires/WiresSystem.cs | 4 +- .../Systems/ArtifactAnalyzerSystem.cs | 3 +- .../Managers/ISharedAdminManager.cs | 2 +- Content.Shared/Buckle/SharedBuckleSystem.cs | 2 +- .../SharedHandsSystem.Interactions.cs | 2 +- .../Interaction/SharedInteractionSystem.cs | 2 +- .../Mind/Components/MindContainerComponent.cs | 65 ++----- Content.Shared/Mind/MindComponent.cs | 49 +++--- Content.Shared/Mind/SharedMindSystem.cs | 91 +++------- .../Movement/Events/MoveInputEvent.cs | 2 + .../Systems/SharedContentEyeSystem.cs | 2 +- .../Systems/SharedMoverController.Input.cs | 2 +- .../{ContentPlayerData.cs => PlayerData.cs} | 21 ++- Content.Shared/Players/PlayerDataExt.cs | 30 ---- Content.Shared/Players/SharedPlayerSystem.cs | 4 +- Content.Shared/Popups/SharedPopupSystem.cs | 1 + .../Pulling/Systems/SharedPullingSystem.cs | 2 +- Content.Shared/Roles/Jobs/SharedJobSystem.cs | 2 +- .../Weapons/Melee/SharedMeleeWeaponSystem.cs | 2 +- RobustToolbox | 2 +- 249 files changed, 1049 insertions(+), 967 deletions(-) create mode 100644 Content.Server/Players/PlayerData.cs rename Content.Shared/Players/{ContentPlayerData.cs => PlayerData.cs} (73%) delete mode 100644 Content.Shared/Players/PlayerDataExt.cs diff --git a/Content.Client/Actions/ActionsSystem.cs b/Content.Client/Actions/ActionsSystem.cs index a487e5d8d8..83d927c94b 100644 --- a/Content.Client/Actions/ActionsSystem.cs +++ b/Content.Client/Actions/ActionsSystem.cs @@ -2,6 +2,7 @@ using System.IO; using System.Linq; using Content.Shared.Actions; using JetBrains.Annotations; +using Robust.Client.GameObjects; using Robust.Client.Player; using Robust.Shared.ContentPack; using Robust.Shared.GameStates; @@ -40,8 +41,8 @@ namespace Content.Client.Actions public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(HandleComponentState); SubscribeLocalEvent(OnInstantHandleState); @@ -195,12 +196,12 @@ namespace Content.Client.Actions return GetActions(user); } - private void OnPlayerAttached(EntityUid uid, ActionsComponent component, LocalPlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, ActionsComponent component, PlayerAttachedEvent args) { LinkAllActions(component); } - private void OnPlayerDetached(EntityUid uid, ActionsComponent component, LocalPlayerDetachedEvent? args = null) + private void OnPlayerDetached(EntityUid uid, ActionsComponent component, PlayerDetachedEvent? args = null) { UnlinkAllActions(); } diff --git a/Content.Client/Administration/Managers/ClientAdminManager.cs b/Content.Client/Administration/Managers/ClientAdminManager.cs index 1a1366c6f2..8978e2fd6d 100644 --- a/Content.Client/Administration/Managers/ClientAdminManager.cs +++ b/Content.Client/Administration/Managers/ClientAdminManager.cs @@ -4,7 +4,7 @@ using Robust.Client.Console; using Robust.Client.Player; using Robust.Shared.ContentPack; using Robust.Shared.Network; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Utility; namespace Content.Client.Administration.Managers diff --git a/Content.Client/Administration/UI/Tabs/AdminTab/TeleportWindow.xaml.cs b/Content.Client/Administration/UI/Tabs/AdminTab/TeleportWindow.xaml.cs index 1978b5c3c0..c5a9bd036a 100644 --- a/Content.Client/Administration/UI/Tabs/AdminTab/TeleportWindow.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/AdminTab/TeleportWindow.xaml.cs @@ -5,6 +5,7 @@ using Robust.Client.Console; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; using Robust.Shared.IoC; +using Robust.Shared.Players; namespace Content.Client.Administration.UI.Tabs.AdminTab { diff --git a/Content.Client/Alerts/ClientAlertsSystem.cs b/Content.Client/Alerts/ClientAlertsSystem.cs index 5089022415..bb6d2d4df4 100644 --- a/Content.Client/Alerts/ClientAlertsSystem.cs +++ b/Content.Client/Alerts/ClientAlertsSystem.cs @@ -1,6 +1,7 @@ using System.Linq; using Content.Shared.Alert; using JetBrains.Annotations; +using Robust.Client.GameObjects; using Robust.Client.Player; using Robust.Shared.Prototypes; @@ -21,8 +22,8 @@ public sealed class ClientAlertsSystem : AlertsSystem { base.Initialize(); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(ClientAlertsHandleState); } @@ -68,7 +69,7 @@ public sealed class ClientAlertsSystem : AlertsSystem SyncAlerts?.Invoke(this, component.Alerts); } - private void OnPlayerAttached(EntityUid uid, AlertsComponent component, LocalPlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, AlertsComponent component, PlayerAttachedEvent args) { if (_playerManager.LocalPlayer?.ControlledEntity != uid) return; @@ -86,7 +87,7 @@ public sealed class ClientAlertsSystem : AlertsSystem ClearAlerts?.Invoke(this, EventArgs.Empty); } - private void OnPlayerDetached(EntityUid uid, AlertsComponent component, LocalPlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, AlertsComponent component, PlayerDetachedEvent args) { ClearAlerts?.Invoke(this, EventArgs.Empty); } diff --git a/Content.Client/CharacterInfo/CharacterInfoSystem.cs b/Content.Client/CharacterInfo/CharacterInfoSystem.cs index 844a352a18..93bd86d140 100644 --- a/Content.Client/CharacterInfo/CharacterInfoSystem.cs +++ b/Content.Client/CharacterInfo/CharacterInfoSystem.cs @@ -1,5 +1,6 @@ using Content.Shared.CharacterInfo; using Content.Shared.Objectives; +using Robust.Client.GameObjects; using Robust.Client.Player; using Robust.Client.UserInterface; @@ -10,11 +11,14 @@ public sealed class CharacterInfoSystem : EntitySystem [Dependency] private readonly IPlayerManager _players = default!; public event Action? OnCharacterUpdate; + public event Action? OnCharacterDetached; public override void Initialize() { base.Initialize(); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeNetworkEvent(OnCharacterInfoEvent); } @@ -29,6 +33,14 @@ public sealed class CharacterInfoSystem : EntitySystem RaiseNetworkEvent(new RequestCharacterInfoEvent(GetNetEntity(entity.Value))); } + private void OnPlayerAttached(PlayerAttachSysMessage msg) + { + if (msg.AttachedEntity == default) + { + OnCharacterDetached?.Invoke(); + } + } + private void OnCharacterInfoEvent(CharacterInfoEvent msg, EntitySessionEventArgs args) { var entity = GetEntity(msg.NetEntity); diff --git a/Content.Client/Construction/ConstructionSystem.cs b/Content.Client/Construction/ConstructionSystem.cs index 9fc638cea2..98d2dfd414 100644 --- a/Content.Client/Construction/ConstructionSystem.cs +++ b/Content.Client/Construction/ConstructionSystem.cs @@ -38,7 +38,7 @@ namespace Content.Client.Construction base.Initialize(); UpdatesOutsidePrediction = true; - SubscribeLocalEvent(HandlePlayerAttached); + SubscribeLocalEvent(HandlePlayerAttached); SubscribeNetworkEvent(HandleAckStructure); SubscribeNetworkEvent(OnConstructionGuideReceived); @@ -110,9 +110,9 @@ namespace Content.Client.Construction ClearGhost(msg.GhostId); } - private void HandlePlayerAttached(LocalPlayerAttachedEvent msg) + private void HandlePlayerAttached(PlayerAttachSysMessage msg) { - var available = IsCraftingAvailable(msg.Entity); + var available = IsCraftingAvailable(msg.AttachedEntity); UpdateCraftingAvailability(available); } diff --git a/Content.Client/Drugs/DrugOverlaySystem.cs b/Content.Client/Drugs/DrugOverlaySystem.cs index ec0d014072..7be63b4c50 100644 --- a/Content.Client/Drugs/DrugOverlaySystem.cs +++ b/Content.Client/Drugs/DrugOverlaySystem.cs @@ -1,4 +1,5 @@ using Content.Shared.Drugs; +using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.Player; @@ -23,18 +24,18 @@ public sealed class DrugOverlaySystem : EntitySystem SubscribeLocalEvent(OnInit); SubscribeLocalEvent(OnShutdown); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); _overlay = new(); } - private void OnPlayerAttached(EntityUid uid, SeeingRainbowsComponent component, LocalPlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, SeeingRainbowsComponent component, PlayerAttachedEvent args) { _overlayMan.AddOverlay(_overlay); } - private void OnPlayerDetached(EntityUid uid, SeeingRainbowsComponent component, LocalPlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, SeeingRainbowsComponent component, PlayerDetachedEvent args) { _overlay.Intoxication = 0; _overlayMan.RemoveOverlay(_overlay); diff --git a/Content.Client/Drunk/DrunkSystem.cs b/Content.Client/Drunk/DrunkSystem.cs index 4f2ec70b56..0573b2ff3e 100644 --- a/Content.Client/Drunk/DrunkSystem.cs +++ b/Content.Client/Drunk/DrunkSystem.cs @@ -1,4 +1,5 @@ using Content.Shared.Drunk; +using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.Player; @@ -18,18 +19,18 @@ public sealed class DrunkSystem : SharedDrunkSystem SubscribeLocalEvent(OnDrunkInit); SubscribeLocalEvent(OnDrunkShutdown); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); _overlay = new(); } - private void OnPlayerAttached(EntityUid uid, DrunkComponent component, LocalPlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, DrunkComponent component, PlayerAttachedEvent args) { _overlayMan.AddOverlay(_overlay); } - private void OnPlayerDetached(EntityUid uid, DrunkComponent component, LocalPlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, DrunkComponent component, PlayerDetachedEvent args) { _overlay.CurrentBoozePower = 0; _overlayMan.RemoveOverlay(_overlay); diff --git a/Content.Client/Eye/Blinding/BlindingSystem.cs b/Content.Client/Eye/Blinding/BlindingSystem.cs index f255f7ef01..f0b760d838 100644 --- a/Content.Client/Eye/Blinding/BlindingSystem.cs +++ b/Content.Client/Eye/Blinding/BlindingSystem.cs @@ -1,7 +1,17 @@ + +using Content.Shared.Eye.Blinding; +using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.Player; +using System; +using System.Collections.Generic; +using System.Linq; +using Content.Shared.Administration; +using Content.Shared.Administration.Events; using Content.Shared.Eye.Blinding.Components; using Content.Shared.GameTicking; +using Robust.Shared.GameObjects; +using Robust.Shared.Network; namespace Content.Client.Eye.Blinding; @@ -21,20 +31,20 @@ public sealed class BlindingSystem : EntitySystem SubscribeLocalEvent(OnBlindInit); SubscribeLocalEvent(OnBlindShutdown); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeNetworkEvent(RoundRestartCleanup); _overlay = new(); } - private void OnPlayerAttached(EntityUid uid, BlindableComponent component, LocalPlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, BlindableComponent component, PlayerAttachedEvent args) { _overlayMan.AddOverlay(_overlay); } - private void OnPlayerDetached(EntityUid uid, BlindableComponent component, LocalPlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, BlindableComponent component, PlayerDetachedEvent args) { _overlayMan.RemoveOverlay(_overlay); _lightManager.Enabled = true; diff --git a/Content.Client/Eye/Blinding/BlurryVisionSystem.cs b/Content.Client/Eye/Blinding/BlurryVisionSystem.cs index 8be5b4ed93..1bac2a97bf 100644 --- a/Content.Client/Eye/Blinding/BlurryVisionSystem.cs +++ b/Content.Client/Eye/Blinding/BlurryVisionSystem.cs @@ -1,6 +1,9 @@ +using Content.Shared.Eye.Blinding; using Content.Shared.Eye.Blinding.Components; +using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.Player; +using Robust.Shared.GameStates; namespace Content.Client.Eye.Blinding; @@ -17,18 +20,18 @@ public sealed class BlurryVisionSystem : EntitySystem SubscribeLocalEvent(OnBlurryInit); SubscribeLocalEvent(OnBlurryShutdown); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); _overlay = new(); } - private void OnPlayerAttached(EntityUid uid, BlurryVisionComponent component, LocalPlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, BlurryVisionComponent component, PlayerAttachedEvent args) { _overlayMan.AddOverlay(_overlay); } - private void OnPlayerDetached(EntityUid uid, BlurryVisionComponent component, LocalPlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, BlurryVisionComponent component, PlayerDetachedEvent args) { _overlayMan.RemoveOverlay(_overlay); } diff --git a/Content.Client/Eye/EyeLerpingSystem.cs b/Content.Client/Eye/EyeLerpingSystem.cs index b46921a9b4..8e54196b81 100644 --- a/Content.Client/Eye/EyeLerpingSystem.cs +++ b/Content.Client/Eye/EyeLerpingSystem.cs @@ -30,7 +30,7 @@ public sealed class EyeLerpingSystem : EntitySystem SubscribeLocalEvent(OnAttached); SubscribeLocalEvent(HandleMapChange); - SubscribeLocalEvent(OnDetached); + SubscribeLocalEvent(OnDetached); UpdatesAfter.Add(typeof(TransformSystem)); UpdatesAfter.Add(typeof(PhysicsSystem)); @@ -94,7 +94,7 @@ public sealed class EyeLerpingSystem : EntitySystem AddEye(ev.Entity, ev.Component, true); } - private void OnDetached(EntityUid uid, LerpingEyeComponent component, LocalPlayerDetachedEvent args) + private void OnDetached(EntityUid uid, LerpingEyeComponent component, PlayerDetachedEvent args) { if (!component.ManuallyAdded) RemCompDeferred(uid, component); diff --git a/Content.Client/Fullscreen/FullscreenHook.cs b/Content.Client/Fullscreen/FullscreenHook.cs index 7917fddfbb..78a0151736 100644 --- a/Content.Client/Fullscreen/FullscreenHook.cs +++ b/Content.Client/Fullscreen/FullscreenHook.cs @@ -4,7 +4,7 @@ using Robust.Client.Input; using Robust.Shared.Input.Binding; using Robust.Shared; using Robust.Shared.Configuration; -using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Client.Fullscreen; public sealed class FullscreenHook diff --git a/Content.Client/Gameplay/GameplayStateBase.cs b/Content.Client/Gameplay/GameplayStateBase.cs index 454c063260..788a4e5dff 100644 --- a/Content.Client/Gameplay/GameplayStateBase.cs +++ b/Content.Client/Gameplay/GameplayStateBase.cs @@ -16,7 +16,7 @@ using Robust.Shared.Console; using Robust.Shared.Input; using Robust.Shared.Input.Binding; using Robust.Shared.Map; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Timing; namespace Content.Client.Gameplay diff --git a/Content.Client/Ghost/GhostSystem.cs b/Content.Client/Ghost/GhostSystem.cs index a89d0858d9..5727534109 100644 --- a/Content.Client/Ghost/GhostSystem.cs +++ b/Content.Client/Ghost/GhostSystem.cs @@ -58,10 +58,10 @@ namespace Content.Client.Ghost SubscribeLocalEvent(OnGhostRemove); SubscribeLocalEvent(OnGhostState); - SubscribeLocalEvent(OnGhostPlayerAttach); - SubscribeLocalEvent(OnGhostPlayerDetach); + SubscribeLocalEvent(OnGhostPlayerAttach); + SubscribeLocalEvent(OnGhostPlayerDetach); - SubscribeLocalEvent(OnPlayerAttach); + SubscribeLocalEvent(OnPlayerAttach); SubscribeNetworkEvent(OnGhostWarpsResponse); SubscribeNetworkEvent(OnUpdateGhostRoleCount); @@ -130,7 +130,7 @@ namespace Content.Client.Ghost PlayerRemoved?.Invoke(component); } - private void OnGhostPlayerAttach(EntityUid uid, GhostComponent component, LocalPlayerAttachedEvent localPlayerAttachedEvent) + private void OnGhostPlayerAttach(EntityUid uid, GhostComponent component, PlayerAttachedEvent playerAttachedEvent) { if (uid != _playerManager.LocalPlayer?.ControlledEntity) return; @@ -161,13 +161,13 @@ namespace Content.Client.Ghost return true; } - private void OnGhostPlayerDetach(EntityUid uid, GhostComponent component, LocalPlayerDetachedEvent args) + private void OnGhostPlayerDetach(EntityUid uid, GhostComponent component, PlayerDetachedEvent args) { if (PlayerDetach(uid)) component.IsAttached = false; } - private void OnPlayerAttach(LocalPlayerAttachedEvent ev) + private void OnPlayerAttach(PlayerAttachedEvent ev) { if (!HasComp(ev.Entity)) PlayerDetach(ev.Entity); diff --git a/Content.Client/Hands/Systems/HandsSystem.cs b/Content.Client/Hands/Systems/HandsSystem.cs index 31de7ec143..ed40589f7f 100644 --- a/Content.Client/Hands/Systems/HandsSystem.cs +++ b/Content.Client/Hands/Systems/HandsSystem.cs @@ -42,8 +42,8 @@ namespace Content.Client.Hands.Systems { base.Initialize(); - SubscribeLocalEvent(HandlePlayerAttached); - SubscribeLocalEvent(HandlePlayerDetached); + SubscribeLocalEvent(HandlePlayerAttached); + SubscribeLocalEvent(HandlePlayerDetached); SubscribeLocalEvent(OnHandsStartup); SubscribeLocalEvent(OnHandsShutdown); SubscribeLocalEvent(HandleComponentState); @@ -361,12 +361,12 @@ namespace Content.Client.Hands.Systems #region Gui - private void HandlePlayerAttached(EntityUid uid, HandsComponent component, LocalPlayerAttachedEvent args) + private void HandlePlayerAttached(EntityUid uid, HandsComponent component, PlayerAttachedEvent args) { OnPlayerHandsAdded?.Invoke(component); } - private void HandlePlayerDetached(EntityUid uid, HandsComponent component, LocalPlayerDetachedEvent args) + private void HandlePlayerDetached(EntityUid uid, HandsComponent component, PlayerDetachedEvent args) { OnPlayerHandsRemoved?.Invoke(); } diff --git a/Content.Client/HealthOverlay/HealthOverlaySystem.cs b/Content.Client/HealthOverlay/HealthOverlaySystem.cs index 29ac937199..baeb4fe025 100644 --- a/Content.Client/HealthOverlay/HealthOverlaySystem.cs +++ b/Content.Client/HealthOverlay/HealthOverlaySystem.cs @@ -3,8 +3,8 @@ using Content.Shared.Damage; using Content.Shared.GameTicking; using Content.Shared.Mobs.Components; using JetBrains.Annotations; +using Robust.Client.GameObjects; using Robust.Client.Graphics; -using Robust.Client.Player; namespace Content.Client.HealthOverlay { @@ -13,9 +13,9 @@ namespace Content.Client.HealthOverlay { [Dependency] private readonly IEyeManager _eyeManager = default!; [Dependency] private readonly IEntityManager _entities = default!; - [Dependency] private readonly IPlayerManager _player = default!; private readonly Dictionary _guis = new(); + private EntityUid? _attachedEntity; private bool _enabled; public bool Enabled @@ -42,6 +42,7 @@ namespace Content.Client.HealthOverlay base.Initialize(); SubscribeNetworkEvent(Reset); + SubscribeLocalEvent(HandlePlayerAttached); } public void Reset(RoundRestartCleanupEvent ev) @@ -52,6 +53,12 @@ namespace Content.Client.HealthOverlay } _guis.Clear(); + _attachedEntity = default; + } + + private void HandlePlayerAttached(PlayerAttachSysMessage message) + { + _attachedEntity = message.AttachedEntity; } public override void FrameUpdate(float frameTime) @@ -63,7 +70,7 @@ namespace Content.Client.HealthOverlay return; } - if (_player.LocalEntity is not {} ent || Deleted(ent)) + if (_attachedEntity is not {} ent || Deleted(ent)) { return; } diff --git a/Content.Client/Inventory/ClientInventorySystem.cs b/Content.Client/Inventory/ClientInventorySystem.cs index f0a12b3b1f..ffff392aa4 100644 --- a/Content.Client/Inventory/ClientInventorySystem.cs +++ b/Content.Client/Inventory/ClientInventorySystem.cs @@ -10,6 +10,7 @@ using Content.Shared.Inventory; using Content.Shared.Inventory.Events; using Content.Shared.Storage; using JetBrains.Annotations; +using Robust.Client.GameObjects; using Robust.Client.Player; using Robust.Client.UserInterface; using Robust.Shared.Containers; @@ -42,8 +43,8 @@ namespace Content.Client.Inventory UpdatesOutsidePrediction = true; base.Initialize(); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(OnShutdown); @@ -112,12 +113,12 @@ namespace Content.Client.Inventory OnUnlinkInventory?.Invoke(); } - private void OnPlayerDetached(EntityUid uid, InventorySlotsComponent component, LocalPlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, InventorySlotsComponent component, PlayerDetachedEvent args) { OnUnlinkInventory?.Invoke(); } - private void OnPlayerAttached(EntityUid uid, InventorySlotsComponent component, LocalPlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, InventorySlotsComponent component, PlayerAttachedEvent args) { if (TryGetSlots(uid, out var definitions)) { diff --git a/Content.Client/Mind/MindSystem.cs b/Content.Client/Mind/MindSystem.cs index cc43c349e4..87d9e9ddbe 100644 --- a/Content.Client/Mind/MindSystem.cs +++ b/Content.Client/Mind/MindSystem.cs @@ -4,24 +4,4 @@ namespace Content.Client.Mind; public sealed class MindSystem : SharedMindSystem { - public override void Initialize() - { - base.Initialize(); - SubscribeLocalEvent(OnHandleState); - } - - private void OnHandleState(EntityUid uid, MindComponent component, ref AfterAutoHandleStateEvent args) - { - // Because minds are generally not networked, there might be weird situations were a client thinks multiple - // users share a mind? E.g., if an admin periodical gets sent all minds via some PVS override, but doesn't get - // sent intermediate states? Not sure if this is actually possible, but better to be safe. - foreach (var (user, mind) in UserMinds) - { - if (mind == uid) - UserMinds.Remove(user); - } - - if (component.UserId != null) - UserMinds[component.UserId.Value] = uid; - } } diff --git a/Content.Client/Overlays/EquipmentHudSystem.cs b/Content.Client/Overlays/EquipmentHudSystem.cs index ac618691d8..1d5ec03291 100644 --- a/Content.Client/Overlays/EquipmentHudSystem.cs +++ b/Content.Client/Overlays/EquipmentHudSystem.cs @@ -1,6 +1,7 @@ using Content.Shared.GameTicking; using Content.Shared.Inventory; using Content.Shared.Inventory.Events; +using Robust.Client.GameObjects; using Robust.Client.Player; namespace Content.Client.Overlays; @@ -23,8 +24,8 @@ public abstract class EquipmentHudSystem : EntitySystem where T : IComponent SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnRemove); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(OnCompEquip); SubscribeLocalEvent(OnCompUnequip); @@ -64,12 +65,12 @@ public abstract class EquipmentHudSystem : EntitySystem where T : IComponent RefreshOverlay(uid); } - private void OnPlayerAttached(LocalPlayerAttachedEvent args) + private void OnPlayerAttached(PlayerAttachedEvent args) { RefreshOverlay(args.Entity); } - private void OnPlayerDetached(LocalPlayerDetachedEvent args) + private void OnPlayerDetached(PlayerDetachedEvent args) { if (_player.LocalPlayer?.ControlledEntity == null) Deactivate(); diff --git a/Content.Client/Physics/Controllers/MoverController.cs b/Content.Client/Physics/Controllers/MoverController.cs index 52340b3391..54c5c3de15 100644 --- a/Content.Client/Physics/Controllers/MoverController.cs +++ b/Content.Client/Physics/Controllers/MoverController.cs @@ -1,6 +1,7 @@ using Content.Shared.Movement.Components; using Content.Shared.Movement.Systems; using Content.Shared.Pulling.Components; +using Robust.Client.GameObjects; using Robust.Client.Physics; using Robust.Client.Player; using Robust.Shared.Physics.Components; @@ -16,10 +17,10 @@ namespace Content.Client.Physics.Controllers public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnRelayPlayerAttached); - SubscribeLocalEvent(OnRelayPlayerDetached); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnRelayPlayerAttached); + SubscribeLocalEvent(OnRelayPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(OnUpdatePredicted); SubscribeLocalEvent(OnUpdateRelayTargetPredicted); @@ -53,7 +54,7 @@ namespace Content.Client.Physics.Controllers // What if the entity is being pulled by a vehicle controlled by the player? } - private void OnRelayPlayerAttached(EntityUid uid, RelayInputMoverComponent component, LocalPlayerAttachedEvent args) + private void OnRelayPlayerAttached(EntityUid uid, RelayInputMoverComponent component, PlayerAttachedEvent args) { Physics.UpdateIsPredicted(uid); Physics.UpdateIsPredicted(component.RelayEntity); @@ -61,7 +62,7 @@ namespace Content.Client.Physics.Controllers SetMoveInput(inputMover, MoveButtons.None); } - private void OnRelayPlayerDetached(EntityUid uid, RelayInputMoverComponent component, LocalPlayerDetachedEvent args) + private void OnRelayPlayerDetached(EntityUid uid, RelayInputMoverComponent component, PlayerDetachedEvent args) { Physics.UpdateIsPredicted(uid); Physics.UpdateIsPredicted(component.RelayEntity); @@ -69,12 +70,12 @@ namespace Content.Client.Physics.Controllers SetMoveInput(inputMover, MoveButtons.None); } - private void OnPlayerAttached(EntityUid uid, InputMoverComponent component, LocalPlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, InputMoverComponent component, PlayerAttachedEvent args) { SetMoveInput(component, MoveButtons.None); } - private void OnPlayerDetached(EntityUid uid, InputMoverComponent component, LocalPlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, InputMoverComponent component, PlayerDetachedEvent args) { SetMoveInput(component, MoveButtons.None); } diff --git a/Content.Client/Players/PlayerSystem.cs b/Content.Client/Players/PlayerSystem.cs index dba95ef7a6..d5ce4ec197 100644 --- a/Content.Client/Players/PlayerSystem.cs +++ b/Content.Client/Players/PlayerSystem.cs @@ -1,11 +1,11 @@ using Content.Shared.Players; -using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Client.Players; public sealed class PlayerSystem : SharedPlayerSystem { - public override ContentPlayerData? ContentData(ICommonSession? session) + public override PlayerData? ContentData(ICommonSession? session) { return null; } diff --git a/Content.Client/Popups/PopupSystem.cs b/Content.Client/Popups/PopupSystem.cs index d68272a107..1d4ca19ce2 100644 --- a/Content.Client/Popups/PopupSystem.cs +++ b/Content.Client/Popups/PopupSystem.cs @@ -9,6 +9,7 @@ using Robust.Client.UserInterface; using Robust.Shared.Configuration; using Robust.Shared.Map; using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Replays; using Robust.Shared.Timing; diff --git a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Movement.cs b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Movement.cs index d48a1eab46..3bb2afe122 100644 --- a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Movement.cs +++ b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Movement.cs @@ -2,7 +2,7 @@ using Content.Shared.Movement.Components; using Robust.Shared.Input; using Robust.Shared.Input.Binding; using Robust.Shared.Map; -using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Client.Replay.Spectator; diff --git a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Position.cs b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Position.cs index 479e2eff97..45a175e688 100644 --- a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Position.cs +++ b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Position.cs @@ -1,5 +1,5 @@ using Content.Shared.Movement.Components; -using Robust.Client.Player; +using Robust.Client.GameObjects; using Robust.Shared.Map; using Robust.Shared.Map.Components; using Robust.Shared.Network; @@ -79,7 +79,7 @@ public sealed partial class ReplaySpectatorSystem public void SetSpectatorPosition(SpectatorData data) { - if (_player.LocalSession == null) + if (_player.LocalPlayer == null) return; if (data.Controller != null @@ -87,13 +87,13 @@ public sealed partial class ReplaySpectatorSystem && Exists(session.AttachedEntity) && Transform(session.AttachedEntity.Value).MapID != MapId.Nullspace) { - _player.SetAttachedEntity(_player.LocalSession, session.AttachedEntity); + _player.LocalPlayer.AttachEntity(session.AttachedEntity.Value, EntityManager, _client); return; } if (Exists(data.Entity) && Transform(data.Entity).MapID != MapId.Nullspace) { - _player.SetAttachedEntity(_player.LocalSession, data.Entity); + _player.LocalPlayer.AttachEntity(data.Entity, EntityManager, _client); return; } @@ -118,7 +118,7 @@ public sealed partial class ReplaySpectatorSystem return; } - if (data.Eye != null && TryComp(_player.LocalSession.AttachedEntity, out InputMoverComponent? newMover)) + if (data.Eye != null && TryComp(_player.LocalPlayer.ControlledEntity, out InputMoverComponent? newMover)) { newMover.RelativeEntity = data.Eye.Value.Ent; newMover.TargetRelativeRotation = newMover.RelativeRotation = data.Eye.Value.Rot; @@ -177,7 +177,7 @@ public sealed partial class ReplaySpectatorSystem SetSpectatorPosition(default); } - private void OnDetached(EntityUid uid, ReplaySpectatorComponent component, LocalPlayerDetachedEvent args) + private void OnDetached(EntityUid uid, ReplaySpectatorComponent component, PlayerDetachedEvent args) { if (IsClientSide(uid)) QueueDel(uid); diff --git a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Spectate.cs b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Spectate.cs index 80a8429055..f3475c5479 100644 --- a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Spectate.cs +++ b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Spectate.cs @@ -32,10 +32,10 @@ public sealed partial class ReplaySpectatorSystem public void SpectateEntity(EntityUid target) { - if (_player.LocalSession == null) + if (_player.LocalPlayer == null) return; - var old = _player.LocalSession.AttachedEntity; + var old = _player.LocalPlayer.ControlledEntity; if (old == target) { @@ -44,7 +44,7 @@ public sealed partial class ReplaySpectatorSystem return; } - _player.SetAttachedEntity(_player.LocalSession, target); + _player.LocalPlayer.AttachEntity(target, EntityManager, _client); EnsureComp(target); _stateMan.RequestStateChange(); @@ -59,10 +59,10 @@ public sealed partial class ReplaySpectatorSystem public TransformComponent SpawnSpectatorGhost(EntityCoordinates coords, bool gridAttach) { - if (_player.LocalSession == null) + if (_player.LocalPlayer == null) throw new InvalidOperationException(); - var old = _player.LocalSession.AttachedEntity; + var old = _player.LocalPlayer.ControlledEntity; var ent = Spawn("ReplayObserver", coords); _eye.SetMaxZoom(ent, Vector2.One * 5); @@ -73,7 +73,7 @@ public sealed partial class ReplaySpectatorSystem if (gridAttach) _transform.AttachToGridOrMap(ent); - _player.SetAttachedEntity(_player.LocalSession, ent); + _player.LocalPlayer.AttachEntity(ent, EntityManager, _client); if (old != null) { @@ -93,7 +93,7 @@ public sealed partial class ReplaySpectatorSystem { if (args.Length == 0) { - if (_player.LocalSession?.AttachedEntity is { } current) + if (_player.LocalPlayer?.ControlledEntity is { } current) SpawnSpectatorGhost(new EntityCoordinates(current, default), true); else SpawnSpectatorGhost(default, true); diff --git a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.cs b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.cs index 3b9662ed8c..c75529c037 100644 --- a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.cs +++ b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.cs @@ -6,6 +6,7 @@ using Robust.Client.Player; using Robust.Client.Replays.Playback; using Robust.Client.State; using Robust.Shared.Console; +using Robust.Shared.Network; using Robust.Shared.Serialization.Markdown.Mapping; namespace Content.Client.Replay.Spectator; @@ -39,7 +40,7 @@ public sealed partial class ReplaySpectatorSystem : EntitySystem SubscribeLocalEvent>(OnGetAlternativeVerbs); SubscribeLocalEvent(OnTerminating); - SubscribeLocalEvent(OnDetached); + SubscribeLocalEvent(OnDetached); SubscribeLocalEvent(OnParentChanged); InitializeBlockers(); diff --git a/Content.Client/Sandbox/SandboxSystem.cs b/Content.Client/Sandbox/SandboxSystem.cs index d16751e371..7dcbfa0ee0 100644 --- a/Content.Client/Sandbox/SandboxSystem.cs +++ b/Content.Client/Sandbox/SandboxSystem.cs @@ -5,7 +5,7 @@ using Robust.Client.Console; using Robust.Client.Placement; using Robust.Client.Placement.Modes; using Robust.Shared.Map; -using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Client.Sandbox { diff --git a/Content.Client/Traits/ParacusiaSystem.cs b/Content.Client/Traits/ParacusiaSystem.cs index 87abec80bb..34c7d6859e 100644 --- a/Content.Client/Traits/ParacusiaSystem.cs +++ b/Content.Client/Traits/ParacusiaSystem.cs @@ -1,6 +1,8 @@ using System.Numerics; using Content.Shared.Traits.Assorted; +using Content.Client.Camera; using Robust.Shared.Random; +using Robust.Client.GameObjects; using Robust.Client.Player; using Robust.Shared.Timing; @@ -17,7 +19,7 @@ public sealed class ParacusiaSystem : SharedParacusiaSystem { base.Initialize(); SubscribeLocalEvent(OnComponentStartup); - SubscribeLocalEvent(OnPlayerDetach); + SubscribeLocalEvent(OnPlayerDetach); } public override void Update(float frameTime) @@ -38,7 +40,7 @@ public sealed class ParacusiaSystem : SharedParacusiaSystem component.NextIncidentTime = _timing.CurTime + TimeSpan.FromSeconds(_random.NextFloat(component.MinTimeBetweenIncidents, component.MaxTimeBetweenIncidents)); } - private void OnPlayerDetach(EntityUid uid, ParacusiaComponent component, LocalPlayerDetachedEvent args) + private void OnPlayerDetach(EntityUid uid, ParacusiaComponent component, PlayerDetachedEvent args) { component.Stream?.Stop(); } diff --git a/Content.Client/UserInterface/Systems/Character/CharacterUIController.cs b/Content.Client/UserInterface/Systems/Character/CharacterUIController.cs index 45bdada6e7..925b2dae4f 100644 --- a/Content.Client/UserInterface/Systems/Character/CharacterUIController.cs +++ b/Content.Client/UserInterface/Systems/Character/CharacterUIController.cs @@ -8,7 +8,6 @@ using Content.Client.UserInterface.Systems.Objectives.Controls; using Content.Shared.Input; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.Player; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controllers; using Robust.Client.UserInterface.Controls; @@ -22,7 +21,6 @@ namespace Content.Client.UserInterface.Systems.Character; [UsedImplicitly] public sealed class CharacterUIController : UIController, IOnStateEntered, IOnStateExited, IOnSystemChanged { - [Dependency] private readonly IPlayerManager _player = default!; [UISystemDependency] private readonly CharacterInfoSystem _characterInfo = default!; [UISystemDependency] private readonly SpriteSystem _sprite = default!; @@ -58,13 +56,13 @@ public sealed class CharacterUIController : UIController, IOnStateEntered(OnChatMessage); _net.RegisterNetMessage(OnDeleteChatMessagesBy); @@ -171,7 +170,7 @@ public sealed class ChatUIController : UIController _speechBubbleRoot = new LayoutContainer(); - UpdateChannelPermissions(); + OnLocalPlayerChanged(new LocalPlayerChangedEventArgs(null, _player.LocalPlayer)); _input.SetInputCommand(ContentKeyFunctions.FocusChat, InputCmdHandler.FromDelegate(_ => FocusChat())); @@ -364,7 +363,29 @@ public sealed class ChatUIController : UIController _speechBubbleRoot.SetPositionLast(); } - private void OnAttachedChanged(EntityUid uid) + private void OnLocalPlayerChanged(LocalPlayerChangedEventArgs obj) + { + if (obj.OldPlayer != null) + { + obj.OldPlayer.EntityAttached -= OnLocalPlayerEntityAttached; + obj.OldPlayer.EntityDetached -= OnLocalPlayerEntityDetached; + } + + if (obj.NewPlayer != null) + { + obj.NewPlayer.EntityAttached += OnLocalPlayerEntityAttached; + obj.NewPlayer.EntityDetached += OnLocalPlayerEntityDetached; + } + + UpdateChannelPermissions(); + } + + private void OnLocalPlayerEntityAttached(EntityAttachedEventArgs obj) + { + UpdateChannelPermissions(); + } + + private void OnLocalPlayerEntityDetached(EntityDetachedEventArgs obj) { UpdateChannelPermissions(); } diff --git a/Content.Client/UserInterface/Systems/DamageOverlays/DamageOverlayUiController.cs b/Content.Client/UserInterface/Systems/DamageOverlays/DamageOverlayUiController.cs index ba4a871199..0836314dbc 100644 --- a/Content.Client/UserInterface/Systems/DamageOverlays/DamageOverlayUiController.cs +++ b/Content.Client/UserInterface/Systems/DamageOverlays/DamageOverlayUiController.cs @@ -1,9 +1,11 @@ +using Content.Client.Alerts; using Content.Shared.Damage; using Content.Shared.FixedPoint; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; using JetBrains.Annotations; +using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.Player; using Robust.Client.UserInterface; @@ -23,13 +25,13 @@ public sealed class DamageOverlayUiController : UIController public override void Initialize() { _overlay = new Overlays.DamageOverlay(); - SubscribeLocalEvent(OnPlayerAttach); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttach); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(OnMobStateChanged); SubscribeLocalEvent(OnThresholdCheck); } - private void OnPlayerAttach(LocalPlayerAttachedEvent args) + private void OnPlayerAttach(PlayerAttachedEvent args) { ClearOverlay(); if (!EntityManager.TryGetComponent(args.Entity, out var mobState)) @@ -39,7 +41,7 @@ public sealed class DamageOverlayUiController : UIController _overlayManager.AddOverlay(_overlay); } - private void OnPlayerDetached(LocalPlayerDetachedEvent args) + private void OnPlayerDetached(PlayerDetachedEvent args) { _overlayManager.RemoveOverlay(_overlay); ClearOverlay(); diff --git a/Content.Client/UserInterface/Systems/Sandbox/SandboxUIController.cs b/Content.Client/UserInterface/Systems/Sandbox/SandboxUIController.cs index 778de82210..d7ec9f3497 100644 --- a/Content.Client/UserInterface/Systems/Sandbox/SandboxUIController.cs +++ b/Content.Client/UserInterface/Systems/Sandbox/SandboxUIController.cs @@ -17,7 +17,7 @@ using Robust.Client.UserInterface.Controllers; using Robust.Client.UserInterface.Controllers.Implementations; using Robust.Shared.Input.Binding; using Robust.Shared.Map; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Utility; using static Robust.Client.UserInterface.Controls.BaseButton; diff --git a/Content.Client/Weapons/Melee/MeleeWeaponSystem.cs b/Content.Client/Weapons/Melee/MeleeWeaponSystem.cs index 2d2883d8b7..397032cd15 100644 --- a/Content.Client/Weapons/Melee/MeleeWeaponSystem.cs +++ b/Content.Client/Weapons/Melee/MeleeWeaponSystem.cs @@ -16,8 +16,7 @@ using Robust.Client.State; using Robust.Shared.Input; using Robust.Shared.Map; using Robust.Shared.Player; -using Robust.Shared.Prototypes; -using Robust.Shared.Timing; +using Robust.Shared.Players; namespace Content.Client.Weapons.Melee; diff --git a/Content.IntegrationTests/Pair/TestPair.cs b/Content.IntegrationTests/Pair/TestPair.cs index 2672b4db56..2971573ff2 100644 --- a/Content.IntegrationTests/Pair/TestPair.cs +++ b/Content.IntegrationTests/Pair/TestPair.cs @@ -3,11 +3,13 @@ using System.Collections.Generic; using System.IO; using System.Linq; using Content.Server.GameTicking; +using Content.Server.Players; +using Content.Shared.Mind; using Content.Shared.Players; +using Robust.Server.Player; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Network; -using Robust.Shared.Player; using Robust.Shared.Timing; using Robust.UnitTesting; @@ -28,8 +30,8 @@ public sealed partial class TestPair public RobustIntegrationTest.ServerIntegrationInstance Server { get; private set; } = default!; public RobustIntegrationTest.ClientIntegrationInstance Client { get; private set; } = default!; - public ICommonSession? Player => Server.PlayerMan.Sessions.FirstOrDefault(); - public ContentPlayerData? PlayerData => Player?.Data.ContentData(); + public IPlayerSession? Player => (IPlayerSession?) Server.PlayerMan.Sessions.FirstOrDefault(); + public PlayerData? PlayerData => Player?.Data.ContentData(); public PoolTestLogHandler ServerLogHandler { get; private set; } = default!; public PoolTestLogHandler ClientLogHandler { get; private set; } = default!; diff --git a/Content.IntegrationTests/Tests/Actions/ActionsAddedTest.cs b/Content.IntegrationTests/Tests/Actions/ActionsAddedTest.cs index 01daeea93c..01f8bdd938 100644 --- a/Content.IntegrationTests/Tests/Actions/ActionsAddedTest.cs +++ b/Content.IntegrationTests/Tests/Actions/ActionsAddedTest.cs @@ -3,6 +3,8 @@ using Content.Shared.Actions; using Content.Shared.CombatMode; using Robust.Server.Player; using Robust.Shared.GameObjects; +using Robust.Shared.Players; +using PlayerManager = Robust.Client.Player.PlayerManager; namespace Content.IntegrationTests.Tests.Actions; @@ -24,7 +26,7 @@ public sealed class ActionsAddedTest var sEntMan = server.ResolveDependency(); var cEntMan = client.ResolveDependency(); var clientSession = client.ResolveDependency().LocalPlayer?.Session; - var serverSession = server.ResolveDependency().Sessions.Single(); + var serverSession = server.ResolveDependency().ServerSessions.Single(); var sActionSystem = server.System(); var cActionSystem = client.System(); diff --git a/Content.IntegrationTests/Tests/Administration/Logs/AddTests.cs b/Content.IntegrationTests/Tests/Administration/Logs/AddTests.cs index 98c7363a6c..6562a26b5e 100644 --- a/Content.IntegrationTests/Tests/Administration/Logs/AddTests.cs +++ b/Content.IntegrationTests/Tests/Administration/Logs/AddTests.cs @@ -7,6 +7,8 @@ using Content.Shared.Administration.Logs; using Content.Shared.Database; using Robust.Server.Player; using Robust.Shared.GameObjects; +using Robust.Shared.Map; +using Robust.Shared.Utility; namespace Content.IntegrationTests.Tests.Administration.Logs; @@ -175,7 +177,7 @@ public sealed class AddTests await server.WaitPost(() => { - var player = sPlayers.Sessions.First(); + var player = sPlayers.ServerSessions.First(); playerGuid = player.UserId; Assert.DoesNotThrow(() => @@ -278,7 +280,7 @@ public sealed class AddTests await server.WaitPost(() => { - var player = sPlayers.Sessions.Single(); + var player = sPlayers.ServerSessions.Single(); sAdminLogSystem.Add(LogType.Unknown, $"{player} {player} test log: {guid}"); }); @@ -316,7 +318,7 @@ public sealed class AddTests await server.WaitPost(() => { - var player = sPlayers.Sessions.Single(); + var player = sPlayers.ServerSessions.Single(); sAdminLogSystem.Add(LogType.Unknown, $"{player:first} {player:second} test log: {guid}"); }); diff --git a/Content.IntegrationTests/Tests/Administration/Logs/QueryTests.cs b/Content.IntegrationTests/Tests/Administration/Logs/QueryTests.cs index 5a58757d53..1155edfad2 100644 --- a/Content.IntegrationTests/Tests/Administration/Logs/QueryTests.cs +++ b/Content.IntegrationTests/Tests/Administration/Logs/QueryTests.cs @@ -5,7 +5,6 @@ using Content.Server.GameTicking; using Content.Shared.Database; using Robust.Server.Player; using Robust.Shared.GameObjects; -using Robust.Shared.Player; namespace Content.IntegrationTests.Tests.Administration.Logs; @@ -28,11 +27,11 @@ public sealed class QueryTests var date = DateTime.UtcNow; var guid = Guid.NewGuid(); - ICommonSession player = default; + IPlayerSession player = default; await server.WaitPost(() => { - player = sPlayers.Sessions.First(); + player = sPlayers.ServerSessions.First(); sAdminLogSystem.Add(LogType.Unknown, $"{player.AttachedEntity:Entity} test log: {guid}"); }); diff --git a/Content.IntegrationTests/Tests/Cleanup/EuiManagerTest.cs b/Content.IntegrationTests/Tests/Cleanup/EuiManagerTest.cs index e2bff03501..9aac4e2892 100644 --- a/Content.IntegrationTests/Tests/Cleanup/EuiManagerTest.cs +++ b/Content.IntegrationTests/Tests/Cleanup/EuiManagerTest.cs @@ -25,7 +25,7 @@ public sealed class EuiManagerTest await server.WaitAssertion(() => { - var clientSession = sPlayerManager.Sessions.Single(); + var clientSession = sPlayerManager.ServerSessions.Single(); var ui = new AdminAnnounceEui(); eui.OpenEui(ui, clientSession); }); diff --git a/Content.IntegrationTests/Tests/Interaction/InteractionTest.cs b/Content.IntegrationTests/Tests/Interaction/InteractionTest.cs index df77410e54..b4b6c2239f 100644 --- a/Content.IntegrationTests/Tests/Interaction/InteractionTest.cs +++ b/Content.IntegrationTests/Tests/Interaction/InteractionTest.cs @@ -14,7 +14,6 @@ using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction; using Content.Shared.Mind; -using Content.Shared.Players; using Robust.Client.Input; using Robust.Client.UserInterface; using Robust.Server.GameObjects; @@ -22,7 +21,7 @@ using Robust.Server.Player; using Robust.Shared.GameObjects; using Robust.Shared.Log; using Robust.Shared.Map; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Timing; using Robust.UnitTesting; @@ -68,7 +67,7 @@ public abstract partial class InteractionTest protected NetEntity Player; protected ICommonSession ClientSession = default!; - protected ICommonSession ServerSession = default!; + protected IPlayerSession ServerSession = default!; public EntityUid? ClientTarget; diff --git a/Content.IntegrationTests/Tests/Minds/GhostRoleTests.cs b/Content.IntegrationTests/Tests/Minds/GhostRoleTests.cs index 22a185798e..28e49645c9 100644 --- a/Content.IntegrationTests/Tests/Minds/GhostRoleTests.cs +++ b/Content.IntegrationTests/Tests/Minds/GhostRoleTests.cs @@ -5,7 +5,6 @@ using Content.Server.Ghost.Roles.Components; using Content.Server.Players; using Content.Shared.Ghost; using Content.Shared.Mind; -using Content.Shared.Players; using Robust.Shared.Console; using Robust.Shared.GameObjects; using Robust.Shared.Map; @@ -44,7 +43,7 @@ public sealed class GhostRoleTests var sPlayerMan = server.ResolveDependency(); var conHost = client.ResolveDependency(); var mindSystem = entMan.System(); - var session = sPlayerMan.Sessions.Single(); + var session = sPlayerMan.ServerSessions.Single(); var originalMindId = session.ContentData()!.Mind!.Value; // Spawn player entity & attach diff --git a/Content.IntegrationTests/Tests/Minds/MindTests.EntityDeletion.cs b/Content.IntegrationTests/Tests/Minds/MindTests.EntityDeletion.cs index a67a45ecb4..9fc68ef93d 100644 --- a/Content.IntegrationTests/Tests/Minds/MindTests.EntityDeletion.cs +++ b/Content.IntegrationTests/Tests/Minds/MindTests.EntityDeletion.cs @@ -2,7 +2,6 @@ using System.Linq; using Content.Server.Players; using Content.Shared.Ghost; using Content.Shared.Mind; -using Content.Shared.Players; using Robust.Server.Console; using Robust.Server.GameObjects; using Robust.Server.Player; @@ -36,7 +35,7 @@ public sealed partial class MindTests MindComponent mind = default!; await server.WaitAssertion(() => { - var player = playerMan.Sessions.Single(); + var player = playerMan.ServerSessions.Single(); playerEnt = entMan.SpawnEntity(null, MapCoordinates.Nullspace); visitEnt = entMan.SpawnEntity(null, MapCoordinates.Nullspace); @@ -82,7 +81,7 @@ public sealed partial class MindTests var entMan = server.ResolveDependency(); var mapManager = server.ResolveDependency(); var playerMan = server.ResolveDependency(); - var player = playerMan.Sessions.Single(); + var player = playerMan.ServerSessions.Single(); var mindSystem = entMan.EntitySysManager.GetEntitySystem(); @@ -129,7 +128,7 @@ public sealed partial class MindTests var entMan = server.ResolveDependency(); var playerMan = server.ResolveDependency(); - var player = playerMan.Sessions.Single(); + var player = playerMan.ServerSessions.Single(); Assert.That(!entMan.HasComponent(player.AttachedEntity), "Player was initially a ghost?"); @@ -163,7 +162,7 @@ public sealed partial class MindTests var mindSystem = entMan.EntitySysManager.GetEntitySystem(); var mind = GetMind(pair); - var player = playerMan.Sessions.Single(); + var player = playerMan.ServerSessions.Single(); #pragma warning disable NUnit2045 // Interdependent assertions. Assert.That(player.AttachedEntity, Is.Not.Null); Assert.That(entMan.EntityExists(player.AttachedEntity)); @@ -219,7 +218,7 @@ public sealed partial class MindTests var playerMan = server.ResolveDependency(); var serverConsole = server.ResolveDependency(); - var player = playerMan.Sessions.Single(); + var player = playerMan.ServerSessions.Single(); var ghost = await BecomeGhost(pair); @@ -264,7 +263,7 @@ public sealed partial class MindTests var playerMan = server.ResolveDependency(); var serverConsole = server.ResolveDependency(); - var player = playerMan.Sessions.Single(); + var player = playerMan.ServerSessions.Single(); EntityUid ghost = default!; diff --git a/Content.IntegrationTests/Tests/Minds/MindTests.Helpers.cs b/Content.IntegrationTests/Tests/Minds/MindTests.Helpers.cs index bbc011acac..f71a6ad5f9 100644 --- a/Content.IntegrationTests/Tests/Minds/MindTests.Helpers.cs +++ b/Content.IntegrationTests/Tests/Minds/MindTests.Helpers.cs @@ -3,14 +3,12 @@ using Content.IntegrationTests.Pair; using Content.Server.Players; using Content.Shared.Ghost; using Content.Shared.Mind; -using Content.Shared.Players; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Enums; using Robust.Shared.GameObjects; using Robust.Shared.Map; using Robust.Shared.Network; -using Robust.Shared.Player; namespace Content.IntegrationTests.Tests.Minds; @@ -38,7 +36,7 @@ public sealed partial class MindTests var playerMan = pair.Server.ResolveDependency(); var mindSys = entMan.System(); - var player = playerMan.Sessions.Single(); + var player = playerMan.ServerSessions.Single(); EntityUid entity = default; EntityUid mindId = default!; @@ -73,7 +71,7 @@ public sealed partial class MindTests EntityUid mindId = default!; MindComponent mind = default!; - var player = playerMan.Sessions.Single(); + var player = playerMan.ServerSessions.Single(); await pair.Server.WaitAssertion(() => { var oldUid = player.AttachedEntity; @@ -120,7 +118,7 @@ public sealed partial class MindTests { var playerMan = pair.Server.ResolveDependency(); var entMan = pair.Server.ResolveDependency(); - var player = playerMan.Sessions.SingleOrDefault(); + var player = playerMan.ServerSessions.SingleOrDefault(); Assert.That(player, Is.Not.Null); var mindId = player.ContentData()!.Mind!.Value; @@ -141,7 +139,7 @@ public sealed partial class MindTests var netManager = pair.Client.ResolveDependency(); var playerMan = pair.Server.ResolveDependency(); var entMan = pair.Server.ResolveDependency(); - var player = playerMan.Sessions.Single(); + var player = playerMan.ServerSessions.Single(); var mindId = player.ContentData()!.Mind!.Value; var mind = entMan.GetComponent(mindId); @@ -163,21 +161,21 @@ public sealed partial class MindTests { var netManager = pair.Client.ResolveDependency(); var playerMan = pair.Server.ResolveDependency(); - Assert.That(!playerMan.Sessions.Any()); + Assert.That(!playerMan.ServerSessions.Any()); await Task.WhenAll(pair.Client.WaitIdleAsync(), pair.Client.WaitIdleAsync()); pair.Client.SetConnectTarget(pair.Server); await pair.Client.WaitPost(() => netManager.ClientConnect(null!, 0, username)); await pair.RunTicksSync(5); - var player = playerMan.Sessions.Single(); + var player = playerMan.ServerSessions.Single(); Assert.That(player.Status, Is.EqualTo(SessionStatus.InGame)); } - private static async Task DisconnectReconnect(Pair.TestPair pair) + private static async Task DisconnectReconnect(Pair.TestPair pair) { var playerMan = pair.Server.ResolveDependency(); - var player = playerMan.Sessions.Single(); + var player = playerMan.ServerSessions.Single(); var name = player.Name; var id = player.UserId; @@ -185,7 +183,7 @@ public sealed partial class MindTests await Connect(pair, name); // Session has changed - var newSession = playerMan.Sessions.Single(); + var newSession = playerMan.ServerSessions.Single(); Assert.Multiple(() => { Assert.That(newSession, Is.Not.EqualTo(player)); diff --git a/Content.IntegrationTests/Tests/Minds/MindTests.ReconnectTests.cs b/Content.IntegrationTests/Tests/Minds/MindTests.ReconnectTests.cs index 9939ebc545..ea2110c03a 100644 --- a/Content.IntegrationTests/Tests/Minds/MindTests.ReconnectTests.cs +++ b/Content.IntegrationTests/Tests/Minds/MindTests.ReconnectTests.cs @@ -49,7 +49,7 @@ public sealed partial class MindTests var mind = GetMind(pair); var playerMan = pair.Server.ResolveDependency(); - var player = playerMan.Sessions.Single(); + var player = playerMan.ServerSessions.Single(); var name = player.Name; var user = player.UserId; Assert.That(mind.Comp.OwnedEntity, Is.Not.Null); @@ -72,7 +72,7 @@ public sealed partial class MindTests // Reconnect await Connect(pair, name); - player = playerMan.Sessions.Single(); + player = playerMan.ServerSessions.Single(); Assert.Multiple(() => { Assert.That(user, Is.EqualTo(player.UserId)); @@ -127,10 +127,8 @@ public sealed partial class MindTests var mindSys = entMan.System(); var mind = GetMind(pair); - Assert.Null(mind.Comp.VisitingEntity); - // Make player visit a new mob - var original = mind.Comp.OwnedEntity; + var original = mind.Comp.CurrentEntity; EntityUid visiting = default; await pair.Server.WaitAssertion(() => { @@ -139,7 +137,6 @@ public sealed partial class MindTests }); await pair.RunTicksSync(5); - Assert.That(mind.Comp.VisitingEntity, Is.EqualTo(visiting)); await DisconnectReconnect(pair); // Player is back in control of the visited mob, mind was preserved diff --git a/Content.IntegrationTests/Tests/Minds/MindTests.cs b/Content.IntegrationTests/Tests/Minds/MindTests.cs index c9788b80a6..fb2fef43ed 100644 --- a/Content.IntegrationTests/Tests/Minds/MindTests.cs +++ b/Content.IntegrationTests/Tests/Minds/MindTests.cs @@ -11,7 +11,6 @@ using Content.Shared.Damage.Prototypes; using Content.Shared.FixedPoint; using Content.Shared.Mind; using Content.Shared.Mind.Components; -using Content.Shared.Players; using Content.Shared.Roles; using Content.Shared.Roles.Jobs; using Robust.Server.Console; @@ -68,12 +67,13 @@ public sealed partial class MindTests var entity = entMan.SpawnEntity(null, new MapCoordinates()); var mindComp = entMan.EnsureComponent(entity); - var mind = mindSystem.CreateMind(null); + var mindId = mindSystem.CreateMind(null); + var mind = entMan.GetComponent(mindId); - Assert.That(mind.Comp.UserId, Is.EqualTo(null)); + Assert.That(mind.UserId, Is.EqualTo(null)); - mindSystem.TransferTo(mind, entity, mind: mind); - Assert.That(mindSystem.GetMind(entity, mindComp), Is.EqualTo(mind.Owner)); + mindSystem.TransferTo(mindId, entity, mind: mind); + Assert.That(mindSystem.GetMind(entity, mindComp), Is.EqualTo(mindId)); }); await pair.CleanReturnAsync(); @@ -94,11 +94,11 @@ public sealed partial class MindTests var entity = entMan.SpawnEntity(null, new MapCoordinates()); var mindComp = entMan.EnsureComponent(entity); - var mindId = mindSystem.CreateMind(null).Owner; + var mindId = mindSystem.CreateMind(null); mindSystem.TransferTo(mindId, entity); Assert.That(mindSystem.GetMind(entity, mindComp), Is.EqualTo(mindId)); - var mind2 = mindSystem.CreateMind(null).Owner; + var mind2 = mindSystem.CreateMind(null); mindSystem.TransferTo(mind2, entity); Assert.Multiple(() => { @@ -184,7 +184,7 @@ public sealed partial class MindTests var mindComp = entMan.EnsureComponent(entity); entMan.EnsureComponent(targetEntity); - var mind = mindSystem.CreateMind(null).Owner; + var mind = mindSystem.CreateMind(null); mindSystem.TransferTo(mind, entity); @@ -276,7 +276,7 @@ public sealed partial class MindTests var entity = entMan.SpawnEntity(null, new MapCoordinates()); var mindComp = entMan.EnsureComponent(entity); - var mindId = mindSystem.CreateMind(null).Owner; + var mindId = mindSystem.CreateMind(null); var mind = entMan.EnsureComponent(mindId); Assert.That(mind.UserId, Is.EqualTo(null)); @@ -334,7 +334,7 @@ public sealed partial class MindTests public async Task TestPlayerCanGhost() { // Client is needed to spawn session - await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true, DummyTicker = false }); + await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true }); var server = pair.Server; var entMan = server.ResolveDependency(); @@ -346,7 +346,7 @@ public sealed partial class MindTests EntityUid entity = default!; EntityUid mindId = default!; MindComponent mind = default!; - var player = playerMan.Sessions.Single(); + var player = playerMan.ServerSessions.Single(); await server.WaitAssertion(() => { @@ -407,6 +407,12 @@ public sealed partial class MindTests await pair.CleanReturnAsync(); } + // TODO Implement + /*[Test] + public async Task TestPlayerCanReturnFromGhostWhenDead() + { + }*/ + [Test] public async Task TestGhostDoesNotInfiniteLoop() { @@ -427,7 +433,7 @@ public sealed partial class MindTests EntityUid ghost = default!; EntityUid mindId = default!; MindComponent mind = default!; - var player = playerMan.Sessions.Single(); + var player = playerMan.ServerSessions.Single(); await server.WaitAssertion(() => { diff --git a/Content.IntegrationTests/Tests/Toolshed/ToolshedTest.cs b/Content.IntegrationTests/Tests/Toolshed/ToolshedTest.cs index d6aec781a9..ca7eeac199 100644 --- a/Content.IntegrationTests/Tests/Toolshed/ToolshedTest.cs +++ b/Content.IntegrationTests/Tests/Toolshed/ToolshedTest.cs @@ -2,7 +2,8 @@ using System.Collections.Generic; using Content.IntegrationTests.Pair; using Content.Server.Administration.Managers; -using Robust.Shared.Player; +using Robust.Server.Player; +using Robust.Shared.Players; using Robust.Shared.Toolshed; using Robust.Shared.Toolshed.Errors; using Robust.Shared.Toolshed.Syntax; @@ -59,7 +60,7 @@ public abstract class ToolshedTest : IInvocationContext AdminManager = Server.ResolveDependency(); } - protected bool InvokeCommand(string command, out object? result, ICommonSession? session = null) + protected bool InvokeCommand(string command, out object? result, IPlayerSession? session = null) { return Toolshed.InvokeCommand(this, command, null, out result); } @@ -94,7 +95,7 @@ public abstract class ToolshedTest : IInvocationContext return true; } - protected ICommonSession? InvocationSession { get; set; } + protected IPlayerSession? InvocationSession { get; set; } public ICommonSession? Session { diff --git a/Content.MapRenderer/Painters/MapPainter.cs b/Content.MapRenderer/Painters/MapPainter.cs index 8f3dd59baf..b799db78a5 100644 --- a/Content.MapRenderer/Painters/MapPainter.cs +++ b/Content.MapRenderer/Painters/MapPainter.cs @@ -68,7 +68,7 @@ namespace Content.MapRenderer.Painters await server.WaitPost(() => { - var playerEntity = sPlayerManager.Sessions.Single().AttachedEntity; + var playerEntity = sPlayerManager.ServerSessions.Single().AttachedEntity; if (playerEntity.HasValue) { diff --git a/Content.Server/Administration/AdminPermsChangedEventArgs.cs b/Content.Server/Administration/AdminPermsChangedEventArgs.cs index 07eb416be6..24ca7aca68 100644 --- a/Content.Server/Administration/AdminPermsChangedEventArgs.cs +++ b/Content.Server/Administration/AdminPermsChangedEventArgs.cs @@ -1,5 +1,5 @@ using Content.Shared.Administration; -using Robust.Shared.Player; +using Robust.Server.Player; namespace Content.Server.Administration { @@ -8,7 +8,7 @@ namespace Content.Server.Administration /// public sealed class AdminPermsChangedEventArgs : EventArgs { - public AdminPermsChangedEventArgs(ICommonSession player, AdminFlags? flags) + public AdminPermsChangedEventArgs(IPlayerSession player, AdminFlags? flags) { Player = player; Flags = flags; @@ -17,7 +17,7 @@ namespace Content.Server.Administration /// /// The player that had their admin permissions changed. /// - public ICommonSession Player { get; } + public IPlayerSession Player { get; } /// /// The admin flags of the player. Null if the player is no longer an admin. diff --git a/Content.Server/Administration/Commands/AGhost.cs b/Content.Server/Administration/Commands/AGhost.cs index 2d1a15a0be..42a8600ff1 100644 --- a/Content.Server/Administration/Commands/AGhost.cs +++ b/Content.Server/Administration/Commands/AGhost.cs @@ -2,6 +2,7 @@ using Content.Shared.Administration; using Content.Shared.Ghost; using Content.Shared.Mind; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands @@ -17,7 +18,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player == null) { shell.WriteLine("Nah"); diff --git a/Content.Server/Administration/Commands/AdminWhoCommand.cs b/Content.Server/Administration/Commands/AdminWhoCommand.cs index 9765e8385f..8e6c402c4e 100644 --- a/Content.Server/Administration/Commands/AdminWhoCommand.cs +++ b/Content.Server/Administration/Commands/AdminWhoCommand.cs @@ -2,6 +2,7 @@ using Content.Server.Administration.Managers; using Content.Server.Afk; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Utility; @@ -34,7 +35,7 @@ public sealed class AdminWhoCommand : IConsoleCommand if (adminData.Title is { } title) sb.Append($": [{title}]"); - if (shell.Player is { } player && adminMgr.HasAdminFlag(player, AdminFlags.Admin)) + if (shell.Player is IPlayerSession player && adminMgr.HasAdminFlag(player, AdminFlags.Admin)) { if (afk.IsAfk(admin)) sb.Append(" [AFK]"); diff --git a/Content.Server/Administration/Commands/AnnounceUiCommand.cs b/Content.Server/Administration/Commands/AnnounceUiCommand.cs index d80db96686..c4cd7f13e4 100644 --- a/Content.Server/Administration/Commands/AnnounceUiCommand.cs +++ b/Content.Server/Administration/Commands/AnnounceUiCommand.cs @@ -1,6 +1,7 @@ using Content.Server.Administration.UI; using Content.Server.EUI; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands @@ -16,7 +17,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player == null) { shell.WriteLine("This does not work from the server console."); diff --git a/Content.Server/Administration/Commands/BanCommand.cs b/Content.Server/Administration/Commands/BanCommand.cs index 156fdf496a..58a801e410 100644 --- a/Content.Server/Administration/Commands/BanCommand.cs +++ b/Content.Server/Administration/Commands/BanCommand.cs @@ -1,8 +1,15 @@ using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Text; using Content.Server.Administration.Managers; +using Content.Server.Administration.Notes; +using Content.Server.Database; +using Content.Server.GameTicking; using Content.Shared.Administration; using Content.Shared.CCVar; using Content.Shared.Database; +using Content.Shared.Players.PlayTimeTracking; using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Console; @@ -77,7 +84,7 @@ public sealed class BanCommand : LocalizedCommands } var located = await _locator.LookupIdByNameOrIdAsync(target); - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (located == null) { @@ -95,7 +102,7 @@ public sealed class BanCommand : LocalizedCommands { if (args.Length == 1) { - var options = _playerManager.Sessions.Select(c => c.Name).OrderBy(c => c).ToArray(); + var options = _playerManager.ServerSessions.Select(c => c.Name).OrderBy(c => c).ToArray(); return CompletionResult.FromHintOptions(options, LocalizationManager.GetString("cmd-ban-hint")); } diff --git a/Content.Server/Administration/Commands/BanListCommand.cs b/Content.Server/Administration/Commands/BanListCommand.cs index a5bc97dce3..1c2be52394 100644 --- a/Content.Server/Administration/Commands/BanListCommand.cs +++ b/Content.Server/Administration/Commands/BanListCommand.cs @@ -36,7 +36,7 @@ public sealed class BanListCommand : LocalizedCommands return; } - if (shell.Player is not { } player) + if (shell.Player is not IPlayerSession player) { var bans = await _dbManager.GetServerBansAsync(data.LastAddress, data.UserId, data.LastHWId, false); @@ -67,7 +67,7 @@ public sealed class BanListCommand : LocalizedCommands return CompletionResult.Empty; var playerMgr = IoCManager.Resolve(); - var options = playerMgr.Sessions.Select(c => c.Name).OrderBy(c => c).ToArray(); + var options = playerMgr.ServerSessions.Select(c => c.Name).OrderBy(c => c).ToArray(); return CompletionResult.FromHintOptions(options, Loc.GetString("cmd-banlist-hint")); } } diff --git a/Content.Server/Administration/Commands/BanPanelCommand.cs b/Content.Server/Administration/Commands/BanPanelCommand.cs index 9f9ec9e89f..6036e5aa6e 100644 --- a/Content.Server/Administration/Commands/BanPanelCommand.cs +++ b/Content.Server/Administration/Commands/BanPanelCommand.cs @@ -1,6 +1,12 @@ using Content.Shared.Administration; using Robust.Shared.Console; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; using Content.Server.EUI; +using Robust.Server.Player; namespace Content.Server.Administration.Commands; @@ -15,7 +21,7 @@ public sealed class BanPanelCommand : LocalizedCommands public override async void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not { } player) + if (shell.Player is not IPlayerSession player) { shell.WriteError(Loc.GetString("cmd-banpanel-server")); return; diff --git a/Content.Server/Administration/Commands/ControlMob.cs b/Content.Server/Administration/Commands/ControlMob.cs index 317461a373..2d205e44d3 100644 --- a/Content.Server/Administration/Commands/ControlMob.cs +++ b/Content.Server/Administration/Commands/ControlMob.cs @@ -1,5 +1,6 @@ -using Content.Server.Mind; using Content.Shared.Administration; +using Content.Shared.Mind; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands @@ -15,7 +16,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not { } player) + if (shell.Player is not IPlayerSession player) { shell.WriteLine("shell-server-cannot"); return; @@ -41,7 +42,14 @@ namespace Content.Server.Administration.Commands return; } - _entities.System().ControlMob(player.UserId, target); + var mindSystem = _entities.System(); + if (!mindSystem.TryGetMind(target, out var mindId, out var mind)) + { + shell.WriteLine(Loc.GetString("shell-entity-is-not-mob")); + return; + } + + mindSystem.TransferTo(mindId, target, mind: mind); } } } diff --git a/Content.Server/Administration/Commands/DSay.cs b/Content.Server/Administration/Commands/DSay.cs index 61b47d7856..79b0e8db7d 100644 --- a/Content.Server/Administration/Commands/DSay.cs +++ b/Content.Server/Administration/Commands/DSay.cs @@ -1,5 +1,7 @@ +using Content.Server.Chat; using Content.Server.Chat.Systems; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands @@ -15,7 +17,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player == null) { shell.WriteLine("shell-only-players-can-run-this-command"); diff --git a/Content.Server/Administration/Commands/DeAdminCommand.cs b/Content.Server/Administration/Commands/DeAdminCommand.cs index cf65941200..c2bbfa7a33 100644 --- a/Content.Server/Administration/Commands/DeAdminCommand.cs +++ b/Content.Server/Administration/Commands/DeAdminCommand.cs @@ -1,8 +1,10 @@ using Content.Server.Administration.Managers; using Content.Shared.Administration; using JetBrains.Annotations; +using Robust.Server.Player; using Robust.Shared.Console; + namespace Content.Server.Administration.Commands { [UsedImplicitly] @@ -15,7 +17,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player == null) { shell.WriteLine("You cannot use this command from the server console."); diff --git a/Content.Server/Administration/Commands/ExplosionCommand.cs b/Content.Server/Administration/Commands/ExplosionCommand.cs index 56ed78b2e2..d48b69a5ad 100644 --- a/Content.Server/Administration/Commands/ExplosionCommand.cs +++ b/Content.Server/Administration/Commands/ExplosionCommand.cs @@ -3,6 +3,7 @@ using Content.Server.EUI; using Content.Server.Explosion.EntitySystems; using Content.Shared.Administration; using Content.Shared.Explosion; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; using Robust.Shared.Prototypes; @@ -20,7 +21,7 @@ public sealed class OpenExplosionEui : IConsoleCommand public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player == null) { shell.WriteError("This does not work from the server console."); diff --git a/Content.Server/Administration/Commands/FaxUiCommand.cs b/Content.Server/Administration/Commands/FaxUiCommand.cs index cf9e97e399..b06d36d08b 100644 --- a/Content.Server/Administration/Commands/FaxUiCommand.cs +++ b/Content.Server/Administration/Commands/FaxUiCommand.cs @@ -1,6 +1,7 @@ using Content.Server.EUI; using Content.Server.Fax.AdminUI; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands; @@ -15,7 +16,7 @@ public sealed class FaxUiCommand : IConsoleCommand public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player == null) { shell.WriteLine("shell-only-players-can-run-this-command"); diff --git a/Content.Server/Administration/Commands/OpenAdminLogsCommand.cs b/Content.Server/Administration/Commands/OpenAdminLogsCommand.cs index 47ff3e1a1c..9f28dc907c 100644 --- a/Content.Server/Administration/Commands/OpenAdminLogsCommand.cs +++ b/Content.Server/Administration/Commands/OpenAdminLogsCommand.cs @@ -1,6 +1,7 @@ using Content.Server.Administration.Logs; using Content.Server.EUI; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands; @@ -14,7 +15,7 @@ public sealed class OpenAdminLogsCommand : IConsoleCommand public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not { } player) + if (shell.Player is not IPlayerSession player) { shell.WriteLine("This does not work from the server console."); return; diff --git a/Content.Server/Administration/Commands/OpenAdminNotesCommand.cs b/Content.Server/Administration/Commands/OpenAdminNotesCommand.cs index e6ae4f7616..147c0d6a82 100644 --- a/Content.Server/Administration/Commands/OpenAdminNotesCommand.cs +++ b/Content.Server/Administration/Commands/OpenAdminNotesCommand.cs @@ -1,5 +1,7 @@ using Content.Server.Administration.Notes; +using Content.Server.Database; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands; @@ -15,7 +17,7 @@ public sealed class OpenAdminNotesCommand : IConsoleCommand public async void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not { } player) + if (shell.Player is not IPlayerSession player) { shell.WriteError("This does not work from the server console."); return; diff --git a/Content.Server/Administration/Commands/OpenPermissionsCommand.cs b/Content.Server/Administration/Commands/OpenPermissionsCommand.cs index fd3227d4aa..78d56cb4fb 100644 --- a/Content.Server/Administration/Commands/OpenPermissionsCommand.cs +++ b/Content.Server/Administration/Commands/OpenPermissionsCommand.cs @@ -1,8 +1,10 @@ using Content.Server.Administration.UI; using Content.Server.EUI; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; + namespace Content.Server.Administration.Commands { [AdminCommand(AdminFlags.Permissions)] @@ -14,7 +16,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player == null) { shell.WriteLine("This does not work from the server console."); diff --git a/Content.Server/Administration/Commands/OpenUserVisibleNotesCommand.cs b/Content.Server/Administration/Commands/OpenUserVisibleNotesCommand.cs index 507c7ab279..d61114fcae 100644 --- a/Content.Server/Administration/Commands/OpenUserVisibleNotesCommand.cs +++ b/Content.Server/Administration/Commands/OpenUserVisibleNotesCommand.cs @@ -1,6 +1,7 @@ using Content.Server.Administration.Notes; using Content.Shared.Administration; using Content.Shared.CCVar; +using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Console; @@ -26,7 +27,7 @@ public sealed class OpenUserVisibleNotesCommand : IConsoleCommand return; } - if (shell.Player is not { } player) + if (shell.Player is not IPlayerSession player) { shell.WriteError("This does not work from the server console."); return; diff --git a/Content.Server/Administration/Commands/PardonCommand.cs b/Content.Server/Administration/Commands/PardonCommand.cs index 9cbaaece31..869024eb7c 100644 --- a/Content.Server/Administration/Commands/PardonCommand.cs +++ b/Content.Server/Administration/Commands/PardonCommand.cs @@ -1,6 +1,7 @@ using System.Text; using Content.Server.Database; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands @@ -14,7 +15,7 @@ namespace Content.Server.Administration.Commands public async void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; var dbMan = IoCManager.Resolve(); if (args.Length != 1) diff --git a/Content.Server/Administration/Commands/PlayGlobalSoundCommand.cs b/Content.Server/Administration/Commands/PlayGlobalSoundCommand.cs index fdf067181d..ec5b21dcee 100644 --- a/Content.Server/Administration/Commands/PlayGlobalSoundCommand.cs +++ b/Content.Server/Administration/Commands/PlayGlobalSoundCommand.cs @@ -6,6 +6,7 @@ using Robust.Shared.Audio; using Robust.Shared.Console; using Robust.Shared.ContentPack; using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Prototypes; namespace Content.Server.Administration.Commands; diff --git a/Content.Server/Administration/Commands/ReAdminCommand.cs b/Content.Server/Administration/Commands/ReAdminCommand.cs index a3f5993766..12ff13221a 100644 --- a/Content.Server/Administration/Commands/ReAdminCommand.cs +++ b/Content.Server/Administration/Commands/ReAdminCommand.cs @@ -1,7 +1,9 @@ using Content.Server.Administration.Managers; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; + namespace Content.Server.Administration.Commands { [AnyCommand] @@ -13,7 +15,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player == null) { shell.WriteLine("You cannot use this command from the server console."); diff --git a/Content.Server/Administration/Commands/SetAdminOOC.cs b/Content.Server/Administration/Commands/SetAdminOOC.cs index 27528e1940..bb11b938d8 100644 --- a/Content.Server/Administration/Commands/SetAdminOOC.cs +++ b/Content.Server/Administration/Commands/SetAdminOOC.cs @@ -1,6 +1,8 @@ + using Content.Server.Database; using Content.Server.Preferences.Managers; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands @@ -14,7 +16,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player == null) + if (!(shell.Player is IPlayerSession)) { shell.WriteError(Loc.GetString("shell-only-players-can-run-this-command")); return; diff --git a/Content.Server/Administration/Commands/SetMindCommand.cs b/Content.Server/Administration/Commands/SetMindCommand.cs index 5310c2dd7f..b9ff329ed2 100644 --- a/Content.Server/Administration/Commands/SetMindCommand.cs +++ b/Content.Server/Administration/Commands/SetMindCommand.cs @@ -2,7 +2,6 @@ using Content.Server.Players; using Content.Shared.Administration; using Content.Shared.Mind; using Content.Shared.Mind.Components; -using Content.Shared.Players; using Robust.Server.Player; using Robust.Shared.Console; diff --git a/Content.Server/Administration/Commands/SetOutfitCommand.cs b/Content.Server/Administration/Commands/SetOutfitCommand.cs index b2e7f4e6cc..28172ee6c5 100644 --- a/Content.Server/Administration/Commands/SetOutfitCommand.cs +++ b/Content.Server/Administration/Commands/SetOutfitCommand.cs @@ -10,6 +10,7 @@ using Content.Shared.PDA; using Content.Shared.Preferences; using Content.Shared.Roles; using Robust.Server.GameObjects; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Prototypes; @@ -56,7 +57,7 @@ namespace Content.Server.Administration.Commands if (args.Length == 1) { - if (shell.Player is not { } player) + if (shell.Player is not IPlayerSession player) { shell.WriteError(Loc.GetString("set-outfit-command-is-not-player-error")); return; diff --git a/Content.Server/Administration/Commands/WarpCommand.cs b/Content.Server/Administration/Commands/WarpCommand.cs index 0d6da0d993..30a6d127aa 100644 --- a/Content.Server/Administration/Commands/WarpCommand.cs +++ b/Content.Server/Administration/Commands/WarpCommand.cs @@ -4,9 +4,11 @@ using Content.Server.Warps; using Content.Shared.Administration; using Content.Shared.Follower; using Content.Shared.Ghost; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; using Robust.Shared.Map; +using Robust.Shared.Physics; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; @@ -26,7 +28,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player == null) { shell.WriteLine("Only players can use this command"); diff --git a/Content.Server/Administration/ContentNetworkResourceManager.cs b/Content.Server/Administration/ContentNetworkResourceManager.cs index dd95a2d897..0d3f3291e6 100644 --- a/Content.Server/Administration/ContentNetworkResourceManager.cs +++ b/Content.Server/Administration/ContentNetworkResourceManager.cs @@ -1,8 +1,8 @@ using Content.Server.Database; using Content.Shared.CCVar; +using Robust.Server.Player; using Robust.Server.Upload; using Robust.Shared.Configuration; -using Robust.Shared.Player; using Robust.Shared.Upload; namespace Content.Server.Administration; @@ -22,7 +22,7 @@ public sealed class ContentNetworkResourceManager _netRes.OnResourceUploaded += OnUploadResource; } - private async void OnUploadResource(ICommonSession session, NetworkResourceUploadMessage msg) + private async void OnUploadResource(IPlayerSession session, NetworkResourceUploadMessage msg) { if (StoreUploaded) await _serverDb.AddUploadedResourceLogAsync(session.UserId, DateTime.Now, msg.RelativePath.ToString(), msg.Data); diff --git a/Content.Server/Administration/Logs/AdminLogManager.Json.cs b/Content.Server/Administration/Logs/AdminLogManager.Json.cs index 0a67d61cef..63f30c7a66 100644 --- a/Content.Server/Administration/Logs/AdminLogManager.Json.cs +++ b/Content.Server/Administration/Logs/AdminLogManager.Json.cs @@ -3,8 +3,8 @@ using System.Text.Json; using System.Text.Json.Serialization; using Content.Server.Administration.Logs.Converters; using Robust.Server.GameObjects; +using Robust.Server.Player; using Robust.Shared.Map; -using Robust.Shared.Player; namespace Content.Server.Administration.Logs; @@ -44,7 +44,7 @@ public sealed partial class AdminLogManager var value = properties[key]; value = value switch { - ICommonSession player => new SerializablePlayer(player), + IPlayerSession player => new SerializablePlayer(player), EntityCoordinates entityCoordinates => new SerializableEntityCoordinates(_entityManager, entityCoordinates), _ => value }; @@ -56,7 +56,7 @@ public sealed partial class AdminLogManager { EntityUid id => id, EntityStringRepresentation rep => rep.Uid, - ICommonSession {AttachedEntity: {Valid: true}} session => session.AttachedEntity, + IPlayerSession {AttachedEntity: {Valid: true}} session => session.AttachedEntity, IComponent component => component.Owner, _ => null }; diff --git a/Content.Server/Administration/Logs/Converters/PlayerSessionConverter.cs b/Content.Server/Administration/Logs/Converters/PlayerSessionConverter.cs index c1567448cc..0605c2db2a 100644 --- a/Content.Server/Administration/Logs/Converters/PlayerSessionConverter.cs +++ b/Content.Server/Administration/Logs/Converters/PlayerSessionConverter.cs @@ -1,5 +1,5 @@ using System.Text.Json; -using Robust.Shared.Player; +using Robust.Server.Player; namespace Content.Server.Administration.Logs.Converters; @@ -36,9 +36,9 @@ public sealed class PlayerSessionConverter : AdminLogConverter _admins = new(); + private readonly Dictionary _admins = new(); private readonly HashSet _promotedPlayers = new(); public event Action? OnPermsChanged; - public IEnumerable ActiveAdmins => _admins + public IEnumerable ActiveAdmins => _admins .Where(p => p.Value.Data.Active) .Select(p => p.Key); - public IEnumerable AllAdmins => _admins.Select(p => p.Key); + public IEnumerable AllAdmins => _admins.Select(p => p.Key); private readonly AdminCommandPermissions _commandPermissions = new(); private readonly AdminCommandPermissions _toolshedCommandPermissions = new(); @@ -56,7 +56,7 @@ namespace Content.Server.Administration.Managers public AdminData? GetAdminData(ICommonSession session, bool includeDeAdmin = false) { - if (_admins.TryGetValue(session, out var reg) && (reg.Data.Active || includeDeAdmin)) + if (_admins.TryGetValue((IPlayerSession)session, out var reg) && (reg.Data.Active || includeDeAdmin)) { return reg.Data; } @@ -66,13 +66,13 @@ namespace Content.Server.Administration.Managers public AdminData? GetAdminData(EntityUid uid, bool includeDeAdmin = false) { - if (_playerManager.TryGetSessionByEntity(uid, out var session)) - return GetAdminData(session, includeDeAdmin); + if (_playerManager.TryGetSessionByEntity(uid, out var session) && session is IPlayerSession playerSession) + return GetAdminData(playerSession, includeDeAdmin); return null; } - public void DeAdmin(ICommonSession session) + public void DeAdmin(IPlayerSession session) { if (!_admins.TryGetValue(session, out var reg)) { @@ -95,7 +95,7 @@ namespace Content.Server.Administration.Managers UpdateAdminStatus(session); } - public void ReAdmin(ICommonSession session) + public void ReAdmin(IPlayerSession session) { if (!_admins.TryGetValue(session, out var reg)) { @@ -119,7 +119,7 @@ namespace Content.Server.Administration.Managers UpdateAdminStatus(session); } - public async void ReloadAdmin(ICommonSession player) + public async void ReloadAdmin(IPlayerSession player) { var data = await LoadAdminData(player); var curAdmin = _admins.GetValueOrDefault(player); @@ -236,7 +236,7 @@ namespace Content.Server.Administration.Managers _toolshed.ActivePermissionController = this; } - public void PromoteHost(ICommonSession player) + public void PromoteHost(IPlayerSession player) { _promotedPlayers.Add(player.UserId); @@ -250,7 +250,7 @@ namespace Content.Server.Administration.Managers } // NOTE: Also sends commands list for non admins.. - private void UpdateAdminStatus(ICommonSession session) + private void UpdateAdminStatus(IPlayerSession session) { var msg = new MsgUpdateAdminStatus(); @@ -290,7 +290,7 @@ namespace Content.Server.Administration.Managers } } - private async void LoginAdminMaybe(ICommonSession session) + private async void LoginAdminMaybe(IPlayerSession session) { var adminDat = await LoadAdminData(session); if (adminDat == null) @@ -323,7 +323,7 @@ namespace Content.Server.Administration.Managers UpdateAdminStatus(session); } - private async Task<(AdminData dat, int? rankId, bool specialLogin)?> LoadAdminData(ICommonSession session) + private async Task<(AdminData dat, int? rankId, bool specialLogin)?> LoadAdminData(IPlayerSession session) { var promoteHost = IsLocal(session) && _cfg.GetCVar(CCVars.ConsoleLoginLocal) || _promotedPlayers.Contains(session.UserId) @@ -387,7 +387,7 @@ namespace Content.Server.Administration.Managers } } - private static bool IsLocal(ICommonSession player) + private static bool IsLocal(IPlayerSession player) { var ep = player.ConnectedClient.RemoteEndPoint; var addr = ep.Address; @@ -419,7 +419,7 @@ namespace Content.Server.Administration.Managers return false; } - public bool CanCommand(ICommonSession session, string cmdName) + public bool CanCommand(IPlayerSession session, string cmdName) { if (_commandPermissions.AnyCommands.Contains(cmdName)) { @@ -474,7 +474,7 @@ namespace Content.Server.Administration.Managers return true; } - var data = GetAdminData(user); + var data = GetAdminData((IPlayerSession)user); if (data == null) { // Player isn't an admin. @@ -520,32 +520,32 @@ namespace Content.Server.Administration.Managers return (attribs.Length != 0, attribs); } - public bool CanViewVar(ICommonSession session) + public bool CanViewVar(IPlayerSession session) { return CanCommand(session, "vv"); } - public bool CanAdminPlace(ICommonSession session) + public bool CanAdminPlace(IPlayerSession session) { return GetAdminData(session)?.CanAdminPlace() ?? false; } - public bool CanScript(ICommonSession session) + public bool CanScript(IPlayerSession session) { return GetAdminData(session)?.CanScript() ?? false; } - public bool CanAdminMenu(ICommonSession session) + public bool CanAdminMenu(IPlayerSession session) { return GetAdminData(session)?.CanAdminMenu() ?? false; } - public bool CanAdminReloadPrototypes(ICommonSession session) + public bool CanAdminReloadPrototypes(IPlayerSession session) { return GetAdminData(session)?.CanAdminReloadPrototypes() ?? false; } - private void SendPermsChangedEvent(ICommonSession session) + private void SendPermsChangedEvent(IPlayerSession session) { var flags = GetAdminData(session)?.Flags; OnPermsChanged?.Invoke(new AdminPermsChangedEventArgs(session, flags)); @@ -553,7 +553,7 @@ namespace Content.Server.Administration.Managers private sealed class AdminReg { - public readonly ICommonSession Session; + public readonly IPlayerSession Session; public AdminData Data; public int? RankId; @@ -561,7 +561,7 @@ namespace Content.Server.Administration.Managers // Such as console.loginlocal or promotehost public bool IsSpecialLogin; - public AdminReg(ICommonSession session, AdminData data) + public AdminReg(IPlayerSession session, AdminData data) { Data = data; Session = session; diff --git a/Content.Server/Administration/Managers/BanManager.cs b/Content.Server/Administration/Managers/BanManager.cs index 4d51d35576..765df17b17 100644 --- a/Content.Server/Administration/Managers/BanManager.cs +++ b/Content.Server/Administration/Managers/BanManager.cs @@ -15,7 +15,6 @@ using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Network; -using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Utility; @@ -284,7 +283,7 @@ public sealed class BanManager : IBanManager, IPostInjectInit SendRoleBans(player); } - public void SendRoleBans(ICommonSession pSession) + public void SendRoleBans(IPlayerSession pSession) { var roleBans = _cachedRoleBans.GetValueOrDefault(pSession.UserId) ?? new HashSet(); var bans = new MsgRoleBans() diff --git a/Content.Server/Administration/Managers/IAdminManager.cs b/Content.Server/Administration/Managers/IAdminManager.cs index a52ec7b099..eeed5cc36e 100644 --- a/Content.Server/Administration/Managers/IAdminManager.cs +++ b/Content.Server/Administration/Managers/IAdminManager.cs @@ -1,8 +1,9 @@ using Content.Shared.Administration; using Content.Shared.Administration.Managers; -using Robust.Shared.Player; +using Robust.Server.Player; using Robust.Shared.Toolshed; + namespace Content.Server.Administration.Managers { /// @@ -21,12 +22,12 @@ namespace Content.Server.Administration.Managers /// /// This does not include admins that are de-adminned. /// - IEnumerable ActiveAdmins { get; } + IEnumerable ActiveAdmins { get; } /// /// Gets all admins currently on the server, even de-adminned ones. /// - IEnumerable AllAdmins { get; } + IEnumerable AllAdmins { get; } /// /// De-admins an admin temporarily so they are effectively a normal player. @@ -34,18 +35,18 @@ namespace Content.Server.Administration.Managers /// /// De-adminned admins are able to re-admin at any time if they so desire. /// - void DeAdmin(ICommonSession session); + void DeAdmin(IPlayerSession session); /// /// Re-admins a de-adminned admin. /// - void ReAdmin(ICommonSession session); + void ReAdmin(IPlayerSession session); /// /// Re-loads the permissions of an player in case their admin data changed DB-side. /// /// - void ReloadAdmin(ICommonSession player); + void ReloadAdmin(IPlayerSession player); /// /// Reloads admin permissions for all admins with a certain rank. @@ -56,7 +57,7 @@ namespace Content.Server.Administration.Managers void Initialize(); - void PromoteHost(ICommonSession player); + void PromoteHost(IPlayerSession player); bool TryGetCommandFlags(CommandSpec command, out AdminFlags[]? flags); } diff --git a/Content.Server/Administration/Managers/IBanManager.cs b/Content.Server/Administration/Managers/IBanManager.cs index dafe3d35bd..8458feac8d 100644 --- a/Content.Server/Administration/Managers/IBanManager.cs +++ b/Content.Server/Administration/Managers/IBanManager.cs @@ -2,8 +2,8 @@ using System.Collections.Immutable; using System.Net; using System.Threading.Tasks; using Content.Shared.Database; +using Robust.Server.Player; using Robust.Shared.Network; -using Robust.Shared.Player; namespace Content.Server.Administration.Managers; @@ -55,5 +55,5 @@ public interface IBanManager /// Sends role bans to the target /// /// Player's session - public void SendRoleBans(ICommonSession pSession); + public void SendRoleBans(IPlayerSession pSession); } diff --git a/Content.Server/Administration/Notes/AdminNotesManager.cs b/Content.Server/Administration/Notes/AdminNotesManager.cs index 0c1e7f3daa..8a7846663f 100644 --- a/Content.Server/Administration/Notes/AdminNotesManager.cs +++ b/Content.Server/Administration/Notes/AdminNotesManager.cs @@ -11,7 +11,7 @@ using Content.Shared.Database; using Content.Shared.Players.PlayTimeTracking; using Robust.Shared.Configuration; using Robust.Shared.Network; -using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Server.Administration.Notes; diff --git a/Content.Server/Administration/Notes/AdminNotesSystem.cs b/Content.Server/Administration/Notes/AdminNotesSystem.cs index f2eb033dca..fd9f3f6bfa 100644 --- a/Content.Server/Administration/Notes/AdminNotesSystem.cs +++ b/Content.Server/Administration/Notes/AdminNotesSystem.cs @@ -1,13 +1,13 @@ using Content.Server.Administration.Commands; using Content.Server.Chat.Managers; using Content.Server.EUI; +using Content.Shared.Chat; using Content.Shared.Database; using Content.Shared.Verbs; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; -using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Server.Administration.Notes; diff --git a/Content.Server/Administration/Notes/IAdminNotesManager.cs b/Content.Server/Administration/Notes/IAdminNotesManager.cs index a726bd11c8..ae7133c56d 100644 --- a/Content.Server/Administration/Notes/IAdminNotesManager.cs +++ b/Content.Server/Administration/Notes/IAdminNotesManager.cs @@ -2,7 +2,7 @@ using System.Threading.Tasks; using Content.Server.Database; using Content.Shared.Administration.Notes; using Content.Shared.Database; -using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Server.Administration.Notes; diff --git a/Content.Server/Administration/QuickDialogSystem.OpenDialog.cs b/Content.Server/Administration/QuickDialogSystem.OpenDialog.cs index fb013a88ad..521bee776f 100644 --- a/Content.Server/Administration/QuickDialogSystem.OpenDialog.cs +++ b/Content.Server/Administration/QuickDialogSystem.OpenDialog.cs @@ -1,6 +1,6 @@ using Content.Shared.Administration; using JetBrains.Annotations; -using Robust.Shared.Player; +using Robust.Server.Player; namespace Content.Server.Administration; @@ -16,7 +16,7 @@ public sealed partial class QuickDialogSystem /// The action to execute upon the dialog being cancelled. /// Type of the input. [PublicAPI] - public void OpenDialog(ICommonSession session, string title, string prompt, Action okAction, + public void OpenDialog(IPlayerSession session, string title, string prompt, Action okAction, Action? cancelAction = null) { OpenDialogInternal( @@ -53,7 +53,7 @@ public sealed partial class QuickDialogSystem /// Type of the first input. /// Type of the second input. [PublicAPI] - public void OpenDialog(ICommonSession session, string title, string prompt1, string prompt2, + public void OpenDialog(IPlayerSession session, string title, string prompt1, string prompt2, Action okAction, Action? cancelAction = null) { OpenDialogInternal( @@ -96,7 +96,7 @@ public sealed partial class QuickDialogSystem /// Type of the second input. /// Type of the third input. [PublicAPI] - public void OpenDialog(ICommonSession session, string title, string prompt1, string prompt2, + public void OpenDialog(IPlayerSession session, string title, string prompt1, string prompt2, string prompt3, Action okAction, Action? cancelAction = null) { OpenDialogInternal( @@ -142,7 +142,7 @@ public sealed partial class QuickDialogSystem /// Type of the third input. /// Type of the fourth input. [PublicAPI] - public void OpenDialog(ICommonSession session, string title, string prompt1, string prompt2, + public void OpenDialog(IPlayerSession session, string title, string prompt1, string prompt2, string prompt3, string prompt4, Action okAction, Action? cancelAction = null) { OpenDialogInternal( diff --git a/Content.Server/Administration/QuickDialogSystem.cs b/Content.Server/Administration/QuickDialogSystem.cs index 96423e5223..51b8cf79c2 100644 --- a/Content.Server/Administration/QuickDialogSystem.cs +++ b/Content.Server/Administration/QuickDialogSystem.cs @@ -1,9 +1,12 @@ -using System.Diagnostics.CodeAnalysis; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using Content.Shared.Administration; +using Microsoft.CodeAnalysis.CSharp.Syntax; using Robust.Server.Player; using Robust.Shared.Enums; using Robust.Shared.Network; using Robust.Shared.Player; +using Robust.Shared.Serialization.TypeSerializers.Interfaces; namespace Content.Server.Administration; @@ -84,7 +87,7 @@ public sealed partial class QuickDialogSystem : EntitySystem _openDialogsByUser.Remove(user); } - private void OpenDialogInternal(ICommonSession session, string title, List entries, QuickDialogButtonFlag buttons, Action okAction, Action cancelAction) + private void OpenDialogInternal(IPlayerSession session, string title, List entries, QuickDialogButtonFlag buttons, Action okAction, Action cancelAction) { var did = GetDialogId(); RaiseNetworkEvent( diff --git a/Content.Server/Administration/Systems/AdminSystem.cs b/Content.Server/Administration/Systems/AdminSystem.cs index feabaa2aad..66f7a8999b 100644 --- a/Content.Server/Administration/Systems/AdminSystem.cs +++ b/Content.Server/Administration/Systems/AdminSystem.cs @@ -109,7 +109,7 @@ namespace Content.Server.Administration.Systems } } - public void UpdatePlayerList(ICommonSession player) + public void UpdatePlayerList(IPlayerSession player) { _playerList[player.UserId] = GetPlayerInfo(player.Data, player); @@ -203,7 +203,7 @@ namespace Content.Server.Administration.Systems UpdatePanicBunker(); } - private void SendFullPlayerList(ICommonSession playerSession) + private void SendFullPlayerList(IPlayerSession playerSession) { var ev = new FullPlayerListEvent(); @@ -212,7 +212,7 @@ namespace Content.Server.Administration.Systems RaiseNetworkEvent(ev, playerSession.ConnectedClient); } - private PlayerInfo GetPlayerInfo(SessionData data, ICommonSession? session) + private PlayerInfo GetPlayerInfo(IPlayerData data, IPlayerSession? session) { var name = data.UserName; var entityName = string.Empty; @@ -326,7 +326,7 @@ namespace Content.Server.Administration.Systems /// chat messages and showing a popup to other players. /// Their items are dropped on the ground. /// - public void Erase(ICommonSession player) + public void Erase(IPlayerSession player) { var entity = player.AttachedEntity; _chat.DeleteMessagesBy(player); diff --git a/Content.Server/Administration/Systems/AdminTestArenaSystem.cs b/Content.Server/Administration/Systems/AdminTestArenaSystem.cs index e3671bcdfb..e65acf571c 100644 --- a/Content.Server/Administration/Systems/AdminTestArenaSystem.cs +++ b/Content.Server/Administration/Systems/AdminTestArenaSystem.cs @@ -1,8 +1,8 @@ using Robust.Server.GameObjects; +using Robust.Server.Player; using Robust.Shared.Map; using Robust.Shared.Map.Components; using Robust.Shared.Network; -using Robust.Shared.Player; namespace Content.Server.Administration.Systems; @@ -20,7 +20,7 @@ public sealed class AdminTestArenaSystem : EntitySystem public Dictionary ArenaMap { get; private set; } = new(); public Dictionary ArenaGrid { get; private set; } = new(); - public (EntityUid Map, EntityUid? Grid) AssertArenaLoaded(ICommonSession admin) + public (EntityUid Map, EntityUid? Grid) AssertArenaLoaded(IPlayerSession admin) { if (ArenaMap.TryGetValue(admin.UserId, out var arenaMap) && !Deleted(arenaMap) && !Terminating(arenaMap)) { diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.cs b/Content.Server/Administration/Systems/AdminVerbSystem.cs index bc065745f5..c7e23374a3 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.cs @@ -6,7 +6,6 @@ using Content.Server.Disposal.Tube; using Content.Server.Disposal.Tube.Components; using Content.Server.EUI; using Content.Server.Ghost.Roles; -using Content.Server.Mind; using Content.Server.Mind.Commands; using Content.Server.Prayer; using Content.Server.Xenoarchaeology.XenoArtifacts; @@ -19,15 +18,17 @@ using Content.Shared.Database; using Content.Shared.Examine; using Content.Shared.GameTicking; using Content.Shared.Inventory; +using Content.Shared.Mind; using Content.Shared.Mind.Components; using Content.Shared.Popups; using Content.Shared.Verbs; using Robust.Server.Console; using Robust.Server.GameObjects; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; using Robust.Shared.Map.Components; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Timing; using Robust.Shared.Toolshed; @@ -55,7 +56,7 @@ namespace Content.Server.Administration.Systems [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; [Dependency] private readonly PrayerSystem _prayerSystem = default!; [Dependency] private readonly EuiManager _eui = default!; - [Dependency] private readonly MindSystem _mindSystem = default!; + [Dependency] private readonly SharedMindSystem _mindSystem = default!; [Dependency] private readonly ToolshedManager _toolshed = default!; [Dependency] private readonly RejuvenateSystem _rejuvenate = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; @@ -276,7 +277,12 @@ namespace Content.Server.Administration.Systems // TODO VERB ICON control mob icon Act = () => { - _mindSystem.ControlMob(args.User, args.Target); + MakeSentientCommand.MakeSentient(args.Target, EntityManager); + + if (!_minds.TryGetMind(player, out var mindId, out var mind)) + return; + + _mindSystem.TransferTo(mindId, args.Target, ghostCheckOverride: true, mind: mind); }, Impact = LogImpact.High, ConfirmationPopup = true @@ -352,7 +358,7 @@ namespace Content.Server.Administration.Systems var message = ExamineSystemShared.InRangeUnOccluded(args.User, args.Target) ? Loc.GetString("in-range-unoccluded-verb-on-activate-not-occluded") : Loc.GetString("in-range-unoccluded-verb-on-activate-occluded"); - + _popup.PopupEntity(message, args.Target, args.User); } }; @@ -426,7 +432,7 @@ namespace Content.Server.Administration.Systems } } - public void OpenEditSolutionsEui(ICommonSession session, EntityUid uid) + public void OpenEditSolutionsEui(IPlayerSession session, EntityUid uid) { if (session.AttachedEntity == null) return; diff --git a/Content.Server/Administration/Systems/BwoinkSystem.cs b/Content.Server/Administration/Systems/BwoinkSystem.cs index 31ef285a88..98e5af1126 100644 --- a/Content.Server/Administration/Systems/BwoinkSystem.cs +++ b/Content.Server/Administration/Systems/BwoinkSystem.cs @@ -17,7 +17,6 @@ using Robust.Shared; using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Network; -using Robust.Shared.Player; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -120,7 +119,7 @@ namespace Content.Server.Administration.Systems _typingUpdateTimestamps[args.SenderSession.UserId] = (_timing.RealTime, msg.Typing); // Non-admins can only ever type on their own ahelp, guard against fake messages - var isAdmin = _adminManager.GetAdminData(args.SenderSession)?.HasFlag(AdminFlags.Adminhelp) ?? false; + var isAdmin = _adminManager.GetAdminData((IPlayerSession) args.SenderSession)?.HasFlag(AdminFlags.Adminhelp) ?? false; var channel = isAdmin ? msg.Channel : args.SenderSession.UserId; var update = new BwoinkPlayerTypingUpdated(channel, args.SenderSession.Name, msg.Typing); @@ -377,7 +376,7 @@ namespace Content.Server.Administration.Systems protected override void OnBwoinkTextMessage(BwoinkTextMessage message, EntitySessionEventArgs eventArgs) { base.OnBwoinkTextMessage(message, eventArgs); - var senderSession = eventArgs.SenderSession; + var senderSession = (IPlayerSession) eventArgs.SenderSession; // TODO: Sanitize text? // Confirm that this person is actually allowed to send a message here. diff --git a/Content.Server/Administration/Toolshed/AdminsCommand.cs b/Content.Server/Administration/Toolshed/AdminsCommand.cs index 1d64f748fd..aa82e0f1d9 100644 --- a/Content.Server/Administration/Toolshed/AdminsCommand.cs +++ b/Content.Server/Administration/Toolshed/AdminsCommand.cs @@ -1,6 +1,6 @@ using Content.Server.Administration.Managers; using Content.Shared.Administration; -using Robust.Shared.Player; +using Robust.Server.Player; using Robust.Shared.Toolshed; namespace Content.Server.Administration.Toolshed; @@ -11,13 +11,13 @@ public sealed class AdminsCommand : ToolshedCommand [Dependency] private readonly IAdminManager _admin = default!; [CommandImplementation("active")] - public IEnumerable Active() + public IEnumerable Active() { return _admin.ActiveAdmins; } [CommandImplementation("all")] - public IEnumerable All() + public IEnumerable All() { return _admin.AllAdmins; } diff --git a/Content.Server/Afk/AFKSystem.cs b/Content.Server/Afk/AFKSystem.cs index f634a415dc..0938f45f73 100644 --- a/Content.Server/Afk/AFKSystem.cs +++ b/Content.Server/Afk/AFKSystem.cs @@ -1,3 +1,4 @@ +using System.Linq; using Content.Server.Afk.Events; using Content.Server.GameTicking; using Content.Shared.CCVar; @@ -23,7 +24,7 @@ public sealed class AFKSystem : EntitySystem private float _checkDelay; private TimeSpan _checkTime; - private readonly HashSet _afkPlayers = new(); + private readonly HashSet _afkPlayers = new(); public override void Initialize() { @@ -72,9 +73,11 @@ public sealed class AFKSystem : EntitySystem _checkTime = _timing.CurTime + TimeSpan.FromSeconds(_checkDelay); - foreach (var pSession in Filter.GetAllPlayers()) + foreach (var session in Filter.GetAllPlayers()) { - if (pSession.Status != SessionStatus.InGame) continue; + if (session.Status != SessionStatus.InGame) continue; + + var pSession = (IPlayerSession) session; var isAfk = _afkManager.IsAfk(pSession); if (isAfk && _afkPlayers.Add(pSession)) diff --git a/Content.Server/Afk/AfkManager.cs b/Content.Server/Afk/AfkManager.cs index 52dc7715df..24cd1e28ce 100644 --- a/Content.Server/Afk/AfkManager.cs +++ b/Content.Server/Afk/AfkManager.cs @@ -5,7 +5,6 @@ using Robust.Shared.Configuration; using Robust.Shared.Console; using Robust.Shared.Enums; using Robust.Shared.Input; -using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.Afk @@ -21,13 +20,13 @@ namespace Content.Server.Afk /// /// The player to check. /// True if the player is AFK, false otherwise. - bool IsAfk(ICommonSession player); + bool IsAfk(IPlayerSession player); /// /// Resets AFK status for the player as if they just did an action and are definitely not AFK. /// /// The player to set AFK status for. - void PlayerDidAction(ICommonSession player); + void PlayerDidAction(IPlayerSession player); void Initialize(); } @@ -41,7 +40,7 @@ namespace Content.Server.Afk [Dependency] private readonly IConfigurationManager _cfg = default!; [Dependency] private readonly IConsoleHost _consoleHost = default!; - private readonly Dictionary _lastActionTimes = new(); + private readonly Dictionary _lastActionTimes = new(); public void Initialize() { @@ -56,7 +55,7 @@ namespace Content.Server.Afk HandleInputCmd); } - public void PlayerDidAction(ICommonSession player) + public void PlayerDidAction(IPlayerSession player) { if (player.Status == SessionStatus.Disconnected) // Make sure we don't re-add to the dictionary if the player is disconnected now. @@ -65,7 +64,7 @@ namespace Content.Server.Afk _lastActionTimes[player] = _gameTiming.RealTime; } - public bool IsAfk(ICommonSession player) + public bool IsAfk(IPlayerSession player) { if (!_lastActionTimes.TryGetValue(player, out var time)) // Some weird edge case like disconnected clients. Just say true I guess. @@ -88,13 +87,13 @@ namespace Content.Server.Afk private void ConsoleHostOnAnyCommandExecuted(IConsoleShell shell, string commandname, string argstr, string[] args) { - if (shell.Player is { } player) + if (shell.Player is IPlayerSession player) PlayerDidAction(player); } private void HandleInputCmd(FullInputCmdMessage msg, EntitySessionEventArgs args) { - PlayerDidAction(args.SenderSession); + PlayerDidAction((IPlayerSession) args.SenderSession); } } } diff --git a/Content.Server/Afk/Events/AFKEvent.cs b/Content.Server/Afk/Events/AFKEvent.cs index ee9d548043..6adb950e47 100644 --- a/Content.Server/Afk/Events/AFKEvent.cs +++ b/Content.Server/Afk/Events/AFKEvent.cs @@ -1,4 +1,4 @@ -using Robust.Shared.Player; +using Robust.Server.Player; namespace Content.Server.Afk.Events; @@ -8,9 +8,9 @@ namespace Content.Server.Afk.Events; [ByRefEvent] public readonly struct AFKEvent { - public readonly ICommonSession Session; + public readonly IPlayerSession Session; - public AFKEvent(ICommonSession playerSession) + public AFKEvent(IPlayerSession playerSession) { Session = playerSession; } diff --git a/Content.Server/Afk/Events/UnAFKEvent.cs b/Content.Server/Afk/Events/UnAFKEvent.cs index 0983c256f0..3dd034583c 100644 --- a/Content.Server/Afk/Events/UnAFKEvent.cs +++ b/Content.Server/Afk/Events/UnAFKEvent.cs @@ -1,4 +1,4 @@ -using Robust.Shared.Player; +using Robust.Server.Player; namespace Content.Server.Afk.Events; @@ -8,9 +8,9 @@ namespace Content.Server.Afk.Events; [ByRefEvent] public readonly struct UnAFKEvent { - public readonly ICommonSession Session; + public readonly IPlayerSession Session; - public UnAFKEvent(ICommonSession playerSession) + public UnAFKEvent(IPlayerSession playerSession) { Session = playerSession; } diff --git a/Content.Server/Alert/Commands/ClearAlert.cs b/Content.Server/Alert/Commands/ClearAlert.cs index 1759612702..e43f06413c 100644 --- a/Content.Server/Alert/Commands/ClearAlert.cs +++ b/Content.Server/Alert/Commands/ClearAlert.cs @@ -2,6 +2,7 @@ using Content.Server.Administration; using Content.Server.Commands; using Content.Shared.Administration; using Content.Shared.Alert; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Alert.Commands @@ -15,7 +16,7 @@ namespace Content.Server.Alert.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player?.AttachedEntity == null) { shell.WriteLine("You don't have an entity."); diff --git a/Content.Server/Alert/Commands/ShowAlert.cs b/Content.Server/Alert/Commands/ShowAlert.cs index 11901e9af0..edb634b546 100644 --- a/Content.Server/Alert/Commands/ShowAlert.cs +++ b/Content.Server/Alert/Commands/ShowAlert.cs @@ -2,6 +2,7 @@ using Content.Server.Administration; using Content.Server.Commands; using Content.Shared.Administration; using Content.Shared.Alert; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Alert.Commands @@ -15,7 +16,7 @@ namespace Content.Server.Alert.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player?.AttachedEntity == null) { shell.WriteLine("You cannot run this from the server or without an attached entity."); diff --git a/Content.Server/AlertLevel/Commands/SetAlertLevelCommand.cs b/Content.Server/AlertLevel/Commands/SetAlertLevelCommand.cs index 2c432a2419..009a8b5f23 100644 --- a/Content.Server/AlertLevel/Commands/SetAlertLevelCommand.cs +++ b/Content.Server/AlertLevel/Commands/SetAlertLevelCommand.cs @@ -3,6 +3,7 @@ using Content.Server.Administration; using Content.Server.Station.Systems; using Content.Shared.Administration; using JetBrains.Annotations; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.AlertLevel.Commands @@ -18,7 +19,7 @@ namespace Content.Server.AlertLevel.Commands public CompletionResult GetCompletion(IConsoleShell shell, string[] args) { var levelNames = new string[] {}; - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player?.AttachedEntity != null) { var stationUid = EntitySystem.Get().GetOwningStation(player.AttachedEntity.Value); @@ -53,7 +54,7 @@ namespace Content.Server.AlertLevel.Commands return; } - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player?.AttachedEntity == null) { shell.WriteLine(Loc.GetString("shell-only-players-can-run-this-command")); diff --git a/Content.Server/Antag/AntagSelectionSystem.cs b/Content.Server/Antag/AntagSelectionSystem.cs index 737b723d39..5e323f5ab8 100644 --- a/Content.Server/Antag/AntagSelectionSystem.cs +++ b/Content.Server/Antag/AntagSelectionSystem.cs @@ -22,7 +22,6 @@ using Content.Server.Station.Systems; using Content.Server.Shuttles.Systems; using Content.Shared.Mobs; using Robust.Server.Containers; -using Robust.Shared.Player; using Robust.Shared.Prototypes; namespace Content.Server.Antag; @@ -89,9 +88,9 @@ public sealed class AntagSelectionSystem : GameRuleSystem out List chosen, bool includeHeads = false) { - var allPlayers = _playerSystem.Sessions.ToList(); - var playerList = new List(); - var prefList = new List(); + var allPlayers = _playerSystem.ServerSessions.ToList(); + var playerList = new List(); + var prefList = new List(); chosen = new List(); foreach (var player in allPlayers) { @@ -117,7 +116,7 @@ public sealed class AntagSelectionSystem : GameRuleSystem var antags = Math.Clamp(allPlayers.Count / antagsPerPlayer, 1, maxAntags); for (var antag = 0; antag < antags; antag++) { - ICommonSession? chosenPlayer = null; + IPlayerSession chosenPlayer = null!; if (prefList.Count == 0) { if (playerList.Count == 0) diff --git a/Content.Server/Arcade/BlockGame/BlockGame.Ui.cs b/Content.Server/Arcade/BlockGame/BlockGame.Ui.cs index ef69600783..92a96ea226 100644 --- a/Content.Server/Arcade/BlockGame/BlockGame.Ui.cs +++ b/Content.Server/Arcade/BlockGame/BlockGame.Ui.cs @@ -1,6 +1,6 @@ using Content.Shared.Arcade; +using Robust.Server.Player; using System.Linq; -using Robust.Shared.Player; namespace Content.Server.Arcade.BlockGame; @@ -166,7 +166,7 @@ public sealed partial class BlockGame /// /// The message to send to a specific player/spectator. /// The target recipient. - private void SendMessage(BoundUserInterfaceMessage message, ICommonSession session) + private void SendMessage(BoundUserInterfaceMessage message, IPlayerSession session) { if (_uiSystem.TryGetUi(_owner, BlockGameUiKey.Key, out var bui)) _uiSystem.TrySendUiMessage(bui, message, session); @@ -176,7 +176,7 @@ public sealed partial class BlockGame /// Handles sending the current state of the game to a player that has just opened the UI. /// /// The target recipient. - public void UpdateNewPlayerUI(ICommonSession session) + public void UpdateNewPlayerUI(IPlayerSession session) { if (_gameOver) { @@ -209,7 +209,7 @@ public sealed partial class BlockGame /// Handles broadcasting the full player-visible game state to a specific player/spectator. /// /// The target recipient. - private void FullUpdate(ICommonSession session) + private void FullUpdate(IPlayerSession session) { UpdateFieldUI(session); SendNextPieceUpdate(session); @@ -235,7 +235,7 @@ public sealed partial class BlockGame /// Handles broadcasting the current location of all of the blocks in the playfield + the active piece to a specific player/spectator. /// /// The target recipient. - public void UpdateFieldUI(ICommonSession session) + public void UpdateFieldUI(IPlayerSession session) { if (!Started) return; @@ -283,7 +283,7 @@ public sealed partial class BlockGame /// Broadcasts the state of the next queued piece to a specific viewer. /// /// The target recipient. - private void SendNextPieceUpdate(ICommonSession session) + private void SendNextPieceUpdate(IPlayerSession session) { SendMessage(new BlockGameMessages.BlockGameVisualUpdateMessage(NextPiece.BlocksForPreview(), BlockGameMessages.BlockGameVisualType.NextBlock), session); } @@ -303,7 +303,7 @@ public sealed partial class BlockGame /// Broadcasts the state of the currently held piece to a specific viewer. /// /// The target recipient. - private void SendHoldPieceUpdate(ICommonSession session) + private void SendHoldPieceUpdate(IPlayerSession session) { if (HeldPiece.HasValue) SendMessage(new BlockGameMessages.BlockGameVisualUpdateMessage(HeldPiece.Value.BlocksForPreview(), BlockGameMessages.BlockGameVisualType.HoldBlock), session); @@ -323,7 +323,7 @@ public sealed partial class BlockGame /// Broadcasts the current game level to a specific viewer. /// /// The target recipient. - private void SendLevelUpdate(ICommonSession session) + private void SendLevelUpdate(IPlayerSession session) { SendMessage(new BlockGameMessages.BlockGameLevelUpdateMessage(Level), session); } @@ -340,7 +340,7 @@ public sealed partial class BlockGame /// Broadcasts the current game score to a specific viewer. /// /// The target recipient. - private void SendPointsUpdate(ICommonSession session) + private void SendPointsUpdate(IPlayerSession session) { SendMessage(new BlockGameMessages.BlockGameScoreUpdateMessage(Points), session); } @@ -357,7 +357,7 @@ public sealed partial class BlockGame /// Broadcasts the current game high score positions to a specific viewer. /// /// The target recipient. - private void SendHighscoreUpdate(ICommonSession session) + private void SendHighscoreUpdate(IPlayerSession session) { SendMessage(new BlockGameMessages.BlockGameHighScoreUpdateMessage(_arcadeSystem.GetLocalHighscores(), _arcadeSystem.GetGlobalHighscores()), session); } diff --git a/Content.Server/Arcade/BlockGame/BlockGameArcadeComponent.cs b/Content.Server/Arcade/BlockGame/BlockGameArcadeComponent.cs index 5613d91544..268d5be4d2 100644 --- a/Content.Server/Arcade/BlockGame/BlockGameArcadeComponent.cs +++ b/Content.Server/Arcade/BlockGame/BlockGameArcadeComponent.cs @@ -1,4 +1,4 @@ -using Robust.Shared.Player; +using Robust.Server.Player; namespace Content.Server.Arcade.BlockGame; @@ -13,10 +13,10 @@ public sealed partial class BlockGameArcadeComponent : Component /// /// The player currently playing the active session of NT-BG. /// - public ICommonSession? Player = null; + public IPlayerSession? Player = null; /// /// The players currently viewing (but not playing) the active session of NT-BG. /// - public readonly List Spectators = new(); + public readonly List Spectators = new(); } diff --git a/Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs b/Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs index ecc5bfd3e2..dac29accc9 100644 --- a/Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs +++ b/Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs @@ -2,7 +2,7 @@ using Content.Server.Power.Components; using Content.Server.UserInterface; using Content.Shared.Arcade; using Robust.Server.GameObjects; -using Robust.Shared.Player; +using Robust.Server.Player; namespace Content.Server.Arcade.BlockGame; @@ -30,7 +30,7 @@ public sealed class BlockGameArcadeSystem : EntitySystem } } - private void UpdatePlayerStatus(EntityUid uid, ICommonSession session, PlayerBoundUserInterface? bui = null, BlockGameArcadeComponent? blockGame = null) + private void UpdatePlayerStatus(EntityUid uid, IPlayerSession session, PlayerBoundUserInterface? bui = null, BlockGameArcadeComponent? blockGame = null) { if (!Resolve(uid, ref blockGame)) return; @@ -67,7 +67,7 @@ public sealed class BlockGameArcadeSystem : EntitySystem private void OnAfterUiClose(EntityUid uid, BlockGameArcadeComponent component, BoundUIClosedEvent args) { - if (args.Session is not { } session) + if (args.Session is not IPlayerSession session) return; if (component.Player != session) diff --git a/Content.Server/Atmos/Commands/DeleteGasCommand.cs b/Content.Server/Atmos/Commands/DeleteGasCommand.cs index 9e7594c024..0f0c399b11 100644 --- a/Content.Server/Atmos/Commands/DeleteGasCommand.cs +++ b/Content.Server/Atmos/Commands/DeleteGasCommand.cs @@ -2,6 +2,7 @@ using Content.Server.Administration; using Content.Server.Atmos.EntitySystems; using Content.Shared.Administration; using Content.Shared.Atmos; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; @@ -19,7 +20,7 @@ namespace Content.Server.Atmos.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; EntityUid? gridId; Gas? gas = null; diff --git a/Content.Server/Atmos/Commands/ShowAtmosCommand.cs b/Content.Server/Atmos/Commands/ShowAtmosCommand.cs index 263ef947d0..5ad73ec906 100644 --- a/Content.Server/Atmos/Commands/ShowAtmosCommand.cs +++ b/Content.Server/Atmos/Commands/ShowAtmosCommand.cs @@ -1,6 +1,7 @@ using Content.Server.Administration; using Content.Server.Atmos.EntitySystems; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Atmos.Commands @@ -14,7 +15,7 @@ namespace Content.Server.Atmos.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player == null) { shell.WriteLine("You must be a player to use this command."); diff --git a/Content.Server/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs b/Content.Server/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs index 90edd4caed..34f558a252 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs @@ -10,7 +10,6 @@ using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Map; using Robust.Shared.Map.Components; -using Robust.Shared.Player; namespace Content.Server.Atmos.EntitySystems { @@ -28,7 +27,7 @@ namespace Content.Server.Atmos.EntitySystems /// To modify it see and /// . /// - private readonly HashSet _playerObservers = new(); + private readonly HashSet _playerObservers = new(); /// /// Overlay update ticks per second. @@ -49,17 +48,17 @@ namespace Content.Server.Atmos.EntitySystems _playerManager.PlayerStatusChanged -= OnPlayerStatusChanged; } - public bool AddObserver(ICommonSession observer) + public bool AddObserver(IPlayerSession observer) { return _playerObservers.Add(observer); } - public bool HasObserver(ICommonSession observer) + public bool HasObserver(IPlayerSession observer) { return _playerObservers.Contains(observer); } - public bool RemoveObserver(ICommonSession observer) + public bool RemoveObserver(IPlayerSession observer) { if (!_playerObservers.Remove(observer)) { @@ -77,7 +76,7 @@ namespace Content.Server.Atmos.EntitySystems /// /// The observer to toggle. /// true if added, false if removed. - public bool ToggleObserver(ICommonSession observer) + public bool ToggleObserver(IPlayerSession observer) { if (HasObserver(observer)) { diff --git a/Content.Server/Atmos/EntitySystems/GasTankSystem.cs b/Content.Server/Atmos/EntitySystems/GasTankSystem.cs index 17715435b2..df867d3516 100644 --- a/Content.Server/Atmos/EntitySystems/GasTankSystem.cs +++ b/Content.Server/Atmos/EntitySystems/GasTankSystem.cs @@ -12,6 +12,7 @@ using Content.Shared.Toggleable; using Content.Shared.Verbs; using JetBrains.Annotations; using Robust.Server.GameObjects; +using Robust.Server.Player; using Robust.Shared.Audio; using Robust.Shared.Containers; using Robust.Shared.Physics.Systems; @@ -59,6 +60,12 @@ namespace Content.Server.Atmos.EntitySystems private void OnGasTankToggleInternals(Entity ent, ref GasTankToggleInternalsMessage args) { + if (args.Session is not IPlayerSession playerSession || + playerSession.AttachedEntity == null) + { + return; + } + ToggleInternals(ent); } diff --git a/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs b/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs index b0e8cf71c7..c229ef50c9 100644 --- a/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs +++ b/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs @@ -16,7 +16,6 @@ using Robust.Shared; using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Map; -using Robust.Shared.Player; using Robust.Shared.Threading; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -36,7 +35,7 @@ namespace Content.Server.Atmos.EntitySystems [Robust.Shared.IoC.Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!; [Robust.Shared.IoC.Dependency] private readonly ChunkingSystem _chunkingSys = default!; - private readonly Dictionary>> _lastSentChunks = new(); + private readonly Dictionary>> _lastSentChunks = new(); // Oh look its more duplicated decal system code! private ObjectPool> _chunkIndexPool = @@ -287,12 +286,12 @@ namespace Content.Server.Atmos.EntitySystems // Now we'll go through each player, then through each chunk in range of that player checking if the player is still in range // If they are, check if they need the new data to send (i.e. if there's an overlay for the gas). // Afterwards we reset all the chunk data for the next time we tick. - var players = _playerManager.Sessions.Where(x => x.Status == SessionStatus.InGame).ToArray(); + var players = _playerManager.ServerSessions.Where(x => x.Status == SessionStatus.InGame).ToArray(); var opts = new ParallelOptions { MaxDegreeOfParallelism = _parMan.ParallelProcessCount }; Parallel.ForEach(players, opts, p => UpdatePlayer(p, curTick)); } - private void UpdatePlayer(ICommonSession playerSession, GameTick curTick) + private void UpdatePlayer(IPlayerSession playerSession, GameTick curTick) { var chunksInRange = _chunkingSys.GetChunksForSession(playerSession, ChunkSize, _chunkIndexPool, _chunkViewerPool); var previouslySent = _lastSentChunks[playerSession]; diff --git a/Content.Server/Body/Commands/AddHandCommand.cs b/Content.Server/Body/Commands/AddHandCommand.cs index 655d0c88f9..308295c06c 100644 --- a/Content.Server/Body/Commands/AddHandCommand.cs +++ b/Content.Server/Body/Commands/AddHandCommand.cs @@ -4,6 +4,7 @@ using Content.Server.Body.Systems; using Content.Shared.Administration; using Content.Shared.Body.Components; using Content.Shared.Body.Part; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -26,7 +27,7 @@ namespace Content.Server.Body.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; EntityUid entity; EntityUid hand; diff --git a/Content.Server/Body/Commands/AttachBodyPartCommand.cs b/Content.Server/Body/Commands/AttachBodyPartCommand.cs index 24604b88b7..267b520808 100644 --- a/Content.Server/Body/Commands/AttachBodyPartCommand.cs +++ b/Content.Server/Body/Commands/AttachBodyPartCommand.cs @@ -1,8 +1,10 @@ +using System.Linq; using Content.Server.Administration; using Content.Server.Body.Systems; using Content.Shared.Administration; using Content.Shared.Body.Components; using Content.Shared.Body.Part; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Body.Commands @@ -18,7 +20,7 @@ namespace Content.Server.Body.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; EntityUid bodyId; EntityUid? partUid; diff --git a/Content.Server/Body/Commands/DestroyMechanismCommand.cs b/Content.Server/Body/Commands/DestroyMechanismCommand.cs index 3aa28f4072..6ad0631150 100644 --- a/Content.Server/Body/Commands/DestroyMechanismCommand.cs +++ b/Content.Server/Body/Commands/DestroyMechanismCommand.cs @@ -2,6 +2,7 @@ using Content.Server.Administration; using Content.Server.Body.Systems; using Content.Shared.Administration; using Content.Shared.Body.Components; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Random; @@ -16,7 +17,7 @@ namespace Content.Server.Body.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player == null) { shell.WriteLine("Only a player can run this command."); diff --git a/Content.Server/Body/Commands/RemoveHandCommand.cs b/Content.Server/Body/Commands/RemoveHandCommand.cs index 4a2956ae7a..729db4bc44 100644 --- a/Content.Server/Body/Commands/RemoveHandCommand.cs +++ b/Content.Server/Body/Commands/RemoveHandCommand.cs @@ -4,6 +4,7 @@ using Content.Server.Body.Systems; using Content.Shared.Administration; using Content.Shared.Body.Components; using Content.Shared.Body.Part; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Random; @@ -21,7 +22,7 @@ namespace Content.Server.Body.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player == null) { shell.WriteLine("Only a player can run this command."); diff --git a/Content.Server/Body/Systems/BodySystem.cs b/Content.Server/Body/Systems/BodySystem.cs index 242b02d78c..f2f848c488 100644 --- a/Content.Server/Body/Systems/BodySystem.cs +++ b/Content.Server/Body/Systems/BodySystem.cs @@ -116,7 +116,7 @@ public sealed class BodySystem : SharedBodySystem if (!Resolve(bodyId, ref body, false)) return new HashSet(); - if (TerminatingOrDeleted(bodyId) || EntityManager.IsQueuedForDeletion(bodyId)) + if (LifeStage(bodyId) >= EntityLifeStage.Terminating || EntityManager.IsQueuedForDeletion(bodyId)) return new HashSet(); var xform = Transform(bodyId); diff --git a/Content.Server/Cargo/Systems/CargoSystem.Orders.cs b/Content.Server/Cargo/Systems/CargoSystem.Orders.cs index f659357ad3..d9327b5150 100644 --- a/Content.Server/Cargo/Systems/CargoSystem.Orders.cs +++ b/Content.Server/Cargo/Systems/CargoSystem.Orders.cs @@ -8,7 +8,7 @@ using Content.Shared.Cargo.Events; using Content.Shared.Cargo.Prototypes; using Content.Shared.Database; using Robust.Shared.Map; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Utility; diff --git a/Content.Server/CartridgeLoader/CartridgeLoaderSystem.cs b/Content.Server/CartridgeLoader/CartridgeLoaderSystem.cs index 02b2eee771..9f7acce4fd 100644 --- a/Content.Server/CartridgeLoader/CartridgeLoaderSystem.cs +++ b/Content.Server/CartridgeLoader/CartridgeLoaderSystem.cs @@ -6,9 +6,9 @@ using Content.Shared.CartridgeLoader; using Content.Shared.Interaction; using Robust.Server.Containers; using Robust.Server.GameObjects; +using Robust.Server.Player; using Robust.Shared.Containers; using Robust.Shared.Map; -using Robust.Shared.Player; namespace Content.Server.CartridgeLoader; @@ -98,7 +98,7 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem /// and use this method to update its state so the cartridge loaders state can be added to it. /// /// - public void UpdateUiState(EntityUid loaderUid, ICommonSession? session, CartridgeLoaderComponent? loader) + public void UpdateUiState(EntityUid loaderUid, IPlayerSession? session, CartridgeLoaderComponent? loader) { if (!Resolve(loaderUid, ref loader)) return; @@ -122,7 +122,7 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem /// This method is called "UpdateCartridgeUiState" but cartridges and a programs are the same. A cartridge is just a program as a visible item. /// /// - public void UpdateCartridgeUiState(EntityUid loaderUid, BoundUserInterfaceState state, ICommonSession? session = default!, CartridgeLoaderComponent? loader = default!) + public void UpdateCartridgeUiState(EntityUid loaderUid, BoundUserInterfaceState state, IPlayerSession? session = default!, CartridgeLoaderComponent? loader = default!) { if (!Resolve(loaderUid, ref loader)) return; diff --git a/Content.Server/Chat/Commands/AdminChatCommand.cs b/Content.Server/Chat/Commands/AdminChatCommand.cs index 979051e9d3..8aa95ffee1 100644 --- a/Content.Server/Chat/Commands/AdminChatCommand.cs +++ b/Content.Server/Chat/Commands/AdminChatCommand.cs @@ -1,6 +1,7 @@ using Content.Server.Administration; using Content.Server.Chat.Managers; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Chat.Commands @@ -14,7 +15,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = (IPlayerSession?) shell.Player; if (player == null) { diff --git a/Content.Server/Chat/Commands/LOOCCommand.cs b/Content.Server/Chat/Commands/LOOCCommand.cs index 9e16193fc3..a897a0b2bf 100644 --- a/Content.Server/Chat/Commands/LOOCCommand.cs +++ b/Content.Server/Chat/Commands/LOOCCommand.cs @@ -1,5 +1,6 @@ using Content.Server.Chat.Systems; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; @@ -14,7 +15,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not { } player) + if (shell.Player is not IPlayerSession player) { shell.WriteError("This command cannot be run from the server."); return; diff --git a/Content.Server/Chat/Commands/MeCommand.cs b/Content.Server/Chat/Commands/MeCommand.cs index e763d5656e..36f86cf4d6 100644 --- a/Content.Server/Chat/Commands/MeCommand.cs +++ b/Content.Server/Chat/Commands/MeCommand.cs @@ -1,5 +1,6 @@ using Content.Server.Chat.Systems; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; @@ -14,7 +15,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not { } player) + if (shell.Player is not IPlayerSession player) { shell.WriteError("This command cannot be run from the server."); return; diff --git a/Content.Server/Chat/Commands/OOCCommand.cs b/Content.Server/Chat/Commands/OOCCommand.cs index 36f6303fbd..bef2024608 100644 --- a/Content.Server/Chat/Commands/OOCCommand.cs +++ b/Content.Server/Chat/Commands/OOCCommand.cs @@ -1,5 +1,6 @@ using Content.Server.Chat.Managers; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Chat.Commands @@ -13,7 +14,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not { } player) + if (shell.Player is not IPlayerSession player) { shell.WriteError("This command cannot be run from the server."); return; diff --git a/Content.Server/Chat/Commands/SayCommand.cs b/Content.Server/Chat/Commands/SayCommand.cs index 273f908c9a..7c2125d8c1 100644 --- a/Content.Server/Chat/Commands/SayCommand.cs +++ b/Content.Server/Chat/Commands/SayCommand.cs @@ -1,5 +1,6 @@ using Content.Server.Chat.Systems; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; @@ -14,7 +15,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not { } player) + if (shell.Player is not IPlayerSession player) { shell.WriteError("This command cannot be run from the server."); return; diff --git a/Content.Server/Chat/Commands/SuicideCommand.cs b/Content.Server/Chat/Commands/SuicideCommand.cs index c967ba78d7..389ff039bf 100644 --- a/Content.Server/Chat/Commands/SuicideCommand.cs +++ b/Content.Server/Chat/Commands/SuicideCommand.cs @@ -1,6 +1,7 @@ using Content.Server.GameTicking; using Content.Shared.Administration; using Content.Shared.Mind; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; @@ -17,7 +18,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not { } player) + if (shell.Player is not IPlayerSession player) { shell.WriteLine(Loc.GetString("shell-cannot-run-command-from-server")); return; diff --git a/Content.Server/Chat/Commands/WhisperCommand.cs b/Content.Server/Chat/Commands/WhisperCommand.cs index c88e2519ee..41eba8b384 100644 --- a/Content.Server/Chat/Commands/WhisperCommand.cs +++ b/Content.Server/Chat/Commands/WhisperCommand.cs @@ -1,5 +1,6 @@ using Content.Server.Chat.Systems; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; @@ -14,7 +15,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not { } player) + if (shell.Player is not IPlayerSession player) { shell.WriteError("This command cannot be run from the server."); return; diff --git a/Content.Server/Chat/Managers/ChatManager.cs b/Content.Server/Chat/Managers/ChatManager.cs index 59a9d305bd..88e143d24e 100644 --- a/Content.Server/Chat/Managers/ChatManager.cs +++ b/Content.Server/Chat/Managers/ChatManager.cs @@ -10,9 +10,11 @@ using Content.Shared.CCVar; using Content.Shared.Chat; using Content.Shared.Database; using Content.Shared.Mind; +using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Network; using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Replays; using Robust.Shared.Utility; @@ -49,8 +51,8 @@ namespace Content.Server.Chat.Managers private bool _oocEnabled = true; private bool _adminOocEnabled = true; - public Dictionary SenderKeys { get; } = new(); - public Dictionary> SenderEntities { get; } = new(); + public Dictionary SenderKeys { get; } = new(); + public Dictionary> SenderEntities { get; } = new(); public void Initialize() { @@ -77,7 +79,7 @@ namespace Content.Server.Chat.Managers DispatchServerAnnouncement(Loc.GetString(val ? "chat-manager-admin-ooc-chat-enabled-message" : "chat-manager-admin-ooc-chat-disabled-message")); } - public void DeleteMessagesBy(ICommonSession player) + public void DeleteMessagesBy(IPlayerSession player) { var key = SenderKeys.GetValueOrDefault(player); var entities = SenderEntities.GetValueOrDefault(player) ?? new HashSet(); @@ -163,7 +165,7 @@ namespace Content.Server.Chat.Managers /// The player sending the message. /// The message. /// The type of message. - public void TrySendOOCMessage(ICommonSession player, string message, OOCChatType type) + public void TrySendOOCMessage(IPlayerSession player, string message, OOCChatType type) { // Check if message exceeds the character limit if (message.Length > MaxMessageLength) @@ -187,7 +189,7 @@ namespace Content.Server.Chat.Managers #region Private API - private void SendOOC(ICommonSession player, string message) + private void SendOOC(IPlayerSession player, string message) { if (_adminManager.IsAdmin(player)) { @@ -224,7 +226,7 @@ namespace Content.Server.Chat.Managers _adminLogger.Add(LogType.Chat, LogImpact.Low, $"OOC from {player:Player}: {message}"); } - private void SendAdminChat(ICommonSession player, string message) + private void SendAdminChat(IPlayerSession player, string message) { if (!_adminManager.IsAdmin(player)) { @@ -324,7 +326,7 @@ namespace Content.Server.Chat.Managers } } - public bool MessageCharacterLimit(ICommonSession? player, string message) + public bool MessageCharacterLimit(IPlayerSession? player, string message) { var isOverLength = false; diff --git a/Content.Server/Chat/Managers/IChatManager.cs b/Content.Server/Chat/Managers/IChatManager.cs index 5317b3054e..10103f011d 100644 --- a/Content.Server/Chat/Managers/IChatManager.cs +++ b/Content.Server/Chat/Managers/IChatManager.cs @@ -1,6 +1,8 @@ using Content.Shared.Chat; +using Robust.Server.Player; using Robust.Shared.Network; using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Server.Chat.Managers { @@ -10,12 +12,12 @@ namespace Content.Server.Chat.Managers /// Keys identifying messages sent by a specific player, used when sending /// /// - Dictionary SenderKeys { get; } + Dictionary SenderKeys { get; } /// /// Tracks which entities a player was attached to while sending messages. /// - Dictionary> SenderEntities { get; } + Dictionary> SenderEntities { get; } void Initialize(); @@ -28,7 +30,7 @@ namespace Content.Server.Chat.Managers void DispatchServerMessage(ICommonSession player, string message, bool suppressLog = false); - void TrySendOOCMessage(ICommonSession player, string message, OOCChatType type); + void TrySendOOCMessage(IPlayerSession player, string message, OOCChatType type); void SendHookOOC(string sender, string message); void SendAdminAnnouncement(string message); @@ -45,8 +47,8 @@ namespace Content.Server.Chat.Managers void ChatMessageToAll(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, bool recordReplay, Color? colorOverride = null, string? audioPath = null, float audioVolume = 0, int? senderKey = null); - bool MessageCharacterLimit(ICommonSession player, string message); + bool MessageCharacterLimit(IPlayerSession player, string message); - void DeleteMessagesBy(ICommonSession player); + void DeleteMessagesBy(IPlayerSession player); } } diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs index 3315f61c2f..455d34c907 100644 --- a/Content.Server/Chat/Systems/ChatSystem.cs +++ b/Content.Server/Chat/Systems/ChatSystem.cs @@ -7,6 +7,7 @@ using Content.Server.Administration.Logs; using Content.Server.Administration.Managers; using Content.Server.Chat.Managers; using Content.Server.GameTicking; +using Content.Server.Players; using Content.Server.Station.Components; using Content.Server.Station.Systems; using Content.Shared.ActionBlocker; @@ -17,7 +18,6 @@ using Content.Shared.Ghost; using Content.Shared.IdentityManagement; using Content.Shared.Interaction; using Content.Shared.Mobs.Systems; -using Content.Shared.Players; using Content.Shared.Radio; using Robust.Server.GameObjects; using Robust.Server.Player; @@ -26,6 +26,7 @@ using Robust.Shared.Configuration; using Robust.Shared.Console; using Robust.Shared.Network; using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Replays; @@ -146,7 +147,7 @@ public sealed partial class ChatSystem : SharedChatSystem InGameICChatType desiredType, bool hideChat, bool hideLog = false, IConsoleShell? shell = null, - ICommonSession? player = null, string? nameOverride = null, + IPlayerSession? player = null, string? nameOverride = null, bool checkRadioPrefix = true, bool ignoreActionBlocker = false) { @@ -171,7 +172,7 @@ public sealed partial class ChatSystem : SharedChatSystem ChatTransmitRange range, bool hideLog = false, IConsoleShell? shell = null, - ICommonSession? player = null, + IPlayerSession? player = null, string? nameOverride = null, bool checkRadioPrefix = true, bool ignoreActionBlocker = false @@ -252,7 +253,7 @@ public sealed partial class ChatSystem : SharedChatSystem InGameOOCChatType type, bool hideChat, IConsoleShell? shell = null, - ICommonSession? player = null + IPlayerSession? player = null ) { if (!CanSendInGame(message, shell, player)) @@ -546,7 +547,7 @@ public sealed partial class ChatSystem : SharedChatSystem } // ReSharper disable once InconsistentNaming - private void SendLOOC(EntityUid source, ICommonSession player, string message, bool hideChat) + private void SendLOOC(EntityUid source, IPlayerSession player, string message, bool hideChat) { var name = FormattedMessage.EscapeText(Identity.Name(source, EntityManager)); @@ -570,7 +571,7 @@ public sealed partial class ChatSystem : SharedChatSystem _adminLogger.Add(LogType.Chat, LogImpact.Low, $"LOOC from {player:Player}: {message}"); } - private void SendDeadChat(EntityUid source, ICommonSession player, string message, bool hideChat) + private void SendDeadChat(EntityUid source, IPlayerSession player, string message, bool hideChat) { var clients = GetDeadChatClients(); var playerName = Name(source); @@ -627,13 +628,13 @@ public sealed partial class ChatSystem : SharedChatSystem initialResult = MessageRangeCheckResult.Full; break; case ChatTransmitRange.GhostRangeLimit: - initialResult = (data.Observer && data.Range < 0 && !_adminManager.IsAdmin(session)) ? MessageRangeCheckResult.HideChat : MessageRangeCheckResult.Full; + initialResult = (data.Observer && data.Range < 0 && !_adminManager.IsAdmin((IPlayerSession) session)) ? MessageRangeCheckResult.HideChat : MessageRangeCheckResult.Full; break; case ChatTransmitRange.HideChat: initialResult = MessageRangeCheckResult.HideChat; break; case ChatTransmitRange.NoGhosts: - initialResult = (data.Observer && !_adminManager.IsAdmin(session)) ? MessageRangeCheckResult.Disallowed : MessageRangeCheckResult.Full; + initialResult = (data.Observer && !_adminManager.IsAdmin((IPlayerSession) session)) ? MessageRangeCheckResult.Disallowed : MessageRangeCheckResult.Full; break; } var insistHideChat = data.HideChatOverride ?? false; @@ -665,7 +666,7 @@ public sealed partial class ChatSystem : SharedChatSystem /// /// Returns true if the given player is 'allowed' to send the given message, false otherwise. /// - private bool CanSendInGame(string message, IConsoleShell? shell = null, ICommonSession? player = null) + private bool CanSendInGame(string message, IConsoleShell? shell = null, IPlayerSession? player = null) { // Non-players don't have to worry about these restrictions. if (player == null) @@ -693,7 +694,7 @@ public sealed partial class ChatSystem : SharedChatSystem { var newMessage = message.Trim(); newMessage = SanitizeMessageReplaceWords(newMessage); - + if (capitalize) newMessage = SanitizeMessageCapital(newMessage); if (capitalizeTheWordI) diff --git a/Content.Server/Chemistry/EntitySystems/ChemistryGuideDataSystem.cs b/Content.Server/Chemistry/EntitySystems/ChemistryGuideDataSystem.cs index 7485c0e901..8cbdd82f07 100644 --- a/Content.Server/Chemistry/EntitySystems/ChemistryGuideDataSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/ChemistryGuideDataSystem.cs @@ -2,7 +2,6 @@ using Content.Shared.Chemistry.Reagent; using Robust.Server.Player; using Robust.Shared.Enums; -using Robust.Shared.Player; using Robust.Shared.Prototypes; namespace Content.Server.Chemistry.EntitySystems; diff --git a/Content.Server/Chunking/ChunkingSystem.cs b/Content.Server/Chunking/ChunkingSystem.cs index 6f44c43be8..4ef44d1678 100644 --- a/Content.Server/Chunking/ChunkingSystem.cs +++ b/Content.Server/Chunking/ChunkingSystem.cs @@ -1,12 +1,12 @@ using System.Linq; using Content.Shared.Decals; using Microsoft.Extensions.ObjectPool; +using Robust.Server.Player; using Robust.Shared; using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Map; using Robust.Shared.Map.Components; -using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Shared.Chunking; @@ -41,7 +41,7 @@ public sealed class ChunkingSystem : EntitySystem private void OnPvsRangeChanged(float value) => _baseViewBounds = Box2.UnitCentered.Scale(value); public Dictionary> GetChunksForSession( - ICommonSession session, + IPlayerSession session, int chunkSize, ObjectPool> indexPool, ObjectPool>> viewerPool, @@ -52,7 +52,7 @@ public sealed class ChunkingSystem : EntitySystem return chunks; } - private HashSet GetSessionViewers(ICommonSession session) + private HashSet GetSessionViewers(IPlayerSession session) { var viewers = new HashSet(); if (session.Status != SessionStatus.InGame || session.AttachedEntity is null) diff --git a/Content.Server/Commands/CommandUtils.cs b/Content.Server/Commands/CommandUtils.cs index 172f3324e3..11adaec9a2 100644 --- a/Content.Server/Commands/CommandUtils.cs +++ b/Content.Server/Commands/CommandUtils.cs @@ -3,7 +3,6 @@ using System.Globalization; using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Network; -using Robust.Shared.Player; namespace Content.Server.Commands { @@ -17,7 +16,7 @@ namespace Content.Server.Commands /// sending a failure to the performer if unable to. /// public static bool TryGetSessionByUsernameOrId(IConsoleShell shell, - string usernameOrId, ICommonSession performer, [NotNullWhen(true)] out ICommonSession? session) + string usernameOrId, IPlayerSession performer, [NotNullWhen(true)] out IPlayerSession? session) { var plyMgr = IoCManager.Resolve(); if (plyMgr.TryGetSessionByUsername(usernameOrId, out session)) return true; @@ -37,7 +36,7 @@ namespace Content.Server.Commands /// sending a failure to the performer if unable to. /// public static bool TryGetAttachedEntityByUsernameOrId(IConsoleShell shell, - string usernameOrId, ICommonSession performer, out EntityUid attachedEntity) + string usernameOrId, IPlayerSession performer, out EntityUid attachedEntity) { attachedEntity = default; if (!TryGetSessionByUsernameOrId(shell, usernameOrId, performer, out var session)) return false; @@ -68,7 +67,7 @@ namespace Content.Server.Commands transform.LocalPosition.Y.ToString(CultureInfo.InvariantCulture)); ruleString = ruleString.Replace("$NAME", entMan.GetComponent(ent).EntityName); - if (shell.Player is { } player) + if (shell.Player is IPlayerSession player) { if (player.AttachedEntity is {Valid: true} p) { diff --git a/Content.Server/Construction/Commands/FixRotationsCommand.cs b/Content.Server/Construction/Commands/FixRotationsCommand.cs index bdbfaf170d..d23fa0a31b 100644 --- a/Content.Server/Construction/Commands/FixRotationsCommand.cs +++ b/Content.Server/Construction/Commands/FixRotationsCommand.cs @@ -3,6 +3,7 @@ using Content.Server.Power.Components; using Content.Shared.Administration; using Content.Shared.Construction; using Content.Shared.Tag; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map.Components; @@ -20,7 +21,7 @@ namespace Content.Server.Construction.Commands public void Execute(IConsoleShell shell, string argsOther, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; EntityUid? gridId; var xformQuery = _entManager.GetEntityQuery(); diff --git a/Content.Server/Construction/Commands/TileReplaceCommand.cs b/Content.Server/Construction/Commands/TileReplaceCommand.cs index f63fd4c13e..ed1fba2424 100644 --- a/Content.Server/Construction/Commands/TileReplaceCommand.cs +++ b/Content.Server/Construction/Commands/TileReplaceCommand.cs @@ -1,5 +1,6 @@ using Content.Server.Administration; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; using Robust.Shared.Map.Components; @@ -19,7 +20,7 @@ sealed class TileReplaceCommand : IConsoleCommand public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; EntityUid? gridId; string tileIdA; string tileIdB; diff --git a/Content.Server/Construction/Commands/TileWallsCommand.cs b/Content.Server/Construction/Commands/TileWallsCommand.cs index 731d4da7f8..55389e41cc 100644 --- a/Content.Server/Construction/Commands/TileWallsCommand.cs +++ b/Content.Server/Construction/Commands/TileWallsCommand.cs @@ -2,9 +2,10 @@ using Content.Server.Administration; using Content.Shared.Administration; using Content.Shared.Maps; using Content.Shared.Tag; +using Robust.Server.GameObjects; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; -using Robust.Server.GameObjects; using Robust.Shared.Map.Components; namespace Content.Server.Construction.Commands @@ -28,7 +29,7 @@ namespace Content.Server.Construction.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; EntityUid? gridId; switch (args.Length) diff --git a/Content.Server/Construction/ConstructionSystem.Initial.cs b/Content.Server/Construction/ConstructionSystem.Initial.cs index 21978f2d0c..e74edb5da2 100644 --- a/Content.Server/Construction/ConstructionSystem.Initial.cs +++ b/Content.Server/Construction/ConstructionSystem.Initial.cs @@ -16,7 +16,7 @@ using Content.Shared.Interaction; using Content.Shared.Inventory; using Content.Shared.Storage; using Robust.Shared.Containers; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Timing; namespace Content.Server.Construction diff --git a/Content.Server/CrewManifest/CrewManifestSystem.cs b/Content.Server/CrewManifest/CrewManifestSystem.cs index 4c4f17f61d..aed0575324 100644 --- a/Content.Server/CrewManifest/CrewManifestSystem.cs +++ b/Content.Server/CrewManifest/CrewManifestSystem.cs @@ -10,9 +10,10 @@ using Content.Shared.CCVar; using Content.Shared.CrewManifest; using Content.Shared.GameTicking; using Content.Shared.StationRecords; +using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Console; -using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Server.CrewManifest; @@ -59,7 +60,7 @@ public sealed class CrewManifestSystem : EntitySystem private void OnRequestCrewManifest(RequestCrewManifestMessage message, EntitySessionEventArgs args) { - if (args.SenderSession is not { } sessionCast + if (args.SenderSession is not IPlayerSession sessionCast || !_configManager.GetCVar(CCVars.CrewManifestWithoutEntity)) { return; @@ -92,12 +93,12 @@ public sealed class CrewManifestSystem : EntitySystem private void OnBoundUiClose(EntityUid uid, CrewManifestViewerComponent component, BoundUIClosedEvent ev) { var owningStation = _stationSystem.GetOwningStation(uid); - if (owningStation == null || ev.Session is not { } session) + if (owningStation == null || ev.Session is not IPlayerSession sessionCast) { return; } - CloseEui(owningStation.Value, session, uid); + CloseEui(owningStation.Value, sessionCast, uid); } /// @@ -125,7 +126,7 @@ public sealed class CrewManifestSystem : EntitySystem private void OpenEuiFromBui(EntityUid uid, CrewManifestViewerComponent component, CrewManifestOpenUiMessage msg) { var owningStation = _stationSystem.GetOwningStation(uid); - if (owningStation == null || msg.Session is not { } session) + if (owningStation == null || msg.Session is not IPlayerSession sessionCast) { return; } @@ -135,7 +136,7 @@ public sealed class CrewManifestSystem : EntitySystem return; } - OpenEui(owningStation.Value, session, uid); + OpenEui(owningStation.Value, sessionCast, uid); } /// @@ -144,7 +145,7 @@ public sealed class CrewManifestSystem : EntitySystem /// Station that we're displaying the crew manifest for. /// The player's session. /// If this EUI should be 'owned' by an entity. - public void OpenEui(EntityUid station, ICommonSession session, EntityUid? owner = null) + public void OpenEui(EntityUid station, IPlayerSession session, EntityUid? owner = null) { if (!HasComp(station)) { @@ -251,7 +252,7 @@ public sealed class CrewManifestCommand : IConsoleCommand return; } - if (shell.Player == null || shell.Player is not { } session) + if (shell.Player == null || shell.Player is not IPlayerSession session) { shell.WriteLine("You must run this from a client."); return; diff --git a/Content.Server/Damage/Commands/GodModeCommand.cs b/Content.Server/Damage/Commands/GodModeCommand.cs index 866737f17a..92a0e53f0f 100644 --- a/Content.Server/Damage/Commands/GodModeCommand.cs +++ b/Content.Server/Damage/Commands/GodModeCommand.cs @@ -1,6 +1,8 @@ using Content.Server.Administration; +using Content.Server.Damage.Systems; using Content.Shared.Administration; using Content.Shared.Damage.Systems; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Damage.Commands @@ -16,7 +18,7 @@ namespace Content.Server.Damage.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; EntityUid entity; switch (args.Length) diff --git a/Content.Server/Damage/ForceSay/DamageForceSaySystem.cs b/Content.Server/Damage/ForceSay/DamageForceSaySystem.cs index 457fab4bb2..3d3346403a 100644 --- a/Content.Server/Damage/ForceSay/DamageForceSaySystem.cs +++ b/Content.Server/Damage/ForceSay/DamageForceSaySystem.cs @@ -6,6 +6,7 @@ using Content.Shared.Mobs.Systems; using Content.Shared.Stunnable; using Robust.Server.GameObjects; using Robust.Server.Player; +using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; diff --git a/Content.Server/Database/UserDbDataManager.cs b/Content.Server/Database/UserDbDataManager.cs index f8b1611fd5..f2c506240b 100644 --- a/Content.Server/Database/UserDbDataManager.cs +++ b/Content.Server/Database/UserDbDataManager.cs @@ -2,8 +2,8 @@ using System.Threading.Tasks; using Content.Server.Players.PlayTimeTracking; using Content.Server.Preferences.Managers; +using Robust.Server.Player; using Robust.Shared.Network; -using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Server.Database; @@ -25,7 +25,7 @@ public sealed class UserDbDataManager // TODO: Ideally connected/disconnected would be subscribed to IPlayerManager directly, // but this runs into ordering issues with game ticker. - public void ClientConnected(ICommonSession session) + public void ClientConnected(IPlayerSession session) { DebugTools.Assert(!_users.ContainsKey(session.UserId), "We should not have any cached data on client connect."); @@ -36,7 +36,7 @@ public sealed class UserDbDataManager _users.Add(session.UserId, data); } - public void ClientDisconnected(ICommonSession session) + public void ClientDisconnected(IPlayerSession session) { _users.Remove(session.UserId, out var data); if (data == null) @@ -49,24 +49,24 @@ public sealed class UserDbDataManager _playTimeTracking.ClientDisconnected(session); } - private async Task Load(ICommonSession session, CancellationToken cancel) + private async Task Load(IPlayerSession session, CancellationToken cancel) { await Task.WhenAll( _prefs.LoadData(session, cancel), _playTimeTracking.LoadData(session, cancel)); } - public Task WaitLoadComplete(ICommonSession session) + public Task WaitLoadComplete(IPlayerSession session) { return _users[session.UserId].Task; } - public bool IsLoadComplete(ICommonSession session) + public bool IsLoadComplete(IPlayerSession session) { return GetLoadTask(session).IsCompleted; } - public Task GetLoadTask(ICommonSession session) + public Task GetLoadTask(IPlayerSession session) { return _users[session.UserId].Task; } diff --git a/Content.Server/Decals/DecalSystem.cs b/Content.Server/Decals/DecalSystem.cs index ce2e0711e7..ed281e05ba 100644 --- a/Content.Server/Decals/DecalSystem.cs +++ b/Content.Server/Decals/DecalSystem.cs @@ -16,7 +16,6 @@ using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Map; using Robust.Shared.Map.Components; -using Robust.Shared.Player; using Robust.Shared.Threading; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -37,7 +36,7 @@ namespace Content.Server.Decals [Dependency] private readonly MapSystem _mapSystem = default!; private readonly Dictionary> _dirtyChunks = new(); - private readonly Dictionary>> _previousSentChunks = new(); + private readonly Dictionary>> _previousSentChunks = new(); private static readonly Vector2 _boundsMinExpansion = new(0.01f, 0.01f); private static readonly Vector2 _boundsMaxExpansion = new(1.01f, 1.01f); @@ -198,7 +197,7 @@ namespace Content.Server.Decals private void OnDecalPlacementRequest(RequestDecalPlacementEvent ev, EntitySessionEventArgs eventArgs) { - if (eventArgs.SenderSession is not { } session) + if (eventArgs.SenderSession is not IPlayerSession session) return; // bad @@ -227,7 +226,7 @@ namespace Content.Server.Decals private void OnDecalRemovalRequest(RequestDecalRemovalEvent ev, EntitySessionEventArgs eventArgs) { - if (eventArgs.SenderSession is not { } session) + if (eventArgs.SenderSession is not IPlayerSession session) return; // bad @@ -428,7 +427,7 @@ namespace Content.Server.Decals if (PvsEnabled) { - var players = _playerManager.Sessions.Where(x => x.Status == SessionStatus.InGame).ToArray(); + var players = _playerManager.ServerSessions.Where(x => x.Status == SessionStatus.InGame).ToArray(); var opts = new ParallelOptions { MaxDegreeOfParallelism = _parMan.ParallelProcessCount }; Parallel.ForEach(players, opts, UpdatePlayer); } @@ -436,7 +435,7 @@ namespace Content.Server.Decals _dirtyChunks.Clear(); } - public void UpdatePlayer(ICommonSession player) + public void UpdatePlayer(IPlayerSession player) { var chunksInRange = _chunking.GetChunksForSession(player, ChunkSize, _chunkIndexPool, _chunkViewerPool); var staleChunks = _chunkViewerPool.Get(); @@ -531,7 +530,7 @@ namespace Content.Server.Decals } private void SendChunkUpdates( - ICommonSession session, + IPlayerSession session, Dictionary> updatedChunks, Dictionary> staleChunks) { diff --git a/Content.Server/Disposal/TubeConnectionsCommand.cs b/Content.Server/Disposal/TubeConnectionsCommand.cs index 55e6465937..7895dcbca6 100644 --- a/Content.Server/Disposal/TubeConnectionsCommand.cs +++ b/Content.Server/Disposal/TubeConnectionsCommand.cs @@ -2,6 +2,7 @@ using Content.Server.Administration; using Content.Server.Disposal.Tube; using Content.Server.Disposal.Tube.Components; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Disposal @@ -17,7 +18,7 @@ namespace Content.Server.Disposal public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player?.AttachedEntity == null) { shell.WriteLine(Loc.GetString("shell-only-players-can-run-this-command")); diff --git a/Content.Server/EUI/BaseEui.cs b/Content.Server/EUI/BaseEui.cs index 70cbfc3775..4a41ad40a5 100644 --- a/Content.Server/EUI/BaseEui.cs +++ b/Content.Server/EUI/BaseEui.cs @@ -1,6 +1,6 @@ using Content.Shared.Eui; using Robust.Shared.Network; -using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Server.EUI { diff --git a/Content.Server/EUI/EuiManager.cs b/Content.Server/EUI/EuiManager.cs index fe8e486b68..4d99719525 100644 --- a/Content.Server/EUI/EuiManager.cs +++ b/Content.Server/EUI/EuiManager.cs @@ -2,7 +2,7 @@ using Robust.Server.Player; using Robust.Shared.Enums; using Robust.Shared.Network; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Utility; namespace Content.Server.EUI diff --git a/Content.Server/EntityList/SpawnEntityListCommand.cs b/Content.Server/EntityList/SpawnEntityListCommand.cs index 027d25dc2c..0891bbd12a 100644 --- a/Content.Server/EntityList/SpawnEntityListCommand.cs +++ b/Content.Server/EntityList/SpawnEntityListCommand.cs @@ -1,6 +1,7 @@ using Content.Server.Administration; using Content.Shared.Administration; using Content.Shared.EntityList; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Prototypes; @@ -21,7 +22,7 @@ namespace Content.Server.EntityList return; } - if (shell.Player is not { } player) + if (shell.Player is not IPlayerSession player) { shell.WriteError("You must be a player to run this command."); return; diff --git a/Content.Server/Examine/ExamineSystem.cs b/Content.Server/Examine/ExamineSystem.cs index 3447810896..98aa806885 100644 --- a/Content.Server/Examine/ExamineSystem.cs +++ b/Content.Server/Examine/ExamineSystem.cs @@ -4,6 +4,7 @@ using Content.Shared.Examine; using Content.Shared.Verbs; using JetBrains.Annotations; using Robust.Server.GameObjects; +using Robust.Server.Player; using Robust.Shared.Utility; namespace Content.Server.Examine @@ -45,7 +46,7 @@ namespace Content.Server.Examine private void ExamineInfoRequest(ExamineSystemMessages.RequestExamineInfoMessage request, EntitySessionEventArgs eventArgs) { - var player = eventArgs.SenderSession; + var player = (IPlayerSession) eventArgs.SenderSession; var session = eventArgs.SenderSession; var channel = player.ConnectedClient; var entity = GetEntity(request.NetEntity); diff --git a/Content.Server/Fluids/EntitySystems/PuddleDebugDebugOverlaySystem.cs b/Content.Server/Fluids/EntitySystems/PuddleDebugDebugOverlaySystem.cs index c17eea684d..59f0a13695 100644 --- a/Content.Server/Fluids/EntitySystems/PuddleDebugDebugOverlaySystem.cs +++ b/Content.Server/Fluids/EntitySystems/PuddleDebugDebugOverlaySystem.cs @@ -1,9 +1,9 @@ using System.Numerics; using Content.Shared.Fluids; using Content.Shared.Fluids.Components; +using Robust.Server.Player; using Robust.Shared.Map; using Robust.Shared.Map.Components; -using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.Fluids.EntitySystems; @@ -14,10 +14,10 @@ public sealed class PuddleDebugDebugOverlaySystem : SharedPuddleDebugOverlaySyst [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly PuddleSystem _puddle = default!; - private readonly HashSet _playerObservers = new(); + private readonly HashSet _playerObservers = new(); private List> _grids = new(); - public bool ToggleObserver(ICommonSession observer) + public bool ToggleObserver(IPlayerSession observer) { NextTick ??= _timing.CurTime + Cooldown; @@ -31,7 +31,7 @@ public sealed class PuddleDebugDebugOverlaySystem : SharedPuddleDebugOverlaySyst return true; } - private void RemoveObserver(ICommonSession observer) + private void RemoveObserver(IPlayerSession observer) { if (!_playerObservers.Remove(observer)) { diff --git a/Content.Server/Fluids/ShowFluidsCommand.cs b/Content.Server/Fluids/ShowFluidsCommand.cs index 71ac273a45..f122eadea7 100644 --- a/Content.Server/Fluids/ShowFluidsCommand.cs +++ b/Content.Server/Fluids/ShowFluidsCommand.cs @@ -1,6 +1,7 @@ using Content.Server.Administration; using Content.Server.Fluids.EntitySystems; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Fluids; @@ -14,7 +15,7 @@ public sealed class ShowFluidsCommand : IConsoleCommand public string Help => $"Usage: {Command}"; public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player == null) { shell.WriteLine("You must be a player to use this command."); diff --git a/Content.Server/GameTicking/Commands/JoinGameCommand.cs b/Content.Server/GameTicking/Commands/JoinGameCommand.cs index 3276b91200..366e6c4e77 100644 --- a/Content.Server/GameTicking/Commands/JoinGameCommand.cs +++ b/Content.Server/GameTicking/Commands/JoinGameCommand.cs @@ -2,6 +2,7 @@ using Content.Server.Station.Systems; using Content.Shared.Administration; using Content.Shared.GameTicking; using Content.Shared.Roles; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Prototypes; @@ -29,7 +30,7 @@ namespace Content.Server.GameTicking.Commands return; } - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player == null) { diff --git a/Content.Server/GameTicking/Commands/ObserveCommand.cs b/Content.Server/GameTicking/Commands/ObserveCommand.cs index 747e54e28b..d608dda9c1 100644 --- a/Content.Server/GameTicking/Commands/ObserveCommand.cs +++ b/Content.Server/GameTicking/Commands/ObserveCommand.cs @@ -1,5 +1,6 @@ using Content.Shared.Administration; using Content.Shared.GameTicking; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.GameTicking.Commands @@ -13,7 +14,7 @@ namespace Content.Server.GameTicking.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not { } player) + if (shell.Player is not IPlayerSession player) { return; } diff --git a/Content.Server/GameTicking/Commands/RespawnCommand.cs b/Content.Server/GameTicking/Commands/RespawnCommand.cs index 4f101d0939..057572297f 100644 --- a/Content.Server/GameTicking/Commands/RespawnCommand.cs +++ b/Content.Server/GameTicking/Commands/RespawnCommand.cs @@ -14,7 +14,7 @@ namespace Content.Server.GameTicking.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (args.Length > 1) { shell.WriteLine("Must provide <= 1 argument."); diff --git a/Content.Server/GameTicking/Commands/ToggleReadyCommand.cs b/Content.Server/GameTicking/Commands/ToggleReadyCommand.cs index df418c27ee..e68c4c5fa7 100644 --- a/Content.Server/GameTicking/Commands/ToggleReadyCommand.cs +++ b/Content.Server/GameTicking/Commands/ToggleReadyCommand.cs @@ -1,4 +1,5 @@ using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.GameTicking.Commands @@ -12,7 +13,7 @@ namespace Content.Server.GameTicking.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (args.Length != 1) { shell.WriteError(Loc.GetString("shell-wrong-arguments-number")); diff --git a/Content.Server/GameTicking/GameTicker.GamePreset.cs b/Content.Server/GameTicking/GameTicker.GamePreset.cs index 2d7539bd0f..a5e6d7a605 100644 --- a/Content.Server/GameTicking/GameTicker.GamePreset.cs +++ b/Content.Server/GameTicking/GameTicker.GamePreset.cs @@ -11,7 +11,7 @@ using Content.Shared.Ghost; using Content.Shared.Mind; using Content.Shared.Mobs.Components; using JetBrains.Annotations; -using Robust.Shared.Player; +using Robust.Server.Player; namespace Content.Server.GameTicking { @@ -29,7 +29,7 @@ namespace Content.Server.GameTicking /// public GamePresetPrototype? CurrentPreset { get; private set; } - private bool StartPreset(ICommonSession[] origReadyPlayers, bool force) + private bool StartPreset(IPlayerSession[] origReadyPlayers, bool force) { var startAttempt = new RoundStartAttemptEvent(origReadyPlayers, force); RaiseLocalEvent(startAttempt); @@ -214,7 +214,7 @@ namespace Content.Server.GameTicking { if (mind.Session != null) // Logging is suppressed to prevent spam from ghost attempts caused by movement attempts { - _chatManager.DispatchServerMessage(mind.Session, Loc.GetString("comp-mind-ghosting-prevented"), + _chatManager.DispatchServerMessage((IPlayerSession) mind.Session, Loc.GetString("comp-mind-ghosting-prevented"), true); } diff --git a/Content.Server/GameTicking/GameTicker.Lobby.cs b/Content.Server/GameTicking/GameTicker.Lobby.cs index 1943a82617..b7b6a29a5a 100644 --- a/Content.Server/GameTicking/GameTicker.Lobby.cs +++ b/Content.Server/GameTicking/GameTicker.Lobby.cs @@ -1,8 +1,10 @@ using System.Linq; using Content.Shared.GameTicking; using Content.Server.Station.Components; +using Robust.Server.Player; using Robust.Shared.Network; using Robust.Shared.Player; +using Robust.Shared.Players; using System.Text; namespace Content.Server.GameTicking @@ -77,7 +79,7 @@ namespace Content.Server.GameTicking ("roundId", RoundId), ("playerCount", playerCount), ("readyCount", readyCount), ("mapName", stationNames.ToString()),("gmTitle", gmTitle),("desc", desc)); } - private TickerLobbyStatusEvent GetStatusMsg(ICommonSession session) + private TickerLobbyStatusEvent GetStatusMsg(IPlayerSession session) { _playerGameStatuses.TryGetValue(session.UserId, out var status); return new TickerLobbyStatusEvent(RunLevel != GameRunLevel.PreRoundLobby, LobbySong, LobbyBackground,status == PlayerGameStatus.ReadyToPlay, _roundStartTime, RoundPreloadTime, _roundStartTimeSpan, Paused); @@ -85,7 +87,7 @@ namespace Content.Server.GameTicking private void SendStatusToAll() { - foreach (var player in _playerManager.Sessions) + foreach (var player in _playerManager.ServerSessions) { RaiseNetworkEvent(GetStatusMsg(player), player.ConnectedClient); } @@ -146,7 +148,7 @@ namespace Content.Server.GameTicking } } - public void ToggleReady(ICommonSession player, bool ready) + public void ToggleReady(IPlayerSession player, bool ready) { if (!_playerGameStatuses.ContainsKey(player.UserId)) return; diff --git a/Content.Server/GameTicking/GameTicker.Player.cs b/Content.Server/GameTicking/GameTicker.Player.cs index 334af3f4fd..3aef1bbe78 100644 --- a/Content.Server/GameTicking/GameTicker.Player.cs +++ b/Content.Server/GameTicking/GameTicker.Player.cs @@ -1,4 +1,5 @@ using Content.Server.Database; +using Content.Server.Players; using Content.Shared.GameTicking; using Content.Shared.GameWindow; using Content.Shared.Players; @@ -6,7 +7,6 @@ using Content.Shared.Preferences; using JetBrains.Annotations; using Robust.Server.Player; using Robust.Shared.Enums; -using Robust.Shared.Player; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -49,14 +49,14 @@ namespace Content.Server.GameTicking // Always make sure the client has player data. if (session.Data.ContentDataUncast == null) { - var data = new ContentPlayerData(session.UserId, args.Session.Name); + var data = new PlayerData(session.UserId, args.Session.Name); data.Mind = mindId; session.Data.ContentDataUncast = data; } // Make the player actually join the game. // timer time must be > tick length - Timer.Spawn(0, () => _playerManager.JoinGame(args.Session)); + Timer.Spawn(0, args.Session.JoinGame); var record = await _dbManager.GetPlayerRecordByUserId(args.Session.UserId); var firstConnection = record != null && @@ -100,7 +100,8 @@ namespace Content.Server.GameTicking } else { - _playerManager.SetAttachedEntity(session, mind.CurrentEntity); + // Simply re-attach to existing entity. + session.AttachToEntity(mind.CurrentEntity); PlayerJoinGame(session); } @@ -145,12 +146,12 @@ namespace Content.Server.GameTicking } } - private HumanoidCharacterProfile GetPlayerProfile(ICommonSession p) + private HumanoidCharacterProfile GetPlayerProfile(IPlayerSession p) { return (HumanoidCharacterProfile) _prefsManager.GetPreferences(p.UserId).SelectedCharacter; } - public void PlayerJoinGame(ICommonSession session, bool silent = false) + public void PlayerJoinGame(IPlayerSession session, bool silent = false) { if (!silent) _chatManager.DispatchServerMessage(session, Loc.GetString("game-ticker-player-join-game-message")); @@ -161,7 +162,7 @@ namespace Content.Server.GameTicking RaiseNetworkEvent(new TickerJoinGameEvent(), session.ConnectedClient); } - private void PlayerJoinLobby(ICommonSession session) + private void PlayerJoinLobby(IPlayerSession session) { _playerGameStatuses[session.UserId] = LobbyEnabled ? PlayerGameStatus.NotReadyToPlay : PlayerGameStatus.ReadyToPlay; _db.AddRoundPlayers(RoundId, session.UserId); @@ -181,9 +182,9 @@ namespace Content.Server.GameTicking public sealed class PlayerJoinedLobbyEvent : EntityEventArgs { - public readonly ICommonSession PlayerSession; + public readonly IPlayerSession PlayerSession; - public PlayerJoinedLobbyEvent(ICommonSession playerSession) + public PlayerJoinedLobbyEvent(IPlayerSession playerSession) { PlayerSession = playerSession; } diff --git a/Content.Server/GameTicking/GameTicker.RoundFlow.cs b/Content.Server/GameTicking/GameTicker.RoundFlow.cs index 85f833bd1c..df2aafa901 100644 --- a/Content.Server/GameTicking/GameTicker.RoundFlow.cs +++ b/Content.Server/GameTicking/GameTicker.RoundFlow.cs @@ -12,6 +12,7 @@ using Content.Shared.Preferences; using JetBrains.Annotations; using Prometheus; using Robust.Server.Maps; +using Robust.Server.Player; using Robust.Shared.Asynchronous; using Robust.Shared.Audio; using Robust.Shared.Map; @@ -204,7 +205,7 @@ namespace Content.Server.GameTicking var startingEvent = new RoundStartingEvent(RoundId); RaiseLocalEvent(startingEvent); - var readyPlayers = new List(); + var readyPlayers = new List(); var readyPlayerProfiles = new Dictionary(); foreach (var (userId, status) in _playerGameStatuses) @@ -343,7 +344,7 @@ namespace Content.Server.GameTicking { connected = true; } - ContentPlayerData? contentPlayerData = null; + PlayerData? contentPlayerData = null; if (userId != null && _playerManager.TryGetPlayerData(userId.Value, out var playerData)) { contentPlayerData = playerData.ContentData(); @@ -359,7 +360,8 @@ namespace Content.Server.GameTicking else if (mind.CurrentEntity != null && TryName(mind.CurrentEntity.Value, out var icName)) playerIcName = icName; - if (TryGetEntity(mind.OriginalOwnedEntity, out var entity)) + var entity = mind.OriginalOwnedEntity; + if (Exists(entity)) _pvsOverride.AddGlobalOverride(entity.Value, recursive: true); var roles = _roles.MindGetAllRoles(mindId); @@ -492,7 +494,7 @@ namespace Content.Server.GameTicking private void ResettingCleanup() { // Move everybody currently in the server to lobby. - foreach (var player in _playerManager.Sessions) + foreach (var player in _playerManager.ServerSessions) { PlayerJoinLobby(player); } @@ -540,7 +542,7 @@ namespace Content.Server.GameTicking DisallowLateJoin = false; _playerGameStatuses.Clear(); - foreach (var session in _playerManager.Sessions) + foreach (var session in _playerManager.ServerSessions) { _playerGameStatuses[session.UserId] = LobbyEnabled ? PlayerGameStatus.NotReadyToPlay : PlayerGameStatus.ReadyToPlay; } @@ -734,10 +736,10 @@ namespace Content.Server.GameTicking /// public sealed class RoundStartAttemptEvent : CancellableEntityEventArgs { - public ICommonSession[] Players { get; } + public IPlayerSession[] Players { get; } public bool Forced { get; } - public RoundStartAttemptEvent(ICommonSession[] players, bool forced) + public RoundStartAttemptEvent(IPlayerSession[] players, bool forced) { Players = players; Forced = forced; @@ -756,11 +758,11 @@ namespace Content.Server.GameTicking /// If you want to handle a specific player being spawned, remove it from this list and do what you need. /// /// If you spawn a player by yourself from this event, don't forget to call on them. - public List PlayerPool { get; } + public List PlayerPool { get; } public IReadOnlyDictionary Profiles { get; } public bool Forced { get; } - public RulePlayerSpawningEvent(List playerPool, IReadOnlyDictionary profiles, bool forced) + public RulePlayerSpawningEvent(List playerPool, IReadOnlyDictionary profiles, bool forced) { PlayerPool = playerPool; Profiles = profiles; @@ -774,11 +776,11 @@ namespace Content.Server.GameTicking /// public sealed class RulePlayerJobsAssignedEvent { - public ICommonSession[] Players { get; } + public IPlayerSession[] Players { get; } public IReadOnlyDictionary Profiles { get; } public bool Forced { get; } - public RulePlayerJobsAssignedEvent(ICommonSession[] players, IReadOnlyDictionary profiles, bool forced) + public RulePlayerJobsAssignedEvent(IPlayerSession[] players, IReadOnlyDictionary profiles, bool forced) { Players = players; Profiles = profiles; diff --git a/Content.Server/GameTicking/GameTicker.Spawning.cs b/Content.Server/GameTicking/GameTicker.Spawning.cs index c2bf523657..0c59f93bb0 100644 --- a/Content.Server/GameTicking/GameTicker.Spawning.cs +++ b/Content.Server/GameTicking/GameTicker.Spawning.cs @@ -3,20 +3,20 @@ using System.Linq; using System.Numerics; using Content.Server.Administration.Managers; using Content.Server.Ghost; +using Content.Server.Players; using Content.Server.Spawners.Components; using Content.Server.Speech.Components; using Content.Server.Station.Components; using Content.Shared.CCVar; using Content.Shared.Database; -using Content.Shared.Players; using Content.Shared.Preferences; using Content.Shared.Roles; using Content.Shared.Roles.Jobs; using JetBrains.Annotations; +using Robust.Server.Player; using Robust.Shared.Map; using Robust.Shared.Map.Components; using Robust.Shared.Network; -using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Utility; @@ -29,7 +29,7 @@ namespace Content.Server.GameTicking [Dependency] private readonly SharedJobSystem _jobs = default!; [ValidatePrototypeId] - public const string ObserverPrototypeName = "MobObserver"; + private const string ObserverPrototypeName = "MobObserver"; /// /// How many players have joined the round through normal methods. @@ -52,7 +52,7 @@ namespace Content.Server.GameTicking return spawnableStations; } - private void SpawnPlayers(List readyPlayers, Dictionary profiles, bool force) + private void SpawnPlayers(List readyPlayers, Dictionary profiles, bool force) { // Allow game rules to spawn players by themselves if needed. (For example, nuke ops or wizard) RaiseLocalEvent(new RulePlayerSpawningEvent(readyPlayers, profiles, force)); @@ -116,7 +116,7 @@ namespace Content.Server.GameTicking RaiseLocalEvent(new RulePlayerJobsAssignedEvent(assignedJobs.Keys.Select(x => _playerManager.GetSessionByUserId(x)).ToArray(), profiles, force)); } - private void SpawnPlayer(ICommonSession player, EntityUid station, string? jobId = null, bool lateJoin = true, bool silent = false) + private void SpawnPlayer(IPlayerSession player, EntityUid station, string? jobId = null, bool lateJoin = true, bool silent = false) { var character = GetPlayerProfile(player); @@ -129,7 +129,7 @@ namespace Content.Server.GameTicking SpawnPlayer(player, character, station, jobId, lateJoin, silent); } - private void SpawnPlayer(ICommonSession player, HumanoidCharacterProfile character, EntityUid station, string? jobId = null, bool lateJoin = true, bool silent = false) + private void SpawnPlayer(IPlayerSession player, HumanoidCharacterProfile character, EntityUid station, string? jobId = null, bool lateJoin = true, bool silent = false) { // Can't spawn players with a dummy ticker! if (DummyTicker) @@ -271,7 +271,7 @@ namespace Content.Server.GameTicking RaiseLocalEvent(mob, aev, true); } - public void Respawn(ICommonSession player) + public void Respawn(IPlayerSession player) { _mind.WipeMind(player); _adminLogger.Add(LogType.Respawn, LogImpact.Medium, $"Player {player} was respawned."); @@ -289,7 +289,7 @@ namespace Content.Server.GameTicking /// The station they're spawning on /// An optional job for them to spawn as /// Whether or not the player should be greeted upon joining - public void MakeJoinGame(ICommonSession player, EntityUid station, string? jobId = null, bool silent = false) + public void MakeJoinGame(IPlayerSession player, EntityUid station, string? jobId = null, bool silent = false) { if (!_playerGameStatuses.ContainsKey(player.UserId)) return; @@ -303,7 +303,7 @@ namespace Content.Server.GameTicking /// /// Causes the given player to join the current game as observer ghost. See also /// - public void JoinAsObserver(ICommonSession player) + public void JoinAsObserver(IPlayerSession player) { // Can't spawn players with a dummy ticker! if (DummyTicker) @@ -317,7 +317,7 @@ namespace Content.Server.GameTicking /// Spawns an observer ghost and attaches the given player to it. If the player does not yet have a mind, the /// player is given a new mind with the observer role. Otherwise, the current mind is transferred to the ghost. /// - public void SpawnObserver(ICommonSession player) + public void SpawnObserver(IPlayerSession player) { if (DummyTicker) return; @@ -430,13 +430,13 @@ namespace Content.Server.GameTicking [PublicAPI] public sealed class PlayerBeforeSpawnEvent : HandledEntityEventArgs { - public ICommonSession Player { get; } + public IPlayerSession Player { get; } public HumanoidCharacterProfile Profile { get; } public string? JobId { get; } public bool LateJoin { get; } public EntityUid Station { get; } - public PlayerBeforeSpawnEvent(ICommonSession player, HumanoidCharacterProfile profile, string? jobId, bool lateJoin, EntityUid station) + public PlayerBeforeSpawnEvent(IPlayerSession player, HumanoidCharacterProfile profile, string? jobId, bool lateJoin, EntityUid station) { Player = player; Profile = profile; @@ -455,7 +455,7 @@ namespace Content.Server.GameTicking public sealed class PlayerSpawnCompleteEvent : EntityEventArgs { public EntityUid Mob { get; } - public ICommonSession Player { get; } + public IPlayerSession Player { get; } public string? JobId { get; } public bool LateJoin { get; } public EntityUid Station { get; } @@ -464,7 +464,7 @@ namespace Content.Server.GameTicking // Ex. If this is the 27th person to join, this will be 27. public int JoinOrder { get; } - public PlayerSpawnCompleteEvent(EntityUid mob, ICommonSession player, string? jobId, bool lateJoin, int joinOrder, EntityUid station, HumanoidCharacterProfile profile) + public PlayerSpawnCompleteEvent(EntityUid mob, IPlayerSession player, string? jobId, bool lateJoin, int joinOrder, EntityUid station, HumanoidCharacterProfile profile) { Mob = mob; Player = player; diff --git a/Content.Server/GameTicking/Rules/Components/TraitorRuleComponent.cs b/Content.Server/GameTicking/Rules/Components/TraitorRuleComponent.cs index 7af87179d6..883abef52f 100644 --- a/Content.Server/GameTicking/Rules/Components/TraitorRuleComponent.cs +++ b/Content.Server/GameTicking/Rules/Components/TraitorRuleComponent.cs @@ -1,7 +1,7 @@ using Content.Shared.Preferences; using Content.Shared.Roles; +using Robust.Server.Player; using Robust.Shared.Audio; -using Robust.Shared.Player; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Server.GameTicking.Rules.Components; @@ -26,7 +26,7 @@ public sealed partial class TraitorRuleComponent : Component public SelectionState SelectionStatus = SelectionState.WaitingForSpawn; public TimeSpan AnnounceAt = TimeSpan.Zero; - public Dictionary StartCandidates = new(); + public Dictionary StartCandidates = new(); /// /// Path to antagonist alert sound. diff --git a/Content.Server/GameTicking/Rules/InactivityTimeRestartRuleSystem.cs b/Content.Server/GameTicking/Rules/InactivityTimeRestartRuleSystem.cs index b775b7af56..c2e91ba4a5 100644 --- a/Content.Server/GameTicking/Rules/InactivityTimeRestartRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/InactivityTimeRestartRuleSystem.cs @@ -2,7 +2,6 @@ using System.Threading; using Content.Server.Chat.Managers; using Content.Server.GameTicking.Rules.Components; using Robust.Server.Player; -using Robust.Shared.Player; using Timer = Robust.Shared.Timing.Timer; namespace Content.Server.GameTicking.Rules; diff --git a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs index 4d3eee81e2..13d4ed71c8 100644 --- a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs @@ -602,11 +602,11 @@ public sealed class NukeopsRuleSystem : GameRuleSystem var maxOperatives = nukeops.MaxOps; // Dear lord what is happening HERE. - var everyone = new List(ev.PlayerPool); - var prefList = new List(); - var medPrefList = new List(); - var cmdrPrefList = new List(); - var operatives = new List(); + var everyone = new List(ev.PlayerPool); + var prefList = new List(); + var medPrefList = new List(); + var cmdrPrefList = new List(); + var operatives = new List(); // The LINQ expression ReSharper keeps suggesting is completely unintelligible so I'm disabling it // ReSharper disable once ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator @@ -637,7 +637,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem for (var i = 0; i < numNukies; i++) { // TODO: Please fix this if you touch it. - ICommonSession nukeOp; + IPlayerSession nukeOp; // Only one commander, so we do it at the start if (i == 0) { @@ -908,7 +908,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem _npcFaction.AddFaction(mob, "Syndicate"); } - private void SpawnOperatives(int spawnCount, List sessions, bool addSpawnPoints, NukeopsRuleComponent component) + private void SpawnOperatives(int spawnCount, List sessions, bool addSpawnPoints, NukeopsRuleComponent component) { if (component.NukieOutpost == null) return; @@ -987,10 +987,10 @@ public sealed class NukeopsRuleSystem : GameRuleSystem var playersPerOperative = component.PlayersPerOperative; var maxOperatives = component.MaxOps; - var playerPool = _playerManager.Sessions.ToList(); + var playerPool = _playerManager.ServerSessions.ToList(); var numNukies = MathHelper.Clamp(playerPool.Count / playersPerOperative, 1, maxOperatives); - var operatives = new List(); + var operatives = new List(); SpawnOperatives(numNukies, operatives, true, component); } diff --git a/Content.Server/GameTicking/Rules/PiratesRuleSystem.cs b/Content.Server/GameTicking/Rules/PiratesRuleSystem.cs index 0785d81d09..b223161c10 100644 --- a/Content.Server/GameTicking/Rules/PiratesRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/PiratesRuleSystem.cs @@ -15,10 +15,10 @@ using Content.Shared.Preferences; using Content.Shared.Roles; using Robust.Server.GameObjects; using Robust.Server.Maps; +using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Map; -using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Utility; @@ -141,7 +141,7 @@ public sealed class PiratesRuleSystem : GameRuleSystem (int) Math.Min( Math.Floor((double) ev.PlayerPool.Count / _cfg.GetCVar(CCVars.PiratesPlayersPerOp)), _cfg.GetCVar(CCVars.PiratesMaxOps))); - var ops = new ICommonSession[numOps]; + var ops = new IPlayerSession[numOps]; for (var i = 0; i < numOps; i++) { ops[i] = _random.PickAndTake(ev.PlayerPool); diff --git a/Content.Server/GameTicking/Rules/RespawnRuleSystem.cs b/Content.Server/GameTicking/Rules/RespawnRuleSystem.cs index 738883fff3..a286808623 100644 --- a/Content.Server/GameTicking/Rules/RespawnRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/RespawnRuleSystem.cs @@ -6,7 +6,6 @@ using Content.Shared.Chat; using Content.Shared.Interaction.Events; using Content.Shared.Mind; using Content.Shared.Mobs; -using Content.Shared.Players; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Network; diff --git a/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs b/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs index ef949d09fc..01317dbfc1 100644 --- a/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs @@ -17,8 +17,9 @@ using Content.Shared.PDA; using Content.Shared.Preferences; using Content.Shared.Roles; using Content.Shared.Roles.Jobs; +using Robust.Server.Player; using Robust.Shared.Configuration; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -150,9 +151,9 @@ public sealed class TraitorRuleSystem : GameRuleSystem } } - private List FindPotentialTraitors(in Dictionary candidates, TraitorRuleComponent component) + private List FindPotentialTraitors(in Dictionary candidates, TraitorRuleComponent component) { - var list = new List(); + var list = new List(); var pendingQuery = GetEntityQuery(); foreach (var player in candidates.Keys) @@ -170,7 +171,7 @@ public sealed class TraitorRuleSystem : GameRuleSystem list.Add(player); } - var prefList = new List(); + var prefList = new List(); foreach (var player in list) { @@ -188,9 +189,9 @@ public sealed class TraitorRuleSystem : GameRuleSystem return prefList; } - private List PickTraitors(int traitorCount, List prefList) + private List PickTraitors(int traitorCount, List prefList) { - var results = new List(traitorCount); + var results = new List(traitorCount); if (prefList.Count == 0) { Log.Info("Insufficient ready players to fill up with traitors, stopping the selection."); diff --git a/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs b/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs index a4febc385c..82ae4b8fa6 100644 --- a/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs @@ -23,7 +23,7 @@ using Content.Shared.Zombies; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Configuration; -using Robust.Shared.Player; +using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -264,9 +264,9 @@ public sealed class ZombieRuleSystem : GameRuleSystem return; component.InfectedChosen = true; - var allPlayers = _playerManager.Sessions.ToList(); - var playerList = new List(); - var prefList = new List(); + var allPlayers = _playerManager.ServerSessions.ToList(); + var playerList = new List(); + var prefList = new List(); foreach (var player in allPlayers) { if (player.AttachedEntity == null || !HasComp(player.AttachedEntity) || HasComp(player.AttachedEntity)) @@ -288,7 +288,7 @@ public sealed class ZombieRuleSystem : GameRuleSystem var totalInfected = 0; while (totalInfected < numInfected) { - ICommonSession zombie; + IPlayerSession zombie; if (prefList.Count == 0) { if (playerList.Count == 0) diff --git a/Content.Server/Ghost/Ghost.cs b/Content.Server/Ghost/Ghost.cs index 1453bf3faa..d04b1197af 100644 --- a/Content.Server/Ghost/Ghost.cs +++ b/Content.Server/Ghost/Ghost.cs @@ -1,6 +1,7 @@ using Content.Server.GameTicking; using Content.Shared.Administration; using Content.Shared.Mind; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Ghost @@ -16,7 +17,7 @@ namespace Content.Server.Ghost public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player == null) { shell.WriteLine("You have no session, you can't ghost."); diff --git a/Content.Server/Ghost/Roles/Components/TakeGhostRoleEvent.cs b/Content.Server/Ghost/Roles/Components/TakeGhostRoleEvent.cs index 16d46871fe..c97e3be9dc 100644 --- a/Content.Server/Ghost/Roles/Components/TakeGhostRoleEvent.cs +++ b/Content.Server/Ghost/Roles/Components/TakeGhostRoleEvent.cs @@ -1,4 +1,4 @@ -using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Server.Ghost.Roles.Components; diff --git a/Content.Server/Ghost/Roles/GhostRoleSystem.cs b/Content.Server/Ghost/Roles/GhostRoleSystem.cs index f372cb4f62..5a4cc176f2 100644 --- a/Content.Server/Ghost/Roles/GhostRoleSystem.cs +++ b/Content.Server/Ghost/Roles/GhostRoleSystem.cs @@ -4,6 +4,7 @@ using Content.Server.Ghost.Roles.Components; using Content.Server.Ghost.Roles.Events; using Content.Server.Ghost.Roles.UI; using Content.Server.Mind.Commands; +using Content.Server.Players; using Content.Shared.Administration; using Content.Shared.Database; using Content.Shared.Follower; @@ -13,14 +14,13 @@ using Content.Shared.Ghost.Roles; using Content.Shared.Mind; using Content.Shared.Mind.Components; using Content.Shared.Mobs; -using Content.Shared.Players; using Content.Shared.Roles; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Random; using Robust.Shared.Utility; @@ -97,7 +97,7 @@ namespace Content.Server.Ghost.Roles return unchecked(_nextRoleIdentifier++); } - public void OpenEui(ICommonSession session) + public void OpenEui(IPlayerSession session) { if (session.AttachedEntity is not {Valid: true} attached || !EntityManager.HasComponent(attached)) @@ -111,7 +111,7 @@ namespace Content.Server.Ghost.Roles eui.StateDirty(); } - public void OpenMakeGhostRoleEui(ICommonSession session, EntityUid uid) + public void OpenMakeGhostRoleEui(IPlayerSession session, EntityUid uid) { if (session.AttachedEntity == null) return; @@ -420,7 +420,7 @@ namespace Content.Server.Ghost.Roles public void Execute(IConsoleShell shell, string argStr, string[] args) { if(shell.Player != null) - EntitySystem.Get().OpenEui(shell.Player); + EntitySystem.Get().OpenEui((IPlayerSession)shell.Player); else shell.WriteLine("You can only open the ghost roles UI on a client."); } diff --git a/Content.Server/Gravity/GravityGeneratorSystem.cs b/Content.Server/Gravity/GravityGeneratorSystem.cs index 0bd159f61a..48002fb823 100644 --- a/Content.Server/Gravity/GravityGeneratorSystem.cs +++ b/Content.Server/Gravity/GravityGeneratorSystem.cs @@ -6,7 +6,7 @@ using Content.Shared.Database; using Content.Shared.Gravity; using Content.Shared.Interaction; using Robust.Server.GameObjects; -using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Server.Gravity { @@ -139,7 +139,7 @@ namespace Content.Server.Gravity return; if (session is { AttachedEntity: { } }) - _adminLogger.Add(LogType.Action, on ? LogImpact.Medium : LogImpact.High, $"{session:player} set ${ToPrettyString(uid):target} to {(on ? "on" : "off")}"); + _adminLogger.Add(LogType.Action, on ? LogImpact.Medium : LogImpact.High, $"{ToPrettyString(session.AttachedEntity.Value):player} set ${ToPrettyString(uid):target} to {(on ? "on" : "off")}"); component.SwitchedOn = on; UpdatePowerState(component, powerReceiver); diff --git a/Content.Server/Hands/Systems/HandsSystem.cs b/Content.Server/Hands/Systems/HandsSystem.cs index e3e6699537..b5b01ac001 100644 --- a/Content.Server/Hands/Systems/HandsSystem.cs +++ b/Content.Server/Hands/Systems/HandsSystem.cs @@ -18,11 +18,12 @@ using Content.Shared.Pulling.Components; using Content.Shared.Stacks; using Content.Shared.Storage; using Content.Shared.Throwing; +using Robust.Server.Player; using Robust.Shared.Containers; using Robust.Shared.GameStates; using Robust.Shared.Input.Binding; using Robust.Shared.Map; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Utility; namespace Content.Server.Hands.Systems @@ -158,9 +159,9 @@ namespace Content.Server.Hands.Systems #endregion #region interactions - private bool HandleThrowItem(ICommonSession? playerSession, EntityCoordinates coordinates, EntityUid entity) + private bool HandleThrowItem(ICommonSession? session, EntityCoordinates coordinates, EntityUid entity) { - if (playerSession == null) + if (session is not IPlayerSession playerSession) return false; if (playerSession.AttachedEntity is not {Valid: true} player || @@ -219,7 +220,7 @@ namespace Content.Server.Hands.Systems // TODO: move to storage or inventory private void HandleSmartEquip(ICommonSession? session, string equipmentSlot) { - if (session is not { } playerSession) + if (session is not IPlayerSession playerSession) return; if (playerSession.AttachedEntity is not {Valid: true} plyEnt || !Exists(plyEnt)) diff --git a/Content.Server/Humanoid/Systems/HumanoidAppearanceSystem.Modifier.cs b/Content.Server/Humanoid/Systems/HumanoidAppearanceSystem.Modifier.cs index b47fe71714..7c0bb7383b 100644 --- a/Content.Server/Humanoid/Systems/HumanoidAppearanceSystem.Modifier.cs +++ b/Content.Server/Humanoid/Systems/HumanoidAppearanceSystem.Modifier.cs @@ -3,6 +3,7 @@ using Content.Shared.Administration; using Content.Shared.Humanoid; using Content.Shared.Verbs; using Robust.Server.GameObjects; +using Robust.Server.Player; using Robust.Shared.Utility; namespace Content.Server.Humanoid; @@ -47,7 +48,7 @@ public sealed partial class HumanoidAppearanceSystem private void OnBaseLayersSet(EntityUid uid, HumanoidAppearanceComponent component, HumanoidMarkingModifierBaseLayersSetMessage message) { - if (message.Session is not { } player + if (message.Session is not IPlayerSession player || !_adminManager.HasAdminFlag(player, AdminFlags.Fun)) { return; @@ -80,7 +81,7 @@ public sealed partial class HumanoidAppearanceSystem private void OnMarkingsSet(EntityUid uid, HumanoidAppearanceComponent component, HumanoidMarkingModifierMarkingSetMessage message) { - if (message.Session is not { } player + if (message.Session is not IPlayerSession player || !_adminManager.HasAdminFlag(player, AdminFlags.Fun)) { return; diff --git a/Content.Server/Instruments/InstrumentComponent.cs b/Content.Server/Instruments/InstrumentComponent.cs index 4302ab6791..810d265314 100644 --- a/Content.Server/Instruments/InstrumentComponent.cs +++ b/Content.Server/Instruments/InstrumentComponent.cs @@ -1,7 +1,7 @@ using Content.Server.UserInterface; using Content.Shared.Instruments; using Robust.Server.GameObjects; -using Robust.Shared.Player; +using Robust.Server.Player; namespace Content.Server.Instruments; @@ -17,7 +17,7 @@ public sealed partial class InstrumentComponent : SharedInstrumentComponent [ViewVariables] public uint LastSequencerTick = 0; // TODO Instruments: Make this ECS - public ICommonSession? InstrumentPlayer => + public IPlayerSession? InstrumentPlayer => _entMan.GetComponentOrNull(Owner)?.CurrentSingleUser ?? _entMan.GetComponentOrNull(Owner)?.PlayerSession; } diff --git a/Content.Server/Instruments/InstrumentSystem.cs b/Content.Server/Instruments/InstrumentSystem.cs index 6f8369182c..ec23382105 100644 --- a/Content.Server/Instruments/InstrumentSystem.cs +++ b/Content.Server/Instruments/InstrumentSystem.cs @@ -9,12 +9,12 @@ using Content.Shared.Physics; using Content.Shared.Popups; using JetBrains.Annotations; using Robust.Server.GameObjects; +using Robust.Server.Player; using Robust.Shared.Audio.Midi; using Robust.Shared.Collections; using Robust.Shared.Configuration; using Robust.Shared.Console; using Robust.Shared.GameStates; -using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.Instruments; @@ -385,7 +385,7 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem var nearby = GetBands(entity); _bui.TrySendUiMessage(entity, request.UiKey, new InstrumentBandResponseBuiMessage(nearby), - request.Session); + (IPlayerSession)request.Session); } _bandRequestQueue.Clear(); @@ -447,7 +447,7 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem } } - public void ToggleInstrumentUi(EntityUid uid, ICommonSession session, InstrumentComponent? component = null) + public void ToggleInstrumentUi(EntityUid uid, IPlayerSession session, InstrumentComponent? component = null) { if (!Resolve(uid, ref component)) return; diff --git a/Content.Server/Interaction/InteractionSystem.cs b/Content.Server/Interaction/InteractionSystem.cs index 9237a1f7dd..a612b73840 100644 --- a/Content.Server/Interaction/InteractionSystem.cs +++ b/Content.Server/Interaction/InteractionSystem.cs @@ -13,6 +13,7 @@ using Robust.Server.GameObjects; using Robust.Shared.Containers; using Robust.Shared.Input.Binding; using Robust.Shared.Map; +using Robust.Shared.Players; using Robust.Shared.Random; namespace Content.Server.Interaction diff --git a/Content.Server/Interaction/TilePryCommand.cs b/Content.Server/Interaction/TilePryCommand.cs index fa75b6d9e4..4fe3599df9 100644 --- a/Content.Server/Interaction/TilePryCommand.cs +++ b/Content.Server/Interaction/TilePryCommand.cs @@ -1,7 +1,10 @@ using System.Numerics; using Content.Server.Administration; +using Content.Server.Tools.Components; using Content.Shared.Administration; using Content.Shared.Maps; +using Content.Shared.Tools.Components; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; @@ -21,7 +24,7 @@ namespace Content.Server.Interaction public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player?.AttachedEntity is not {} attached) { return; diff --git a/Content.Server/MagicMirror/MagicMirrorSystem.cs b/Content.Server/MagicMirror/MagicMirrorSystem.cs index a599a2c868..90a0b19b7d 100644 --- a/Content.Server/MagicMirror/MagicMirrorSystem.cs +++ b/Content.Server/MagicMirror/MagicMirrorSystem.cs @@ -5,7 +5,8 @@ using Content.Shared.Humanoid; using Content.Shared.Humanoid.Markings; using Content.Shared.MagicMirror; using Robust.Server.GameObjects; -using Robust.Shared.Player; +using Robust.Server.Player; +using Robust.Shared.Players; namespace Content.Server.MagicMirror; @@ -146,7 +147,7 @@ public sealed class MagicMirrorSystem : EntitySystem private void UpdateInterface(EntityUid uid, EntityUid playerUid, ICommonSession session, HumanoidAppearanceComponent? humanoid = null) { - if (!Resolve(playerUid, ref humanoid) || session is not { } player) + if (!Resolve(playerUid, ref humanoid) || session is not IPlayerSession player) { return; } diff --git a/Content.Server/Mapping/MappingCommand.cs b/Content.Server/Mapping/MappingCommand.cs index d72a5c4178..e4a4cd8942 100644 --- a/Content.Server/Mapping/MappingCommand.cs +++ b/Content.Server/Mapping/MappingCommand.cs @@ -40,7 +40,7 @@ namespace Content.Server.Mapping public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not { } player) + if (shell.Player is not IPlayerSession player) { shell.WriteError(Loc.GetString("cmd-savemap-server")); return; diff --git a/Content.Server/Maps/GridDraggingSystem.cs b/Content.Server/Maps/GridDraggingSystem.cs index 7d7b61955b..90770af1ad 100644 --- a/Content.Server/Maps/GridDraggingSystem.cs +++ b/Content.Server/Maps/GridDraggingSystem.cs @@ -1,9 +1,10 @@ using Content.Shared.Maps; using Robust.Server.Console; +using Robust.Server.Player; +using Robust.Shared.Players; using Robust.Shared.Utility; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; -using Robust.Shared.Player; namespace Content.Server.Maps; @@ -26,7 +27,7 @@ public sealed class GridDraggingSystem : SharedGridDraggingSystem public void Toggle(ICommonSession session) { - if (session is not { } pSession) + if (session is not IPlayerSession pSession) return; DebugTools.Assert(_admin.CanCommand(pSession, CommandName)); @@ -51,7 +52,7 @@ public sealed class GridDraggingSystem : SharedGridDraggingSystem { var grid = GetEntity(ev.Grid); - if (args.SenderSession is not { } playerSession || + if (args.SenderSession is not IPlayerSession playerSession || !_admin.CanCommand(playerSession, CommandName) || !Exists(grid) || Deleted(grid)) @@ -68,7 +69,7 @@ public sealed class GridDraggingSystem : SharedGridDraggingSystem { var grid = GetEntity(msg.Grid); - if (args.SenderSession is not { } playerSession || + if (args.SenderSession is not IPlayerSession playerSession || !_admin.CanCommand(playerSession, CommandName) || !Exists(grid) || Deleted(grid)) diff --git a/Content.Server/Medical/DefibrillatorSystem.cs b/Content.Server/Medical/DefibrillatorSystem.cs index d041f8ee9d..4ffa9f558d 100644 --- a/Content.Server/Medical/DefibrillatorSystem.cs +++ b/Content.Server/Medical/DefibrillatorSystem.cs @@ -18,7 +18,7 @@ using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; using Content.Shared.Timing; using Content.Shared.Toggleable; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Timing; namespace Content.Server.Medical; diff --git a/Content.Server/Mind/Commands/RenameCommand.cs b/Content.Server/Mind/Commands/RenameCommand.cs index 2d65adc508..5674da4ffd 100644 --- a/Content.Server/Mind/Commands/RenameCommand.cs +++ b/Content.Server/Mind/Commands/RenameCommand.cs @@ -54,7 +54,6 @@ public sealed class RenameCommand : IConsoleCommand { // Mind mind.CharacterName = name; - _entManager.Dirty(mindId, mind); } // Id Cards diff --git a/Content.Server/Mind/MindSystem.cs b/Content.Server/Mind/MindSystem.cs index f23e9b6407..373007fd1b 100644 --- a/Content.Server/Mind/MindSystem.cs +++ b/Content.Server/Mind/MindSystem.cs @@ -1,7 +1,6 @@ using System.Diagnostics.CodeAnalysis; using Content.Server.Administration.Logs; using Content.Server.GameTicking; -using Content.Server.Mind.Commands; using Content.Shared.Database; using Content.Shared.Ghost; using Content.Shared.Mind; @@ -11,9 +10,7 @@ using Robust.Server.GameObjects; using Robust.Server.GameStates; using Robust.Server.Player; using Robust.Shared.Map; -using Robust.Shared.Map.Components; using Robust.Shared.Network; -using Robust.Shared.Player; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -49,14 +46,20 @@ public sealed class MindSystem : SharedMindSystem mind.UserId = null; } - if (mind.OwnedEntity != null && !TerminatingOrDeleted(mind.OwnedEntity.Value)) - TransferTo(uid, null, mind: mind, createGhost: false); + if (!TryComp(mind.OwnedEntity, out MetaDataComponent? meta) || meta.EntityLifeStage >= EntityLifeStage.Terminating) + return; + RaiseLocalEvent(mind.OwnedEntity.Value, new MindRemovedMessage(uid, mind), true); mind.OwnedEntity = null; + mind.OwnedComponent = null; } private void OnMindContainerTerminating(EntityUid uid, MindContainerComponent component, ref EntityTerminatingEvent args) { + // Let's not create ghosts if not in the middle of the round. + if (_gameTicker.RunLevel == GameRunLevel.PreRoundLobby) + return; + if (!TryGetMind(uid, out var mindId, out var mind, component)) return; @@ -73,45 +76,46 @@ public sealed class MindSystem : SharedMindSystem } TransferTo(mindId, null, createGhost: false, mind: mind); - DebugTools.AssertNull(mind.OwnedEntity); - if (!component.GhostOnShutdown || mind.Session == null || _gameTicker.RunLevel == GameRunLevel.PreRoundLobby) - return; - - var xform = Transform(uid); - var gridId = xform.GridUid; - var spawnPosition = Transform(uid).Coordinates; - - // Use a regular timer here because the entity has probably been deleted. - Timer.Spawn(0, () => + if (component.GhostOnShutdown && mind.Session != null) { - // Make extra sure the round didn't end between spawning the timer and it being executed. - if (_gameTicker.RunLevel == GameRunLevel.PreRoundLobby) - return; + var xform = Transform(uid); + var gridId = xform.GridUid; + var spawnPosition = Transform(uid).Coordinates; - // Async this so that we don't throw if the grid we're on is being deleted. - if (!HasComp(gridId)) - spawnPosition = _gameTicker.GetObserverSpawnPoint(); - - // TODO refactor observer spawning. - // please. - if (!spawnPosition.IsValid(EntityManager)) + // Use a regular timer here because the entity has probably been deleted. + Timer.Spawn(0, () => { - // This should be an error, if it didn't cause tests to start erroring when they delete a player. - Log.Warning($"Entity \"{ToPrettyString(uid)}\" for {mind.CharacterName} was deleted, and no applicable spawn location is available."); - TransferTo(mindId, null, createGhost: false, mind: mind); - return; - } + // Make extra sure the round didn't end between spawning the timer and it being executed. + if (_gameTicker.RunLevel == GameRunLevel.PreRoundLobby) + return; - var ghost = Spawn(GameTicker.ObserverPrototypeName, spawnPosition); - var ghostComponent = Comp(ghost); - _ghosts.SetCanReturnToBody(ghostComponent, false); + // Async this so that we don't throw if the grid we're on is being deleted. + if (!_maps.GridExists(gridId)) + spawnPosition = _gameTicker.GetObserverSpawnPoint(); - // Log these to make sure they're not causing the GameTicker round restart bugs... - Log.Debug($"Entity \"{ToPrettyString(uid)}\" for {mind.CharacterName} was deleted, spawned \"{ToPrettyString(ghost)}\"."); - _metaData.SetEntityName(ghost, mind.CharacterName ?? string.Empty); - TransferTo(mindId, ghost, mind: mind); - }); + // TODO refactor observer spawning. + // please. + if (!spawnPosition.IsValid(EntityManager)) + { + // This should be an error, if it didn't cause tests to start erroring when they delete a player. + Log.Warning($"Entity \"{ToPrettyString(uid)}\" for {mind.CharacterName} was deleted, and no applicable spawn location is available."); + TransferTo(mindId, null, createGhost: false, mind: mind); + return; + } + + var ghost = Spawn("MobObserver", spawnPosition); + var ghostComponent = Comp(ghost); + _ghosts.SetCanReturnToBody(ghostComponent, false); + + // Log these to make sure they're not causing the GameTicker round restart bugs... + Log.Debug($"Entity \"{ToPrettyString(uid)}\" for {mind.CharacterName} was deleted, spawned \"{ToPrettyString(ghost)}\"."); + + var val = mind.CharacterName ?? string.Empty; + _metaData.SetEntityName(ghost, val); + TransferTo(mindId, ghost, mind: mind); + }); + } } public override bool TryGetMind(NetUserId user, [NotNullWhen(true)] out EntityUid? mindId, [NotNullWhen(true)] out MindComponent? mind) @@ -126,18 +130,18 @@ public sealed class MindSystem : SharedMindSystem return false; } - public bool TryGetSession(EntityUid? mindId, [NotNullWhen(true)] out ICommonSession? session) + public bool TryGetSession(EntityUid? mindId, [NotNullWhen(true)] out IPlayerSession? session) { session = null; - return TryComp(mindId, out MindComponent? mind) && (session = mind.Session) != null; + return TryComp(mindId, out MindComponent? mind) && (session = (IPlayerSession?) mind.Session) != null; } - public ICommonSession? GetSession(MindComponent mind) + public IPlayerSession? GetSession(MindComponent mind) { - return mind.Session; + return (IPlayerSession?) mind.Session; } - public bool TryGetSession(MindComponent mind, [NotNullWhen(true)] out ICommonSession? session) + public bool TryGetSession(MindComponent mind, [NotNullWhen(true)] out IPlayerSession? session) { return (session = GetSession(mind)) != null; } @@ -175,9 +179,7 @@ public sealed class MindSystem : SharedMindSystem return; } - if (GetSession(mind) is { } session) - _actor.Attach(entity, session); - + GetSession(mind)?.AttachToEntity(entity); mind.VisitingEntity = entity; // EnsureComp instead of AddComp to deal with deferred deletions. @@ -196,14 +198,13 @@ public sealed class MindSystem : SharedMindSystem if (mind.VisitingEntity == null) return; - RemoveVisitingEntity(mindId, mind); + RemoveVisitingEntity(mind); if (mind.Session == null || mind.Session.AttachedEntity == mind.VisitingEntity) return; var owned = mind.OwnedEntity; - if (GetSession(mind) is { } session) - _actor.Attach(owned, session); + GetSession(mind)?.AttachToEntity(owned); if (owned.HasValue) { @@ -218,10 +219,11 @@ public sealed class MindSystem : SharedMindSystem if (mind == null && !Resolve(mindId, ref mind)) return; + base.TransferTo(mindId, entity, ghostCheckOverride, createGhost, mind); + if (entity == mind.OwnedEntity) return; - Dirty(mindId, mind); MindContainerComponent? component = null; var alreadyAttached = false; @@ -245,33 +247,27 @@ public sealed class MindSystem : SharedMindSystem } else if (createGhost) { - // TODO remove this option. - // Transfer-to-null should just detach a mind. - // If people want to create a ghost, that should be done explicitly via some TransferToGhost() method, not - // not implicitly via optional arguments. - var position = Deleted(mind.OwnedEntity) ? _gameTicker.GetObserverSpawnPoint().ToMap(EntityManager, _transform) : Transform(mind.OwnedEntity.Value).MapPosition; entity = Spawn("MobObserver", position); - component = EnsureComp(entity.Value); var ghostComponent = Comp(entity.Value); _ghosts.SetCanReturnToBody(ghostComponent, false); } + var oldComp = mind.OwnedComponent; var oldEntity = mind.OwnedEntity; - if (TryComp(oldEntity, out MindContainerComponent? oldContainer)) + if (oldComp != null && oldEntity != null) { - oldContainer.Mind = null; - mind.OwnedEntity = null; - Entity mindEnt = (mindId, mind); - Entity containerEnt = (oldEntity.Value, oldContainer); - RaiseLocalEvent(oldEntity.Value, new MindRemovedMessage(mindEnt, containerEnt)); - RaiseLocalEvent(mindId, new MindGotRemovedEvent(mindEnt, containerEnt)); - Dirty(oldEntity.Value, oldContainer); + if (oldComp.Mind != null) + _pvsOverride.ClearOverride(oldComp.Mind.Value); + oldComp.Mind = null; + RaiseLocalEvent(oldEntity.Value, new MindRemovedMessage(oldEntity.Value, mind), true); } + SetOwnedEntity(mind, entity, component); + // Don't do the full deletion cleanup if we're transferring to our VisitingEntity if (alreadyAttached) { @@ -285,7 +281,7 @@ public sealed class MindSystem : SharedMindSystem || !TryComp(mind.VisitingEntity!, out GhostComponent? ghostComponent) // visiting entity is not a Ghost || !ghostComponent.CanReturnToBody)) // it is a ghost, but cannot return to body anyway, so it's okay { - RemoveVisitingEntity(mindId, mind); + RemoveVisitingEntity(mind); } // Player is CURRENTLY connected. @@ -293,20 +289,14 @@ public sealed class MindSystem : SharedMindSystem if (session != null && !alreadyAttached && mind.VisitingEntity == null) { _actor.Attach(entity, session, true); - DebugTools.Assert(session.AttachedEntity == entity, $"Failed to attach entity."); Log.Info($"Session {session.Name} transferred to entity {entity}."); } - if (entity != null) + if (mind.OwnedComponent != null) { - component!.Mind = mindId; - mind.OwnedEntity = entity; - mind.OriginalOwnedEntity ??= GetNetEntity(mind.OwnedEntity); - Entity mindEnt = (mindId, mind); - Entity containerEnt = (entity.Value, component); - RaiseLocalEvent(entity.Value, new MindAddedMessage(mindEnt, containerEnt)); - RaiseLocalEvent(mindId, new MindGotAddedEvent(mindEnt, containerEnt)); - Dirty(entity.Value, component); + mind.OwnedComponent.Mind = mindId; + RaiseLocalEvent(mind.OwnedEntity!.Value, new MindAddedMessage(), true); + mind.OriginalOwnedEntity ??= mind.OwnedEntity; } } @@ -323,7 +313,6 @@ public sealed class MindSystem : SharedMindSystem if (mind.UserId == userId) return; - Dirty(mindId, mind); _pvsOverride.ClearOverride(mindId); if (userId != null && !_players.TryGetPlayerData(userId.Value, out _)) { @@ -374,27 +363,4 @@ public sealed class MindSystem : SharedMindSystem if (_players.GetPlayerData(userId.Value).ContentData() is { } data) data.Mind = mindId; } - - public void ControlMob(EntityUid user, EntityUid target) - { - if (TryComp(user, out ActorComponent? actor)) - ControlMob(actor.PlayerSession.UserId, target); - } - - public void ControlMob(NetUserId user, EntityUid target) - { - var (mindId, mind) = GetOrCreateMind(user); - - if (mind.CurrentEntity == target) - return; - - if (mind.OwnedEntity == target) - { - UnVisit(mindId, mind); - return; - } - - MakeSentientCommand.MakeSentient(target, EntityManager); - TransferTo(mindId, target, ghostCheckOverride: true, mind: mind); - } } diff --git a/Content.Server/Mind/Toolshed/MindCommand.cs b/Content.Server/Mind/Toolshed/MindCommand.cs index 917e6fb7f1..b53f9a6a9c 100644 --- a/Content.Server/Mind/Toolshed/MindCommand.cs +++ b/Content.Server/Mind/Toolshed/MindCommand.cs @@ -1,5 +1,5 @@ using Content.Shared.Mind; -using Robust.Shared.Player; +using Robust.Server.Player; using Robust.Shared.Toolshed; using Robust.Shared.Toolshed.Errors; using Robust.Shared.Toolshed.Syntax; @@ -15,7 +15,7 @@ public sealed class MindCommand : ToolshedCommand private SharedMindSystem? _mind; [CommandImplementation("get")] - public MindComponent? Get([PipedArgument] ICommonSession session) + public MindComponent? Get([PipedArgument] IPlayerSession session) { _mind ??= GetSys(); return _mind.TryGetMind(session, out _, out var mind) ? mind : null; @@ -32,7 +32,7 @@ public sealed class MindCommand : ToolshedCommand public EntityUid Control( [CommandInvocationContext] IInvocationContext ctx, [PipedArgument] EntityUid target, - [CommandArgument] ValueRef playerRef) + [CommandArgument] ValueRef playerRef) { _mind ??= GetSys(); diff --git a/Content.Server/Motd/MOTDCommand.cs b/Content.Server/Motd/MOTDCommand.cs index 9e59589b95..a1aa4d2df5 100644 --- a/Content.Server/Motd/MOTDCommand.cs +++ b/Content.Server/Motd/MOTDCommand.cs @@ -1,5 +1,6 @@ using Content.Server.Administration.Managers; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Motd; @@ -13,10 +14,10 @@ internal sealed class MOTDCommand : LocalizedCommands [Dependency] private readonly IAdminManager _adminManager = default!; public override string Command => "motd"; - + public override void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = (IPlayerSession?)shell.Player; if (args.Length < 1 || (player != null && _adminManager is AdminManager aMan && !aMan.CanCommand(player, "set-motd"))) shell.ConsoleHost.ExecuteCommand(shell.Player, "get-motd"); else @@ -25,7 +26,7 @@ internal sealed class MOTDCommand : LocalizedCommands public override CompletionResult GetCompletion(IConsoleShell shell, string[] args) { - var player = shell.Player; + var player = (IPlayerSession?)shell.Player; if (player != null && _adminManager is AdminManager aMan && !aMan.CanCommand(player, "set-motd")) return CompletionResult.Empty; if (args.Length == 1) diff --git a/Content.Server/Motd/MOTDSystem.cs b/Content.Server/Motd/MOTDSystem.cs index 39d780f108..e749fe48f3 100644 --- a/Content.Server/Motd/MOTDSystem.cs +++ b/Content.Server/Motd/MOTDSystem.cs @@ -2,9 +2,9 @@ using Content.Server.Chat.Managers; using Content.Server.GameTicking; using Content.Shared.CCVar; using Content.Shared.Chat; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Configuration; -using Robust.Shared.Player; namespace Content.Server.Motd; @@ -41,7 +41,7 @@ public sealed class MOTDSystem : EntitySystem { if (string.IsNullOrEmpty(_messageOfTheDay)) return; - + var wrappedMessage = Loc.GetString("motd-wrap-message", ("motd", _messageOfTheDay)); _chatManager.ChatMessageToAll(ChatChannel.Server, _messageOfTheDay, wrappedMessage, source: EntityUid.Invalid, hideChat: false, recordReplay: true); } @@ -49,11 +49,11 @@ public sealed class MOTDSystem : EntitySystem /// /// Sends the Message Of The Day, if any, to a specific player. /// - public void TrySendMOTD(ICommonSession player) + public void TrySendMOTD(IPlayerSession player) { if (string.IsNullOrEmpty(_messageOfTheDay)) return; - + var wrappedMessage = Loc.GetString("motd-wrap-message", ("motd", _messageOfTheDay)); _chatManager.ChatMessageToOne(ChatChannel.Server, _messageOfTheDay, wrappedMessage, source: EntityUid.Invalid, hideChat: false, client: player.ConnectedClient); } @@ -68,10 +68,10 @@ public sealed class MOTDSystem : EntitySystem { if (string.IsNullOrEmpty(_messageOfTheDay)) return; - + var wrappedMessage = Loc.GetString("motd-wrap-message", ("motd", _messageOfTheDay)); shell.WriteLine(wrappedMessage); - if (shell.Player is { } player) + if (shell.Player is IPlayerSession player) _chatManager.ChatMessageToOne(ChatChannel.Server, _messageOfTheDay, wrappedMessage, source: EntityUid.Invalid, hideChat: false, client: player.ConnectedClient); } @@ -92,7 +92,7 @@ public sealed class MOTDSystem : EntitySystem { if (val == _messageOfTheDay) return; - + _messageOfTheDay = val; TrySendMOTD(); } diff --git a/Content.Server/Motd/SetMOTDCommand.cs b/Content.Server/Motd/SetMOTDCommand.cs index 9678781c87..f3f52b0670 100644 --- a/Content.Server/Motd/SetMOTDCommand.cs +++ b/Content.Server/Motd/SetMOTDCommand.cs @@ -4,6 +4,7 @@ using Content.Shared.Administration; using Content.Shared.Database; using Content.Shared.CCVar; using Content.Server.Chat.Managers; +using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Console; @@ -20,18 +21,18 @@ public sealed class SetMotdCommand : LocalizedCommands [Dependency] private readonly IConfigurationManager _configurationManager = default!; public override string Command => "set-motd"; - + public override void Execute(IConsoleShell shell, string argStr, string[] args) { string motd = ""; - var player = shell.Player; + var player = (IPlayerSession?)shell.Player; if (args.Length > 0) { motd = string.Join(" ", args).Trim(); if (player != null && _chatManager.MessageCharacterLimit(player, motd)) return; // check function prints its own error response } - + _configurationManager.SetCVar(CCVars.MOTD, motd); // A hook in MOTDSystem broadcasts changes to the MOTD to everyone so we don't need to do it here. if (string.IsNullOrEmpty(motd)) { diff --git a/Content.Server/Movement/Systems/LagCompensationSystem.cs b/Content.Server/Movement/Systems/LagCompensationSystem.cs index 0576fe8f25..64965c2fee 100644 --- a/Content.Server/Movement/Systems/LagCompensationSystem.cs +++ b/Content.Server/Movement/Systems/LagCompensationSystem.cs @@ -1,7 +1,7 @@ using Content.Server.Movement.Components; using Robust.Server.Player; using Robust.Shared.Map; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Timing; namespace Content.Server.Movement.Systems; diff --git a/Content.Server/NPC/Commands/NPCCommand.cs b/Content.Server/NPC/Commands/NPCCommand.cs index 7f9e56b8ca..57fe223b66 100644 --- a/Content.Server/NPC/Commands/NPCCommand.cs +++ b/Content.Server/NPC/Commands/NPCCommand.cs @@ -2,6 +2,7 @@ using Content.Server.Administration; using Content.Server.EUI; using Content.Server.NPC.UI; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.NPC.Commands; @@ -14,7 +15,7 @@ public sealed class NPCCommand : IConsoleCommand public string Help => $"{Command}"; public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not { } playerSession) + if (shell.Player is not IPlayerSession playerSession) { return; } diff --git a/Content.Server/NPC/HTN/HTNSystem.cs b/Content.Server/NPC/HTN/HTNSystem.cs index a7689fbabe..2c1dadb127 100644 --- a/Content.Server/NPC/HTN/HTNSystem.cs +++ b/Content.Server/NPC/HTN/HTNSystem.cs @@ -4,14 +4,17 @@ using System.Threading; using Content.Server.Administration.Managers; using Robust.Shared.CPUJob.JobQueues; using Robust.Shared.CPUJob.JobQueues.Queues; +using Content.Server.NPC.Components; using Content.Server.NPC.HTN.PrimitiveTasks; using Content.Server.NPC.Systems; using Content.Shared.Administration; using Content.Shared.Mobs; using Content.Shared.NPC; +using Content.Shared.NPC; using JetBrains.Annotations; using Robust.Server.GameObjects; -using Robust.Shared.Player; +using Robust.Server.Player; +using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Utility; @@ -45,7 +48,7 @@ public sealed class HTNSystem : EntitySystem private void OnHTNMessage(RequestHTNMessage msg, EntitySessionEventArgs args) { - if (!_admin.HasAdminFlag(args.SenderSession, AdminFlags.Debug)) + if (!_admin.HasAdminFlag((IPlayerSession) args.SenderSession, AdminFlags.Debug)) { _subscribers.Remove(args.SenderSession); return; diff --git a/Content.Server/NPC/Pathfinding/PathfindingSystem.cs b/Content.Server/NPC/Pathfinding/PathfindingSystem.cs index 1b1f6f5476..bb0eff7b39 100644 --- a/Content.Server/NPC/Pathfinding/PathfindingSystem.cs +++ b/Content.Server/NPC/Pathfinding/PathfindingSystem.cs @@ -13,7 +13,7 @@ using Robust.Shared.Enums; using Robust.Shared.Map; using Robust.Shared.Physics; using Robust.Shared.Physics.Systems; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Random; using Robust.Shared.Threading; using Robust.Shared.Timing; @@ -528,7 +528,7 @@ namespace Content.Server.NPC.Pathfinding private void OnBreadcrumbs(RequestPathfindingDebugMessage msg, EntitySessionEventArgs args) { - var pSession = args.SenderSession; + var pSession = (IPlayerSession) args.SenderSession; if (!_adminManager.HasAdminFlag(pSession, AdminFlags.Debug)) { diff --git a/Content.Server/NPC/Systems/NPCSteeringSystem.cs b/Content.Server/NPC/Systems/NPCSteeringSystem.cs index e5b62acfe8..61b43df6f0 100644 --- a/Content.Server/NPC/Systems/NPCSteeringSystem.cs +++ b/Content.Server/NPC/Systems/NPCSteeringSystem.cs @@ -17,12 +17,14 @@ using Content.Shared.NPC; using Content.Shared.NPC.Events; using Content.Shared.Physics; using Content.Shared.Weapons.Melee; +using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Map; using Robust.Shared.Physics; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Random; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -145,7 +147,7 @@ public sealed partial class NPCSteeringSystem : SharedNPCSteeringSystem private void OnDebugRequest(RequestNPCSteeringDebugEvent msg, EntitySessionEventArgs args) { - if (!_admin.IsAdmin(args.SenderSession)) + if (!_admin.IsAdmin((IPlayerSession)args.SenderSession)) return; if (msg.Enabled) diff --git a/Content.Server/NodeContainer/EntitySystems/NodeGroupSystem.cs b/Content.Server/NodeContainer/EntitySystems/NodeGroupSystem.cs index 9ee9702c5b..e4bd303150 100644 --- a/Content.Server/NodeContainer/EntitySystems/NodeGroupSystem.cs +++ b/Content.Server/NodeContainer/EntitySystems/NodeGroupSystem.cs @@ -9,7 +9,6 @@ using JetBrains.Annotations; using Robust.Server.Player; using Robust.Shared.Enums; using Robust.Shared.Map; -using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Server.NodeContainer.EntitySystems @@ -30,7 +29,7 @@ namespace Content.Server.NodeContainer.EntitySystems private readonly List _visDeletes = new(); private readonly List _visSends = new(); - private readonly HashSet _visPlayers = new(); + private readonly HashSet _visPlayers = new(); private readonly HashSet _toRemake = new(); private readonly HashSet _nodeGroups = new(); private readonly HashSet _toRemove = new(); @@ -75,7 +74,7 @@ namespace Content.Server.NodeContainer.EntitySystems private void HandleEnableMsg(NodeVis.MsgEnable msg, EntitySessionEventArgs args) { - var session = args.SenderSession; + var session = (IPlayerSession) args.SenderSession; if (!_adminManager.HasAdminFlag(session, AdminFlags.Debug)) return; @@ -398,7 +397,7 @@ namespace Content.Server.NodeContainer.EntitySystems } } - private void VisSendFullStateImmediate(ICommonSession player) + private void VisSendFullStateImmediate(IPlayerSession player) { var msg = new NodeVis.MsgData(); diff --git a/Content.Server/Nutrition/Hungry.cs b/Content.Server/Nutrition/Hungry.cs index ae68dcd2fd..c27f302a8d 100644 --- a/Content.Server/Nutrition/Hungry.cs +++ b/Content.Server/Nutrition/Hungry.cs @@ -1,7 +1,9 @@ using Content.Server.Administration; +using Content.Server.Nutrition.Components; using Content.Shared.Administration; using Content.Shared.Nutrition.Components; using Content.Shared.Nutrition.EntitySystems; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Nutrition @@ -17,7 +19,7 @@ namespace Content.Server.Nutrition public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player == null) { shell.WriteLine("You cannot use this command unless you are a player."); diff --git a/Content.Server/Objectives/Commands/ListObjectivesCommand.cs b/Content.Server/Objectives/Commands/ListObjectivesCommand.cs index 97fc943269..93dec3fa44 100644 --- a/Content.Server/Objectives/Commands/ListObjectivesCommand.cs +++ b/Content.Server/Objectives/Commands/ListObjectivesCommand.cs @@ -18,7 +18,7 @@ namespace Content.Server.Objectives.Commands public override void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player; + var player = shell.Player as IPlayerSession; if (player == null || !_players.TryGetSessionByUsername(args[0], out player)) { shell.WriteError(LocalizationManager.GetString("shell-target-player-does-not-exist")); diff --git a/Content.Server/PDA/PdaSystem.cs b/Content.Server/PDA/PdaSystem.cs index 44e2659841..6c506dc3dd 100644 --- a/Content.Server/PDA/PdaSystem.cs +++ b/Content.Server/PDA/PdaSystem.cs @@ -4,6 +4,9 @@ using Content.Server.DeviceNetwork.Components; using Content.Server.Instruments; using Content.Server.Light.EntitySystems; using Content.Server.Light.Events; +using Content.Server.MassMedia.Components; +using Content.Server.MassMedia.Systems; +using Content.Server.Mind; using Content.Server.PDA.Ringer; using Content.Server.Station.Systems; using Content.Server.Store.Components; @@ -13,6 +16,7 @@ using Content.Shared.CartridgeLoader; using Content.Shared.Light.Components; using Content.Shared.PDA; using Robust.Server.GameObjects; +using Robust.Server.Player; using Robust.Shared.Containers; namespace Content.Server.PDA @@ -176,7 +180,7 @@ namespace Content.Server.PDA return; if (HasComp(uid)) - _ringer.ToggleRingerUI(uid, msg.Session); + _ringer.ToggleRingerUI(uid, (IPlayerSession) msg.Session); } private void OnUiMessage(EntityUid uid, PdaComponent pda, PdaShowMusicMessage msg) @@ -185,7 +189,7 @@ namespace Content.Server.PDA return; if (TryComp(uid, out var instrument)) - _instrument.ToggleInstrumentUi(uid, msg.Session, instrument); + _instrument.ToggleInstrumentUi(uid, (IPlayerSession) msg.Session, instrument); } private void OnUiMessage(EntityUid uid, PdaComponent pda, PdaShowUplinkMessage msg) diff --git a/Content.Server/PDA/Ringer/RingerSystem.cs b/Content.Server/PDA/Ringer/RingerSystem.cs index 7494d5e12c..a772e76bc4 100644 --- a/Content.Server/PDA/Ringer/RingerSystem.cs +++ b/Content.Server/PDA/Ringer/RingerSystem.cs @@ -7,6 +7,7 @@ using Content.Shared.PDA.Ringer; using Content.Shared.Popups; using Content.Shared.Store; using Robust.Server.GameObjects; +using Robust.Server.Player; using Robust.Shared.Audio; using Robust.Shared.Network; using Robust.Shared.Player; @@ -181,7 +182,7 @@ namespace Content.Server.PDA.Ringer _ui.SetUiState(bui, new RingerUpdateState(isPlaying, ringer.Ringtone)); } - public bool ToggleRingerUI(EntityUid uid, ICommonSession session) + public bool ToggleRingerUI(EntityUid uid, IPlayerSession session) { if (_ui.TryGetUi(uid, RingerUiKey.Key, out var bui)) _ui.ToggleUi(bui, session); diff --git a/Content.Server/Paper/PaperSystem.cs b/Content.Server/Paper/PaperSystem.cs index 553bcaa0a2..f38013e14d 100644 --- a/Content.Server/Paper/PaperSystem.cs +++ b/Content.Server/Paper/PaperSystem.cs @@ -4,11 +4,15 @@ using Content.Server.Popups; using Content.Server.UserInterface; using Content.Shared.Database; using Content.Shared.Examine; +using Content.Shared.IdentityManagement; using Content.Shared.Interaction; using Content.Shared.Paper; using Content.Shared.Tag; using Robust.Server.GameObjects; +using Robust.Server.Player; using Robust.Shared.Player; +using Robust.Shared.Utility; +using Robust.Shared.Audio; using static Content.Shared.Paper.SharedPaperComponent; namespace Content.Server.Paper @@ -203,7 +207,7 @@ namespace Content.Server.Paper _appearance.SetData(uid, PaperVisuals.Status, status, appearance); } - public void UpdateUserInterface(EntityUid uid, PaperComponent? paperComp = null, ICommonSession? session = null) + public void UpdateUserInterface(EntityUid uid, PaperComponent? paperComp = null, IPlayerSession? session = null) { if (!Resolve(uid, ref paperComp)) return; diff --git a/Content.Server/Parallax/BiomeSystem.cs b/Content.Server/Parallax/BiomeSystem.cs index c9017ac821..a9d78afa86 100644 --- a/Content.Server/Parallax/BiomeSystem.cs +++ b/Content.Server/Parallax/BiomeSystem.cs @@ -282,8 +282,9 @@ public sealed partial class BiomeSystem : SharedBiomeSystem } // Get chunks in range - foreach (var pSession in Filter.GetAllPlayers(_playerManager)) + foreach (var client in Filter.GetAllPlayers(_playerManager)) { + var pSession = (IPlayerSession) client; if (xformQuery.TryGetComponent(pSession.AttachedEntity, out var xform) && _handledEntities.Add(pSession.AttachedEntity.Value) && diff --git a/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.ControlBox.cs b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.ControlBox.cs index f200c991d7..20ed276967 100644 --- a/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.ControlBox.cs +++ b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.ControlBox.cs @@ -2,10 +2,11 @@ using Content.Server.ParticleAccelerator.Components; using Content.Server.Power.Components; using Content.Shared.Database; using Content.Shared.Singularity.Components; +using Robust.Server.Player; +using Robust.Server.GameObjects; using Robust.Shared.Utility; using System.Diagnostics; using Content.Shared.CCVar; -using Robust.Shared.Player; namespace Content.Server.ParticleAccelerator.EntitySystems; @@ -59,7 +60,7 @@ public sealed partial class ParticleAcceleratorSystem FireEmitter(comp.StarboardEmitter!.Value, strength); } - public void SwitchOn(EntityUid uid, ICommonSession? user = null, ParticleAcceleratorControlBoxComponent? comp = null) + public void SwitchOn(EntityUid uid, IPlayerSession? user = null, ParticleAcceleratorControlBoxComponent? comp = null) { if (!Resolve(uid, ref comp)) return; @@ -82,7 +83,7 @@ public sealed partial class ParticleAcceleratorSystem UpdateUI(uid, comp); } - public void SwitchOff(EntityUid uid, ICommonSession? user = null, ParticleAcceleratorControlBoxComponent? comp = null) + public void SwitchOff(EntityUid uid, IPlayerSession? user = null, ParticleAcceleratorControlBoxComponent? comp = null) { if (!Resolve(uid, ref comp)) return; @@ -130,7 +131,7 @@ public sealed partial class ParticleAcceleratorSystem UpdateUI(uid, comp); } - public void SetStrength(EntityUid uid, ParticleAcceleratorPowerState strength, ICommonSession? user = null, ParticleAcceleratorControlBoxComponent? comp = null) + public void SetStrength(EntityUid uid, ParticleAcceleratorPowerState strength, IPlayerSession? user = null, ParticleAcceleratorControlBoxComponent? comp = null) { if (!Resolve(uid, ref comp)) return; @@ -346,10 +347,10 @@ public sealed partial class ParticleAcceleratorSystem if (msg.Enabled) { if (comp.Assembled) - SwitchOn(uid, msg.Session, comp); + SwitchOn(uid, (IPlayerSession?) msg.Session, comp); } else - SwitchOff(uid, msg.Session, comp); + SwitchOff(uid, (IPlayerSession?) msg.Session, comp); UpdateUI(uid, comp); } @@ -363,7 +364,7 @@ public sealed partial class ParticleAcceleratorSystem if (TryComp(uid, out var apcPower) && !apcPower.Powered) return; - SetStrength(uid, msg.State, msg.Session, comp); + SetStrength(uid, msg.State, (IPlayerSession?) msg.Session, comp); UpdateUI(uid, comp); } @@ -377,7 +378,7 @@ public sealed partial class ParticleAcceleratorSystem if (TryComp(uid, out var apcPower) && !apcPower.Powered) return; - RescanParts(uid, msg.Session, comp); + RescanParts(uid, (IPlayerSession?) msg.Session, comp); UpdateUI(uid, comp); } diff --git a/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Parts.cs b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Parts.cs index abc68543ff..271d17a0c4 100644 --- a/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Parts.cs +++ b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Parts.cs @@ -2,9 +2,9 @@ using System.Diagnostics.CodeAnalysis; using System.Numerics; using Content.Server.ParticleAccelerator.Components; using JetBrains.Annotations; +using Robust.Server.Player; using Robust.Shared.Map.Components; using Robust.Shared.Physics.Events; -using Robust.Shared.Player; namespace Content.Server.ParticleAccelerator.EntitySystems; @@ -18,7 +18,7 @@ public sealed partial class ParticleAcceleratorSystem SubscribeLocalEvent(BodyTypeChanged); } - public void RescanParts(EntityUid uid, ICommonSession? user = null, ParticleAcceleratorControlBoxComponent? controller = null) + public void RescanParts(EntityUid uid, IPlayerSession? user = null, ParticleAcceleratorControlBoxComponent? controller = null) { if (!Resolve(uid, ref controller)) return; diff --git a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingManager.cs b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingManager.cs index bcc6f211ed..50c64e718c 100644 --- a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingManager.cs +++ b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingManager.cs @@ -5,18 +5,18 @@ using System.Threading.Tasks; using Content.Server.Database; using Content.Shared.CCVar; using Content.Shared.Players.PlayTimeTracking; +using Robust.Server.Player; using Robust.Shared.Asynchronous; using Robust.Shared.Collections; using Robust.Shared.Configuration; using Robust.Shared.Exceptions; using Robust.Shared.Network; -using Robust.Shared.Player; using Robust.Shared.Timing; using Robust.Shared.Utility; namespace Content.Server.Players.PlayTimeTracking; -public delegate void CalcPlayTimeTrackersCallback(ICommonSession player, HashSet trackers); +public delegate void CalcPlayTimeTrackersCallback(IPlayerSession player, HashSet trackers); /// /// Tracks play time for players, across all roles. @@ -66,7 +66,7 @@ public sealed class PlayTimeTrackingManager private ISawmill _sawmill = default!; // List of players that need some kind of update (refresh timers or resend). - private ValueList _playersDirty; + private ValueList _playersDirty; // DB auto-saving logic. private TimeSpan _saveInterval; @@ -76,7 +76,7 @@ public sealed class PlayTimeTrackingManager // We must block server shutdown on these to avoid losing data. private readonly List _pendingSaveTasks = new(); - private readonly Dictionary _playTimeData = new(); + private readonly Dictionary _playTimeData = new(); public event CalcPlayTimeTrackersCallback? CalcTrackers; @@ -139,7 +139,7 @@ public sealed class PlayTimeTrackingManager _playersDirty.Clear(); } - private void RefreshSingleTracker(ICommonSession dirty, PlayTimeData data, TimeSpan time) + private void RefreshSingleTracker(IPlayerSession dirty, PlayTimeData data, TimeSpan time) { DebugTools.Assert(data.Initialized); @@ -181,7 +181,7 @@ public sealed class PlayTimeTrackingManager /// so APIs like return up-to-date info. /// /// - public void FlushTracker(ICommonSession player) + public void FlushTracker(IPlayerSession player) { var time = _timing.RealTime; var data = _playTimeData[player]; @@ -201,7 +201,7 @@ public sealed class PlayTimeTrackingManager } } - private void SendPlayTimes(ICommonSession pSession) + private void SendPlayTimes(IPlayerSession pSession) { var roles = GetTrackerTimes(pSession); @@ -228,7 +228,7 @@ public sealed class PlayTimeTrackingManager /// /// Save all modified time trackers for a player to the database. /// - public async void SaveSession(ICommonSession session) + public async void SaveSession(IPlayerSession session) { // This causes all trackers to refresh, ah well. FlushAllTrackers(); @@ -278,7 +278,7 @@ public sealed class PlayTimeTrackingManager _sawmill.Debug($"Saved {log.Count} trackers"); } - private async Task DoSaveSessionAsync(ICommonSession session) + private async Task DoSaveSessionAsync(IPlayerSession session) { var log = new List(); @@ -299,7 +299,7 @@ public sealed class PlayTimeTrackingManager _sawmill.Debug($"Saved {log.Count} trackers for {session.Name}"); } - public async Task LoadData(ICommonSession session, CancellationToken cancel) + public async Task LoadData(IPlayerSession session, CancellationToken cancel) { var data = new PlayTimeData(); _playTimeData.Add(session, data); @@ -318,14 +318,14 @@ public sealed class PlayTimeTrackingManager QueueSendTimers(session); } - public void ClientDisconnected(ICommonSession session) + public void ClientDisconnected(IPlayerSession session) { SaveSession(session); _playTimeData.Remove(session); } - public void AddTimeToTracker(ICommonSession id, string tracker, TimeSpan time) + public void AddTimeToTracker(IPlayerSession id, string tracker, TimeSpan time) { if (!_playTimeData.TryGetValue(id, out var data) || !data.Initialized) throw new InvalidOperationException("Play time info is not yet loaded for this player!"); @@ -341,17 +341,17 @@ public sealed class PlayTimeTrackingManager data.DbTrackersDirty.Add(tracker); } - public void AddTimeToOverallPlaytime(ICommonSession id, TimeSpan time) + public void AddTimeToOverallPlaytime(IPlayerSession id, TimeSpan time) { AddTimeToTracker(id, PlayTimeTrackingShared.TrackerOverall, time); } - public TimeSpan GetOverallPlaytime(ICommonSession id) + public TimeSpan GetOverallPlaytime(IPlayerSession id) { return GetPlayTimeForTracker(id, PlayTimeTrackingShared.TrackerOverall); } - public bool TryGetTrackerTimes(ICommonSession id, [NotNullWhen(true)] out Dictionary? time) + public bool TryGetTrackerTimes(IPlayerSession id, [NotNullWhen(true)] out Dictionary? time) { time = null; @@ -364,7 +364,7 @@ public sealed class PlayTimeTrackingManager return true; } - public Dictionary GetTrackerTimes(ICommonSession id) + public Dictionary GetTrackerTimes(IPlayerSession id) { if (!_playTimeData.TryGetValue(id, out var data) || !data.Initialized) throw new InvalidOperationException("Play time info is not yet loaded for this player!"); @@ -372,7 +372,7 @@ public sealed class PlayTimeTrackingManager return data.TrackerTimes; } - public TimeSpan GetPlayTimeForTracker(ICommonSession id, string tracker) + public TimeSpan GetPlayTimeForTracker(IPlayerSession id, string tracker) { if (!_playTimeData.TryGetValue(id, out var data) || !data.Initialized) throw new InvalidOperationException("Play time info is not yet loaded for this player!"); @@ -383,7 +383,7 @@ public sealed class PlayTimeTrackingManager /// /// Queue for play time trackers to be refreshed on a player, in case the set of active trackers may have changed. /// - public void QueueRefreshTrackers(ICommonSession player) + public void QueueRefreshTrackers(IPlayerSession player) { if (DirtyPlayer(player) is { } data) data.NeedRefreshTackers = true; @@ -392,13 +392,13 @@ public sealed class PlayTimeTrackingManager /// /// Queue for play time information to be sent to a client, for showing in UIs etc. /// - public void QueueSendTimers(ICommonSession player) + public void QueueSendTimers(IPlayerSession player) { if (DirtyPlayer(player) is { } data) data.NeedSendTimers = true; } - private PlayTimeData? DirtyPlayer(ICommonSession player) + private PlayTimeData? DirtyPlayer(IPlayerSession player) { if (!_playTimeData.TryGetValue(player, out var data) || !data.Initialized) return null; diff --git a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs index f865b25bac..13d0794dd5 100644 --- a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs +++ b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs @@ -14,7 +14,6 @@ using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Network; -using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Utility; @@ -56,7 +55,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem _tracking.CalcTrackers -= CalcTrackers; } - private void CalcTrackers(ICommonSession player, HashSet trackers) + private void CalcTrackers(IPlayerSession player, HashSet trackers) { if (_afk.IsAfk(player)) return; @@ -68,7 +67,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem trackers.UnionWith(GetTimedRoles(player)); } - private bool IsPlayerAlive(ICommonSession session) + private bool IsPlayerAlive(IPlayerSession session) { var attached = session.AttachedEntity; if (attached == null) @@ -94,7 +93,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem } } - private IEnumerable GetTimedRoles(ICommonSession session) + private IEnumerable GetTimedRoles(IPlayerSession session) { var contentData = _playerManager.GetPlayerData(session.UserId).ContentData(); @@ -157,7 +156,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem _tracking.QueueSendTimers(ev.PlayerSession); } - public bool IsAllowed(ICommonSession player, string role) + public bool IsAllowed(IPlayerSession player, string role) { if (!_prototypes.TryIndex(role, out var job) || job.Requirements == null || @@ -169,7 +168,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem return JobRequirements.TryRequirementsMet(job, playTimes, out _, EntityManager, _prototypes); } - public HashSet GetDisallowedJobs(ICommonSession player) + public HashSet GetDisallowedJobs(IPlayerSession player) { var roles = new HashSet(); if (!_cfg.GetCVar(CCVars.GameRoleTimers)) @@ -231,7 +230,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem } } - public void PlayerRolesChanged(ICommonSession player) + public void PlayerRolesChanged(IPlayerSession player) { _tracking.QueueRefreshTrackers(player); } diff --git a/Content.Server/Players/PlayerData.cs b/Content.Server/Players/PlayerData.cs new file mode 100644 index 0000000000..b0ca6f3c18 --- /dev/null +++ b/Content.Server/Players/PlayerData.cs @@ -0,0 +1,30 @@ +using Content.Shared.Players; +using Robust.Server.Player; +using Robust.Shared.Players; + +namespace Content.Server.Players +{ + public static class PlayerDataExt + { + /// + /// Gets the correctly cast instance of content player data from an engine player data storage. + /// + public static PlayerData? ContentData(this IPlayerSession session) + { + return session.Data.ContentData(); + } + + public static PlayerData? ContentData(this ICommonSession session) + { + return ((IPlayerSession) session).ContentData(); + } + + /// + /// Gets the mind that is associated with this player. + /// + public static EntityUid? GetMind(this IPlayerSession session) + { + return session.Data.ContentData()?.Mind; + } + } +} diff --git a/Content.Server/Players/PlayerSystem.cs b/Content.Server/Players/PlayerSystem.cs index c79683c338..0c407aa876 100644 --- a/Content.Server/Players/PlayerSystem.cs +++ b/Content.Server/Players/PlayerSystem.cs @@ -1,11 +1,11 @@ using Content.Shared.Players; -using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Server.Players; public sealed class PlayerSystem : SharedPlayerSystem { - public override ContentPlayerData? ContentData(ICommonSession? session) + public override PlayerData? ContentData(ICommonSession? session) { return session?.ContentData(); } diff --git a/Content.Server/Pointing/EntitySystems/PointingSystem.cs b/Content.Server/Pointing/EntitySystems/PointingSystem.cs index 6fcdfcf994..b253e32e37 100644 --- a/Content.Server/Pointing/EntitySystems/PointingSystem.cs +++ b/Content.Server/Pointing/EntitySystems/PointingSystem.cs @@ -20,6 +20,7 @@ using Robust.Shared.Enums; using Robust.Shared.Input.Binding; using Robust.Shared.Map; using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Replays; using Robust.Shared.Timing; @@ -169,7 +170,7 @@ namespace Content.Server.Pointing.EntitySystems } // Get players that are in range and whose visibility layer matches the arrow's. - bool ViewerPredicate(ICommonSession playerSession) + bool ViewerPredicate(IPlayerSession playerSession) { if (!_minds.TryGetMind(playerSession, out _, out var mind) || mind.CurrentEntity is not { Valid: true } ent || @@ -181,7 +182,7 @@ namespace Content.Server.Pointing.EntitySystems } var viewers = Filter.Empty() - .AddWhere(session1 => ViewerPredicate(session1)) + .AddWhere(session1 => ViewerPredicate((IPlayerSession) session1)) .Recipients; string selfMessage; diff --git a/Content.Server/Popups/PopupSystem.cs b/Content.Server/Popups/PopupSystem.cs index 61ccaf4423..483d4f3d3f 100644 --- a/Content.Server/Popups/PopupSystem.cs +++ b/Content.Server/Popups/PopupSystem.cs @@ -4,6 +4,7 @@ using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Map; using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Server.Popups { diff --git a/Content.Server/Prayer/PrayerSystem.cs b/Content.Server/Prayer/PrayerSystem.cs index e20291cc06..be6ae80bfd 100644 --- a/Content.Server/Prayer/PrayerSystem.cs +++ b/Content.Server/Prayer/PrayerSystem.cs @@ -5,11 +5,12 @@ using Content.Server.Chat.Managers; using Content.Server.Popups; using Content.Shared.Database; using Content.Shared.Popups; +using Robust.Server.Player; +using Robust.Shared.Player; using Content.Shared.Chat; using Content.Shared.Prayer; using Content.Shared.Verbs; using Robust.Server.GameObjects; -using Robust.Shared.Player; namespace Content.Server.Prayer; /// @@ -73,7 +74,7 @@ public sealed class PrayerSystem : EntitySystem /// The IPlayerSession that sent the message /// The main message sent to the player via the chatbox /// The popup to notify the player, also prepended to the messageString - public void SendSubtleMessage(ICommonSession target, ICommonSession source, string messageString, string popupMessage) + public void SendSubtleMessage(IPlayerSession target, IPlayerSession source, string messageString, string popupMessage) { if (target.AttachedEntity == null) return; @@ -95,7 +96,7 @@ public sealed class PrayerSystem : EntitySystem /// You may be wondering, "Why the admin chat, specifically? Nobody even reads it!" /// Exactly. /// - public void Pray(ICommonSession sender, PrayableComponent comp, string message) + public void Pray(IPlayerSession sender, PrayableComponent comp, string message) { if (sender.AttachedEntity == null) return; diff --git a/Content.Server/Preferences/Managers/IServerPreferencesManager.cs b/Content.Server/Preferences/Managers/IServerPreferencesManager.cs index a36b053717..8c06e00ab1 100644 --- a/Content.Server/Preferences/Managers/IServerPreferencesManager.cs +++ b/Content.Server/Preferences/Managers/IServerPreferencesManager.cs @@ -2,8 +2,8 @@ using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; using Content.Shared.Preferences; +using Robust.Server.Player; using Robust.Shared.Network; -using Robust.Shared.Player; namespace Content.Server.Preferences.Managers { @@ -11,12 +11,12 @@ namespace Content.Server.Preferences.Managers { void Init(); - Task LoadData(ICommonSession session, CancellationToken cancel); - void OnClientDisconnected(ICommonSession session); + Task LoadData(IPlayerSession session, CancellationToken cancel); + void OnClientDisconnected(IPlayerSession session); bool TryGetCachedPreferences(NetUserId userId, [NotNullWhen(true)] out PlayerPreferences? playerPreferences); PlayerPreferences GetPreferences(NetUserId userId); IEnumerable> GetSelectedProfilesForPlayers(List userIds); - bool HavePreferencesLoaded(ICommonSession session); + bool HavePreferencesLoaded(IPlayerSession session); } } diff --git a/Content.Server/Preferences/Managers/ServerPreferencesManager.cs b/Content.Server/Preferences/Managers/ServerPreferencesManager.cs index a0b5e8ce65..ea04d00e82 100644 --- a/Content.Server/Preferences/Managers/ServerPreferencesManager.cs +++ b/Content.Server/Preferences/Managers/ServerPreferencesManager.cs @@ -8,9 +8,9 @@ using Content.Shared.CCVar; using Content.Shared.Humanoid.Prototypes; using Content.Shared.Preferences; using Content.Shared.Roles; +using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Network; -using Robust.Shared.Player; using Robust.Shared.Prototypes; @@ -167,7 +167,7 @@ namespace Content.Server.Preferences.Managers } // Should only be called via UserDbDataManager. - public async Task LoadData(ICommonSession session, CancellationToken cancel) + public async Task LoadData(IPlayerSession session, CancellationToken cancel) { if (!ShouldStorePrefs(session.ConnectedClient.AuthType)) { @@ -207,12 +207,12 @@ namespace Content.Server.Preferences.Managers } } - public void OnClientDisconnected(ICommonSession session) + public void OnClientDisconnected(IPlayerSession session) { _cachedPlayerPrefs.Remove(session.UserId); } - public bool HavePreferencesLoaded(ICommonSession session) + public bool HavePreferencesLoaded(IPlayerSession session) { return _cachedPlayerPrefs.ContainsKey(session.UserId); } diff --git a/Content.Server/Pulling/PullingSystem.cs b/Content.Server/Pulling/PullingSystem.cs index 69bb7c9370..f7ea0aae57 100644 --- a/Content.Server/Pulling/PullingSystem.cs +++ b/Content.Server/Pulling/PullingSystem.cs @@ -4,7 +4,7 @@ using Content.Shared.Pulling.Components; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Shared.Input.Binding; -using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Server.Pulling { diff --git a/Content.Server/Radiation/Systems/RadiationSystem.Debug.cs b/Content.Server/Radiation/Systems/RadiationSystem.Debug.cs index 56806d8c9c..97f2e485ca 100644 --- a/Content.Server/Radiation/Systems/RadiationSystem.Debug.cs +++ b/Content.Server/Radiation/Systems/RadiationSystem.Debug.cs @@ -7,7 +7,7 @@ using Content.Shared.Radiation.Systems; using Robust.Shared.Console; using Robust.Shared.Enums; using Robust.Shared.Map.Components; -using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Server.Radiation.Systems; diff --git a/Content.Server/Research/Systems/ResearchSystem.Client.cs b/Content.Server/Research/Systems/ResearchSystem.Client.cs index 135ef8fe88..e813f09ff9 100644 --- a/Content.Server/Research/Systems/ResearchSystem.Client.cs +++ b/Content.Server/Research/Systems/ResearchSystem.Client.cs @@ -1,6 +1,7 @@ using System.Diagnostics.CodeAnalysis; using Content.Server.Power.EntitySystems; using Content.Shared.Research.Components; +using Robust.Server.Player; namespace Content.Server.Research.Systems; @@ -45,7 +46,7 @@ public sealed partial class ResearchSystem if (!this.IsPowered(uid, EntityManager)) return; - _uiSystem.TryToggleUi(uid, ResearchClientUiKey.Key, args.Session); + _uiSystem.TryToggleUi(uid, ResearchClientUiKey.Key, (IPlayerSession) args.Session); } #endregion diff --git a/Content.Server/Salvage/SalvageRulerCommand.cs b/Content.Server/Salvage/SalvageRulerCommand.cs index a1fd609741..b0a64508c5 100644 --- a/Content.Server/Salvage/SalvageRulerCommand.cs +++ b/Content.Server/Salvage/SalvageRulerCommand.cs @@ -1,5 +1,6 @@ using Content.Server.Administration; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; @@ -25,7 +26,7 @@ sealed class SalvageRulerCommand : IConsoleCommand return; } - if (shell.Player is not { } player) + if (shell.Player is not IPlayerSession player) { shell.WriteError(Loc.GetString("shell-only-players-can-run-this-command")); return; diff --git a/Content.Server/Sandbox/Commands/ColorNetworkCommand.cs b/Content.Server/Sandbox/Commands/ColorNetworkCommand.cs index cc20b71946..0b9148f0fb 100644 --- a/Content.Server/Sandbox/Commands/ColorNetworkCommand.cs +++ b/Content.Server/Sandbox/Commands/ColorNetworkCommand.cs @@ -4,6 +4,7 @@ using Content.Server.Atmos.Piping.EntitySystems; using Content.Server.NodeContainer; using Content.Server.NodeContainer.NodeGroups; using Content.Shared.Administration; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Sandbox.Commands @@ -19,7 +20,7 @@ namespace Content.Server.Sandbox.Commands { var sandboxManager = EntitySystem.Get(); var adminManager = IoCManager.Resolve(); - if (shell.IsClient && (!sandboxManager.IsSandboxEnabled && !adminManager.HasAdminFlag(shell.Player!, AdminFlags.Mapping))) + if (shell.IsClient && (!sandboxManager.IsSandboxEnabled && !adminManager.HasAdminFlag((IPlayerSession)shell.Player!, AdminFlags.Mapping))) { shell.WriteError("You are not currently able to use mapping commands."); } diff --git a/Content.Server/Sandbox/SandboxSystem.cs b/Content.Server/Sandbox/SandboxSystem.cs index 194cf59843..ec9b1a0c3c 100644 --- a/Content.Server/Sandbox/SandboxSystem.cs +++ b/Content.Server/Sandbox/SandboxSystem.cs @@ -13,7 +13,6 @@ using Robust.Server.Console; using Robust.Server.Placement; using Robust.Server.Player; using Robust.Shared.Enums; -using Robust.Shared.Player; namespace Content.Server.Sandbox { diff --git a/Content.Server/SensorMonitoring/SensorMonitoringConsoleComponent.cs b/Content.Server/SensorMonitoring/SensorMonitoringConsoleComponent.cs index 63b4d9daef..cd4f2ea23b 100644 --- a/Content.Server/SensorMonitoring/SensorMonitoringConsoleComponent.cs +++ b/Content.Server/SensorMonitoring/SensorMonitoringConsoleComponent.cs @@ -1,7 +1,7 @@ using Content.Shared.SensorMonitoring; using Robust.Server.Player; using Robust.Shared.Collections; -using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Server.SensorMonitoring; diff --git a/Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.UI.cs b/Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.UI.cs index 6c0dddeb26..a09badcd59 100644 --- a/Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.UI.cs +++ b/Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.UI.cs @@ -1,5 +1,7 @@ using Content.Server.DeviceNetwork.Components; using Content.Shared.SensorMonitoring; +using Robust.Server.GameObjects; +using Robust.Server.Player; using Robust.Shared.Collections; using ConsoleUIState = Content.Shared.SensorMonitoring.SensorMonitoringConsoleBoundInterfaceState; using IncrementalUIState = Content.Shared.SensorMonitoring.SensorMonitoringIncrementalUpdate; @@ -128,7 +130,7 @@ public sealed partial class SensorMonitoringConsoleSystem if (!args.UiKey.Equals(SensorMonitoringConsoleUiKey.Key)) return; - if (args.Session is not { } player) + if (args.Session is not IPlayerSession player) return; component.InitialUIStateSent.Remove(player); diff --git a/Content.Server/ServerUpdates/ServerUpdateManager.cs b/Content.Server/ServerUpdates/ServerUpdateManager.cs index f4e54984e9..769c5d58d7 100644 --- a/Content.Server/ServerUpdates/ServerUpdateManager.cs +++ b/Content.Server/ServerUpdates/ServerUpdateManager.cs @@ -6,7 +6,6 @@ using Robust.Server.Player; using Robust.Server.ServerStatus; using Robust.Shared.Configuration; using Robust.Shared.Enums; -using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.ServerUpdates; diff --git a/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs b/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs index 3ef3d97a21..1a1debc9e3 100644 --- a/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs +++ b/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs @@ -20,6 +20,7 @@ using Content.Shared.Tag; using Content.Shared.Tiles; using Robust.Server.GameObjects; using Robust.Server.Maps; +using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Map; using Robust.Shared.Map.Components; @@ -139,7 +140,7 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem /// private void OnShuttleRequestPosition(EmergencyShuttleRequestPositionMessage msg, EntitySessionEventArgs args) { - if (!_admin.IsAdmin(args.SenderSession)) + if (!_admin.IsAdmin((IPlayerSession) args.SenderSession)) return; var player = args.SenderSession.AttachedEntity; diff --git a/Content.Server/Silicons/Borgs/BorgSystem.Modules.cs b/Content.Server/Silicons/Borgs/BorgSystem.Modules.cs index c080420266..31d826087d 100644 --- a/Content.Server/Silicons/Borgs/BorgSystem.Modules.cs +++ b/Content.Server/Silicons/Borgs/BorgSystem.Modules.cs @@ -229,7 +229,7 @@ public sealed partial class BorgSystem if (!TryComp(chassis, out var hands)) return; - if (TerminatingOrDeleted(uid)) + if (LifeStage(uid) >= EntityLifeStage.Terminating) { foreach (var (hand, item) in component.ProvidedItems) { diff --git a/Content.Server/Silicons/Borgs/BorgSystem.cs b/Content.Server/Silicons/Borgs/BorgSystem.cs index 883cb3b3d8..611dfa6ea2 100644 --- a/Content.Server/Silicons/Borgs/BorgSystem.cs +++ b/Content.Server/Silicons/Borgs/BorgSystem.cs @@ -21,7 +21,7 @@ using Content.Shared.Throwing; using Content.Shared.Wires; using Robust.Server.GameObjects; using Robust.Shared.Containers; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Random; namespace Content.Server.Silicons.Borgs; diff --git a/Content.Server/Silicons/Laws/SiliconLawSystem.cs b/Content.Server/Silicons/Laws/SiliconLawSystem.cs index 41ddd9651b..1d5c2e35e8 100644 --- a/Content.Server/Silicons/Laws/SiliconLawSystem.cs +++ b/Content.Server/Silicons/Laws/SiliconLawSystem.cs @@ -18,6 +18,7 @@ using Content.Shared.Silicons.Laws.Components; using Content.Shared.Stunnable; using Content.Shared.Wires; using Robust.Server.GameObjects; +using Robust.Server.Player; using Robust.Shared.Prototypes; using Robust.Shared.Toolshed; @@ -93,7 +94,7 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem HashSet? radioChannels = intrinsicRadio?.Channels; var state = new SiliconLawBuiState(GetLaws(uid), radioChannels); - _userInterface.TrySetUiState(args.Entity, SiliconLawsUiKey.Key, state, args.Session); + _userInterface.TrySetUiState(args.Entity, SiliconLawsUiKey.Key, state, (IPlayerSession) args.Session); } private void OnPlayerSpawnComplete(EntityUid uid, SiliconLawBoundComponent component, PlayerSpawnCompleteEvent args) @@ -169,7 +170,7 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem if (component.AntagonistRole == null) return; - _roles.MindTryRemoveRole(args.Mind); + _roles.MindTryRemoveRole(args.OldMindId); } private void EnsureEmaggedRole(EntityUid uid, EmagSiliconLawComponent component) diff --git a/Content.Server/Station/Systems/StationJobsSystem.cs b/Content.Server/Station/Systems/StationJobsSystem.cs index eeaace03b2..2709bc2072 100644 --- a/Content.Server/Station/Systems/StationJobsSystem.cs +++ b/Content.Server/Station/Systems/StationJobsSystem.cs @@ -41,7 +41,7 @@ public sealed partial class StationJobsSystem : EntitySystem if (_availableJobsDirty) { _cachedAvailableJobs = GenerateJobsAvailableEvent(); - RaiseNetworkEvent(_cachedAvailableJobs, Filter.Empty().AddPlayers(_playerManager.Sessions)); + RaiseNetworkEvent(_cachedAvailableJobs, Filter.Empty().AddPlayers(_playerManager.ServerSessions)); _availableJobsDirty = false; } } diff --git a/Content.Server/Storage/EntitySystems/StorageSystem.cs b/Content.Server/Storage/EntitySystems/StorageSystem.cs index 8b4ae1c76f..3430449957 100644 --- a/Content.Server/Storage/EntitySystems/StorageSystem.cs +++ b/Content.Server/Storage/EntitySystems/StorageSystem.cs @@ -9,6 +9,7 @@ using Content.Shared.Storage.EntitySystems; using Content.Shared.Timing; using Content.Shared.Verbs; using Robust.Server.GameObjects; +using Robust.Server.Player; using Robust.Shared.Map; using Robust.Shared.Player; using Robust.Shared.Prototypes; @@ -134,7 +135,7 @@ public sealed partial class StorageSystem : SharedStorageSystem /// If the user has nested-UIs open (e.g., PDA UI open when pda is in a backpack), close them. /// /// - public void CloseNestedInterfaces(EntityUid uid, ICommonSession session, StorageComponent? storageComp = null) + public void CloseNestedInterfaces(EntityUid uid, IPlayerSession session, StorageComponent? storageComp = null) { if (!Resolve(uid, ref storageComp)) return; diff --git a/Content.Server/Tabletop/TabletopSession.cs b/Content.Server/Tabletop/TabletopSession.cs index 5e7c6ac02e..d94b4fd657 100644 --- a/Content.Server/Tabletop/TabletopSession.cs +++ b/Content.Server/Tabletop/TabletopSession.cs @@ -1,6 +1,6 @@ using System.Numerics; +using Robust.Server.Player; using Robust.Shared.Map; -using Robust.Shared.Player; namespace Content.Server.Tabletop { @@ -17,7 +17,7 @@ namespace Content.Server.Tabletop /// /// The set of players currently playing this tabletop game. /// - public readonly Dictionary Players = new(); + public readonly Dictionary Players = new(); /// /// All entities bound to this session. If you create an entity for this session, you have to add it here. diff --git a/Content.Server/Tabletop/TabletopSystem.Session.cs b/Content.Server/Tabletop/TabletopSystem.Session.cs index 8f1bc7005d..e9dea0c66a 100644 --- a/Content.Server/Tabletop/TabletopSystem.Session.cs +++ b/Content.Server/Tabletop/TabletopSystem.Session.cs @@ -1,7 +1,7 @@ using System.Numerics; using Content.Server.Tabletop.Components; using Content.Shared.Tabletop.Events; -using Robust.Shared.Player; +using Robust.Server.Player; using Robust.Shared.Utility; namespace Content.Server.Tabletop @@ -66,7 +66,7 @@ namespace Content.Server.Tabletop /// /// The player session in question. /// The UID of the tabletop game entity. - public void OpenSessionFor(ICommonSession player, EntityUid uid) + public void OpenSessionFor(IPlayerSession player, EntityUid uid) { if (!EntityManager.TryGetComponent(uid, out TabletopGameComponent? tabletop) || player.AttachedEntity is not {Valid: true} attachedEntity) return; @@ -98,7 +98,7 @@ namespace Content.Server.Tabletop /// The player in question. /// The UID of the tabletop game entity. /// Whether to remove the from the player's attached entity. - public void CloseSessionFor(ICommonSession player, EntityUid uid, bool removeGamerComponent = true) + public void CloseSessionFor(IPlayerSession player, EntityUid uid, bool removeGamerComponent = true) { if (!EntityManager.TryGetComponent(uid, out TabletopGameComponent? tabletop) || tabletop.Session is not { } session) return; @@ -129,7 +129,7 @@ namespace Content.Server.Tabletop /// The player in question. /// An offset from the tabletop position for the camera. Zero by default. /// The UID of the camera entity. - private EntityUid CreateCamera(TabletopGameComponent tabletop, ICommonSession player, Vector2 offset = default) + private EntityUid CreateCamera(TabletopGameComponent tabletop, IPlayerSession player, Vector2 offset = default) { DebugTools.AssertNotNull(tabletop.Session); diff --git a/Content.Server/Tabletop/TabletopSystem.cs b/Content.Server/Tabletop/TabletopSystem.cs index b81331d62e..2e271080d0 100644 --- a/Content.Server/Tabletop/TabletopSystem.cs +++ b/Content.Server/Tabletop/TabletopSystem.cs @@ -9,6 +9,7 @@ using Content.Shared.Tabletop.Events; using Content.Shared.Verbs; using JetBrains.Annotations; using Robust.Server.GameObjects; +using Robust.Server.Player; using Robust.Shared.Enums; using Robust.Shared.Map; using Robust.Shared.Utility; @@ -41,7 +42,7 @@ namespace Content.Server.Tabletop private void OnTabletopRequestTakeOut(TabletopRequestTakeOut msg, EntitySessionEventArgs args) { - if (args.SenderSession is not { } playerSession) + if (args.SenderSession is not IPlayerSession playerSession) return; var table = GetEntity(msg.TableUid); @@ -104,7 +105,7 @@ namespace Content.Server.Tabletop protected override void OnTabletopMove(TabletopMoveEvent msg, EntitySessionEventArgs args) { - if (args.SenderSession is not { } playerSession) + if (args.SenderSession is not IPlayerSession playerSession) return; if (!TryComp(GetEntity(msg.TableUid), out TabletopGameComponent? tabletop) || tabletop.Session is not { } session) @@ -154,7 +155,7 @@ namespace Content.Server.Tabletop private void OnStopPlaying(TabletopStopPlayingEvent msg, EntitySessionEventArgs args) { - CloseSessionFor(args.SenderSession, GetEntity(msg.TableUid)); + CloseSessionFor((IPlayerSession)args.SenderSession, GetEntity(msg.TableUid)); } private void OnPlayerDetached(EntityUid uid, TabletopGamerComponent component, PlayerDetachedEvent args) diff --git a/Content.Server/Toolshed/Commands/AdminDebug/ACmdCommand.cs b/Content.Server/Toolshed/Commands/AdminDebug/ACmdCommand.cs index f113e49655..d2b3cc261c 100644 --- a/Content.Server/Toolshed/Commands/AdminDebug/ACmdCommand.cs +++ b/Content.Server/Toolshed/Commands/AdminDebug/ACmdCommand.cs @@ -1,7 +1,7 @@ using Content.Server.Administration; using Content.Server.Administration.Managers; using Content.Shared.Administration; -using Robust.Shared.Player; +using Robust.Server.Player; using Robust.Shared.Toolshed; using Robust.Shared.Toolshed.Syntax; @@ -25,7 +25,7 @@ public sealed class ACmdCommand : ToolshedCommand public bool CanInvoke( [CommandInvocationContext] IInvocationContext ctx, [PipedArgument] CommandSpec command, - [CommandArgument] ValueRef player + [CommandArgument] ValueRef player ) { // Deliberately discard the error. diff --git a/Content.Server/Toolshed/Commands/VisualizeCommand.cs b/Content.Server/Toolshed/Commands/VisualizeCommand.cs index 2225bfaf44..4ef08a91bf 100644 --- a/Content.Server/Toolshed/Commands/VisualizeCommand.cs +++ b/Content.Server/Toolshed/Commands/VisualizeCommand.cs @@ -4,6 +4,7 @@ using Content.Server.EUI; using Content.Shared.Administration; using Content.Shared.Bql; using Content.Shared.Eui; +using Robust.Server.Player; using Robust.Shared.Toolshed; using Robust.Shared.Toolshed.Errors; @@ -29,7 +30,7 @@ public sealed class VisualizeCommand : ToolshedCommand var ui = new ToolshedVisualizeEui( input.Select(e => (EntName(e), EntityManager.GetNetEntity(e))).ToArray() ); - _euiManager.OpenEui(ui, ctx.Session); + _euiManager.OpenEui(ui, (IPlayerSession) ctx.Session); _euiManager.QueueStateUpdate(ui); } } diff --git a/Content.Server/Traitor/Uplink/Commands/AddUplinkCommand.cs b/Content.Server/Traitor/Uplink/Commands/AddUplinkCommand.cs index fd656a9f71..1feab11b99 100644 --- a/Content.Server/Traitor/Uplink/Commands/AddUplinkCommand.cs +++ b/Content.Server/Traitor/Uplink/Commands/AddUplinkCommand.cs @@ -5,7 +5,6 @@ using Content.Shared.FixedPoint; using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Console; -using Robust.Shared.Player; namespace Content.Server.Traitor.Uplink.Commands { @@ -37,7 +36,7 @@ namespace Content.Server.Traitor.Uplink.Commands return; } - ICommonSession? session; + IPlayerSession? session; if (args.Length > 0) { // Get player entity @@ -49,7 +48,7 @@ namespace Content.Server.Traitor.Uplink.Commands } else { - session = shell.Player; + session = (IPlayerSession?) shell.Player; } if (session?.AttachedEntity is not { } user) diff --git a/Content.Server/UserInterface/ActivatableUIComponent.cs b/Content.Server/UserInterface/ActivatableUIComponent.cs index 34f9c0f397..bb020608e2 100644 --- a/Content.Server/UserInterface/ActivatableUIComponent.cs +++ b/Content.Server/UserInterface/ActivatableUIComponent.cs @@ -1,4 +1,4 @@ -using Robust.Shared.Player; +using Robust.Server.Player; using Robust.Shared.Reflection; using Robust.Shared.Serialization; @@ -65,7 +65,7 @@ namespace Content.Server.UserInterface /// NOTE: DO NOT DIRECTLY SET, USE ActivatableUISystem.SetCurrentSingleUser /// [ViewVariables] - public ICommonSession? CurrentSingleUser; + public IPlayerSession? CurrentSingleUser; void ISerializationHooks.AfterDeserialization() { diff --git a/Content.Server/UserInterface/ActivatableUISystem.cs b/Content.Server/UserInterface/ActivatableUISystem.cs index adeeed7c19..59086415b4 100644 --- a/Content.Server/UserInterface/ActivatableUISystem.cs +++ b/Content.Server/UserInterface/ActivatableUISystem.cs @@ -8,7 +8,7 @@ using Content.Shared.Interaction.Events; using Content.Shared.UserInterface; using Content.Shared.Verbs; using Robust.Server.GameObjects; -using Robust.Shared.Player; +using Robust.Server.Player; namespace Content.Server.UserInterface; @@ -173,7 +173,7 @@ public sealed partial class ActivatableUISystem : EntitySystem return true; } - public void SetCurrentSingleUser(EntityUid uid, ICommonSession? v, ActivatableUIComponent? aui = null) + public void SetCurrentSingleUser(EntityUid uid, IPlayerSession? v, ActivatableUIComponent? aui = null) { if (!Resolve(uid, ref aui)) return; @@ -231,9 +231,9 @@ public sealed class UserOpenActivatableUIAttemptEvent : CancellableEntityEventAr public sealed class AfterActivatableUIOpenEvent : EntityEventArgs { public EntityUid User { get; } - public readonly ICommonSession Session; + public readonly IPlayerSession Session; - public AfterActivatableUIOpenEvent(EntityUid who, ICommonSession session) + public AfterActivatableUIOpenEvent(EntityUid who, IPlayerSession session) { User = who; Session = session; diff --git a/Content.Server/UserInterface/StatValuesCommand.cs b/Content.Server/UserInterface/StatValuesCommand.cs index fe2ee380fe..b13b596323 100644 --- a/Content.Server/UserInterface/StatValuesCommand.cs +++ b/Content.Server/UserInterface/StatValuesCommand.cs @@ -8,6 +8,7 @@ using Content.Shared.Materials; using Content.Shared.Research.Prototypes; using Content.Shared.UserInterface; using Content.Shared.Weapons.Melee; +using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Prototypes; @@ -26,7 +27,7 @@ public sealed class StatValuesCommand : IConsoleCommand public string Help => $"{Command} "; public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not { } pSession) + if (shell.Player is not IPlayerSession pSession) { shell.WriteError(Loc.GetString("stat-values-server")); return; diff --git a/Content.Server/Verbs/VerbSystem.cs b/Content.Server/Verbs/VerbSystem.cs index e304c6b4af..6d12b08e86 100644 --- a/Content.Server/Verbs/VerbSystem.cs +++ b/Content.Server/Verbs/VerbSystem.cs @@ -6,6 +6,7 @@ using Content.Shared.Administration.Logs; using Content.Shared.Database; using Content.Shared.Hands.Components; using Content.Shared.Verbs; +using Robust.Server.Player; namespace Content.Server.Verbs { @@ -24,7 +25,7 @@ namespace Content.Server.Verbs private void HandleVerbRequest(RequestServerVerbsEvent args, EntitySessionEventArgs eventArgs) { - var player = eventArgs.SenderSession; + var player = (IPlayerSession) eventArgs.SenderSession; if (!EntityManager.EntityExists(GetEntity(args.EntityUid))) { @@ -42,7 +43,7 @@ namespace Content.Server.Verbs // this, and some verbs (e.g. view variables) won't even care about whether an entity is accessible through // the entity menu or not. - var force = args.AdminRequest && eventArgs.SenderSession is { } playerSession && + var force = args.AdminRequest && eventArgs.SenderSession is IPlayerSession playerSession && _adminMgr.HasAdminFlag(playerSession, AdminFlags.Admin); List verbTypes = new(); diff --git a/Content.Server/Voting/IVoteHandle.cs b/Content.Server/Voting/IVoteHandle.cs index 869f2017d7..13f64e6ef8 100644 --- a/Content.Server/Voting/IVoteHandle.cs +++ b/Content.Server/Voting/IVoteHandle.cs @@ -1,5 +1,5 @@ using Content.Server.Voting.Managers; -using Robust.Shared.Player; +using Robust.Server.Player; namespace Content.Server.Voting { @@ -75,7 +75,7 @@ namespace Content.Server.Voting /// /// is not a valid option ID. /// - void CastVote(ICommonSession session, int? optionId); + void CastVote(IPlayerSession session, int? optionId); /// /// Cancel this vote. diff --git a/Content.Server/Voting/Managers/IVoteManager.cs b/Content.Server/Voting/Managers/IVoteManager.cs index d95fac9ae9..6a92e70fff 100644 --- a/Content.Server/Voting/Managers/IVoteManager.cs +++ b/Content.Server/Voting/Managers/IVoteManager.cs @@ -1,6 +1,6 @@ using System.Diagnostics.CodeAnalysis; using Content.Shared.Voting; -using Robust.Shared.Player; +using Robust.Server.Player; namespace Content.Server.Voting.Managers { @@ -41,7 +41,7 @@ namespace Content.Server.Voting.Managers /// True if can start votes right now, /// and if provided if they can start votes of type . /// - bool CanCallVote(ICommonSession initiator, StandardVoteType? voteType = null); + bool CanCallVote(IPlayerSession initiator, StandardVoteType? voteType = null); /// /// Initiate a standard vote such as restart round, that can be initiated by players. @@ -51,7 +51,7 @@ namespace Content.Server.Voting.Managers /// If null it is assumed to be an automatic vote by the server. /// /// The type of standard vote to make. - void CreateStandardVote(ICommonSession? initiator, StandardVoteType voteType); + void CreateStandardVote(IPlayerSession? initiator, StandardVoteType voteType); /// /// Create a non-standard vote with special parameters. diff --git a/Content.Server/Voting/Managers/VoteManager.DefaultVotes.cs b/Content.Server/Voting/Managers/VoteManager.DefaultVotes.cs index e1bffa769d..55e88e2a8c 100644 --- a/Content.Server/Voting/Managers/VoteManager.DefaultVotes.cs +++ b/Content.Server/Voting/Managers/VoteManager.DefaultVotes.cs @@ -6,8 +6,8 @@ using Content.Server.RoundEnd; using Content.Shared.CCVar; using Content.Shared.Database; using Content.Shared.Voting; +using Robust.Server.Player; using Robust.Shared.Configuration; -using Robust.Shared.Player; using Robust.Shared.Random; namespace Content.Server.Voting.Managers @@ -21,7 +21,7 @@ namespace Content.Server.Voting.Managers {StandardVoteType.Map, CCVars.VoteMapEnabled}, }; - public void CreateStandardVote(ICommonSession? initiator, StandardVoteType voteType) + public void CreateStandardVote(IPlayerSession? initiator, StandardVoteType voteType) { if (initiator != null) _adminLogger.Add(LogType.Vote, LogImpact.Medium, $"{initiator} initiated a {voteType.ToString()} vote"); @@ -47,7 +47,7 @@ namespace Content.Server.Voting.Managers TimeoutStandardVote(voteType); } - private void CreateRestartVote(ICommonSession? initiator) + private void CreateRestartVote(IPlayerSession? initiator) { var alone = _playerManager.PlayerCount == 1 && initiator != null; var options = new VoteOptions @@ -100,7 +100,7 @@ namespace Content.Server.Voting.Managers vote.CastVote(initiator, 0); } - foreach (var player in _playerManager.Sessions) + foreach (var player in _playerManager.ServerSessions) { if (player != initiator) { @@ -110,7 +110,7 @@ namespace Content.Server.Voting.Managers } } - private void CreatePresetVote(ICommonSession? initiator) + private void CreatePresetVote(IPlayerSession? initiator) { var presets = GetGamePresets(); @@ -156,7 +156,7 @@ namespace Content.Server.Voting.Managers }; } - private void CreateMapVote(ICommonSession? initiator) + private void CreateMapVote(IPlayerSession? initiator) { var maps = _gameMapManager.CurrentlyEligibleMaps().ToDictionary(map => map, map => map.MapName); diff --git a/Content.Server/Voting/Managers/VoteManager.cs b/Content.Server/Voting/Managers/VoteManager.cs index 90089afb54..98ad8d8341 100644 --- a/Content.Server/Voting/Managers/VoteManager.cs +++ b/Content.Server/Voting/Managers/VoteManager.cs @@ -16,7 +16,6 @@ using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Network; -using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -46,7 +45,7 @@ namespace Content.Server.Voting.Managers private readonly Dictionary _standardVoteTimeout = new(); private readonly Dictionary _voteTimeout = new(); - private readonly HashSet _playerCanCallVoteDirty = new(); + private readonly HashSet _playerCanCallVoteDirty = new(); private readonly StandardVoteType[] _standardVoteTypeValues = Enum.GetValues(); public void Initialize() @@ -107,7 +106,7 @@ namespace Content.Server.Voting.Managers } } - private void CastVote(VoteReg v, ICommonSession player, int? option) + private void CastVote(VoteReg v, IPlayerSession player, int? option) { if (!IsValidOption(v, option)) throw new ArgumentOutOfRangeException(nameof(option), "Invalid vote option ID"); @@ -229,7 +228,7 @@ namespace Content.Server.Voting.Managers private void SendUpdates(VoteReg v) { - foreach (var player in _playerManager.Sessions) + foreach (var player in _playerManager.ServerSessions) { SendSingleUpdate(v, player); } @@ -238,7 +237,7 @@ namespace Content.Server.Voting.Managers v.Dirty = false; } - private void SendSingleUpdate(VoteReg v, ICommonSession player) + private void SendSingleUpdate(VoteReg v, IPlayerSession player) { var msg = new MsgVoteData(); @@ -278,10 +277,10 @@ namespace Content.Server.Voting.Managers private void DirtyCanCallVoteAll() { - _playerCanCallVoteDirty.UnionWith(_playerManager.Sessions); + _playerCanCallVoteDirty.UnionWith(_playerManager.ServerSessions); } - private void SendUpdateCanCallVote(ICommonSession player) + private void SendUpdateCanCallVote(IPlayerSession player) { var msg = new MsgVoteCanCall(); msg.CanCall = CanCallVote(player, null, out var isAdmin, out var timeSpan); @@ -307,7 +306,7 @@ namespace Content.Server.Voting.Managers } private bool CanCallVote( - ICommonSession initiator, + IPlayerSession initiator, StandardVoteType? voteType, out bool isAdmin, out TimeSpan timeSpan) @@ -354,7 +353,7 @@ namespace Content.Server.Voting.Managers return !_voteTimeout.TryGetValue(initiator.UserId, out timeSpan); } - public bool CanCallVote(ICommonSession initiator, StandardVoteType? voteType = null) + public bool CanCallVote(IPlayerSession initiator, StandardVoteType? voteType = null) { return CanCallVote(initiator, voteType, out _, out _); } @@ -407,14 +406,14 @@ namespace Content.Server.Voting.Managers return false; } - private void DirtyCanCallVote(ICommonSession player) + private void DirtyCanCallVote(IPlayerSession player) { _playerCanCallVoteDirty.Add(player); } #region Preset Votes - private void WirePresetVoteInitiator(VoteOptions options, ICommonSession? player) + private void WirePresetVoteInitiator(VoteOptions options, IPlayerSession? player) { if (player != null) { @@ -433,13 +432,13 @@ namespace Content.Server.Voting.Managers private sealed class VoteReg { public readonly int Id; - public readonly Dictionary CastVotes = new(); + public readonly Dictionary CastVotes = new(); public readonly VoteEntry[] Entries; public readonly string Title; public readonly string InitiatorText; public readonly TimeSpan StartTime; public readonly TimeSpan EndTime; - public readonly HashSet VotesDirty = new(); + public readonly HashSet VotesDirty = new(); public bool Cancelled; public bool Finished; @@ -447,10 +446,10 @@ namespace Content.Server.Voting.Managers public VoteFinishedEventHandler? OnFinished; public VoteCancelledEventHandler? OnCancelled; - public ICommonSession? Initiator { get; } + public IPlayerSession? Initiator { get; } public VoteReg(int id, VoteEntry[] entries, string title, string initiatorText, - ICommonSession? initiator, TimeSpan start, TimeSpan end) + IPlayerSession? initiator, TimeSpan start, TimeSpan end) { Id = id; Entries = entries; @@ -518,7 +517,7 @@ namespace Content.Server.Voting.Managers return _mgr.IsValidOption(_reg, optionId); } - public void CastVote(ICommonSession session, int? optionId) + public void CastVote(IPlayerSession session, int? optionId) { _mgr.CastVote(_reg, session, optionId); } diff --git a/Content.Server/Voting/VoteCommands.cs b/Content.Server/Voting/VoteCommands.cs index 498c9d0494..cb296a7d58 100644 --- a/Content.Server/Voting/VoteCommands.cs +++ b/Content.Server/Voting/VoteCommands.cs @@ -6,6 +6,7 @@ using Content.Server.Voting.Managers; using Content.Shared.Administration; using Content.Shared.Database; using Content.Shared.Voting; +using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Voting @@ -35,14 +36,14 @@ namespace Content.Server.Voting var mgr = IoCManager.Resolve(); - if (shell.Player != null && !mgr.CanCallVote(shell.Player, type)) + if (shell.Player != null && !mgr.CanCallVote((IPlayerSession) shell.Player, type)) { _adminLogger.Add(LogType.Vote, LogImpact.Medium, $"{shell.Player} failed to start {type.ToString()} vote"); shell.WriteError(Loc.GetString("cmd-createvote-cannot-call-vote-now")); return; } - mgr.CreateStandardVote(shell.Player, type); + mgr.CreateStandardVote((IPlayerSession?) shell.Player, type); } public CompletionResult GetCompletion(IConsoleShell shell, string[] args) @@ -91,7 +92,7 @@ namespace Content.Server.Voting options.Options.Add((args[i], i)); } - options.SetInitiatorOrServer(shell.Player); + options.SetInitiatorOrServer((IPlayerSession?) shell.Player); if (shell.Player != null) _adminLogger.Add(LogType.Vote, LogImpact.Medium, $"{shell.Player} initiated a custom vote: {options.Title} - {string.Join("; ", options.Options.Select(x => x.text))}"); @@ -186,7 +187,7 @@ namespace Content.Server.Voting return; } - vote.CastVote(shell.Player!, optionN); + vote.CastVote((IPlayerSession) shell.Player!, optionN); } } diff --git a/Content.Server/Voting/VoteOptions.cs b/Content.Server/Voting/VoteOptions.cs index 5475d10d32..6e6d0465ed 100644 --- a/Content.Server/Voting/VoteOptions.cs +++ b/Content.Server/Voting/VoteOptions.cs @@ -1,4 +1,4 @@ -using Robust.Shared.Player; +using Robust.Server.Player; namespace Content.Server.Voting @@ -16,7 +16,7 @@ namespace Content.Server.Voting /// /// The player that started the vote. Used to keep track of player cooldowns to avoid vote spam. /// - public ICommonSession? InitiatorPlayer { get; set; } + public IPlayerSession? InitiatorPlayer { get; set; } /// /// The shown title of the vote. @@ -43,13 +43,13 @@ namespace Content.Server.Voting /// Sets and /// by setting the latter to the player's name. /// - public void SetInitiator(ICommonSession player) + public void SetInitiator(IPlayerSession player) { InitiatorPlayer = player; InitiatorText = player.Name; } - public void SetInitiatorOrServer(ICommonSession? player) + public void SetInitiatorOrServer(IPlayerSession? player) { if (player != null) { diff --git a/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs b/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs index 3d9c3e8219..1b6b2ebef1 100644 --- a/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs +++ b/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs @@ -24,9 +24,11 @@ using Content.Shared.StatusEffect; using Content.Shared.Tag; using Content.Shared.Weapons.Melee; using Content.Shared.Weapons.Melee.Events; +using Robust.Server.Player; using Robust.Shared.Audio; using Robust.Shared.Map; using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Random; namespace Content.Server.Weapons.Melee; @@ -172,7 +174,7 @@ public sealed class MeleeWeaponSystem : SharedMeleeWeaponSystem EntityCoordinates targetCoordinates; Angle targetLocalAngle; - if (session is { } pSession) + if (session is IPlayerSession pSession) { (targetCoordinates, targetLocalAngle) = _lag.GetCoordinatesAngle(target, pSession); } diff --git a/Content.Server/Wires/WiresSystem.cs b/Content.Server/Wires/WiresSystem.cs index b6452efa8a..e75ad0a9ef 100644 --- a/Content.Server/Wires/WiresSystem.cs +++ b/Content.Server/Wires/WiresSystem.cs @@ -16,7 +16,7 @@ using Content.Shared.Tools; using Content.Shared.Tools.Components; using Content.Shared.Wires; using Robust.Server.GameObjects; -using Robust.Shared.Player; +using Robust.Server.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; @@ -616,7 +616,7 @@ public sealed class WiresSystem : SharedWiresSystem wires.WireSeed), ui: ui); } - public void OpenUserInterface(EntityUid uid, ICommonSession player) + public void OpenUserInterface(EntityUid uid, IPlayerSession player) { if (_uiSystem.TryGetUi(uid, WiresUiKey.Key, out var ui)) _uiSystem.OpenUi(ui, player); diff --git a/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs b/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs index 9200928d66..49036fb19d 100644 --- a/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs +++ b/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs @@ -17,6 +17,7 @@ using Content.Shared.Xenoarchaeology.Equipment; using Content.Shared.Xenoarchaeology.XenoArtifacts; using JetBrains.Annotations; using Robust.Server.GameObjects; +using Robust.Server.Player; using Robust.Shared.Audio; using Robust.Shared.Prototypes; using Robust.Shared.Timing; @@ -228,7 +229,7 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem /// private void OnServerSelectionMessage(EntityUid uid, AnalysisConsoleComponent component, AnalysisConsoleServerSelectionMessage args) { - _ui.TryOpen(uid, ResearchClientUiKey.Key, args.Session); + _ui.TryOpen(uid, ResearchClientUiKey.Key, (IPlayerSession) args.Session); } /// diff --git a/Content.Shared/Administration/Managers/ISharedAdminManager.cs b/Content.Shared/Administration/Managers/ISharedAdminManager.cs index 22d918d4a3..7e01c81433 100644 --- a/Content.Shared/Administration/Managers/ISharedAdminManager.cs +++ b/Content.Shared/Administration/Managers/ISharedAdminManager.cs @@ -1,4 +1,4 @@ -using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Shared.Administration.Managers; diff --git a/Content.Shared/Buckle/SharedBuckleSystem.cs b/Content.Shared/Buckle/SharedBuckleSystem.cs index 1441745b5d..7edf2448ae 100644 --- a/Content.Shared/Buckle/SharedBuckleSystem.cs +++ b/Content.Shared/Buckle/SharedBuckleSystem.cs @@ -11,7 +11,7 @@ using Robust.Shared.Containers; using Robust.Shared.Map; using Robust.Shared.Network; using Robust.Shared.Physics.Systems; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Timing; namespace Content.Shared.Buckle; diff --git a/Content.Shared/Hands/EntitySystems/SharedHandsSystem.Interactions.cs b/Content.Shared/Hands/EntitySystems/SharedHandsSystem.Interactions.cs index dfa72fcfb7..d0c3be3b31 100644 --- a/Content.Shared/Hands/EntitySystems/SharedHandsSystem.Interactions.cs +++ b/Content.Shared/Hands/EntitySystems/SharedHandsSystem.Interactions.cs @@ -6,7 +6,7 @@ using Content.Shared.Input; using Content.Shared.Localizations; using Robust.Shared.Input.Binding; using Robust.Shared.Map; -using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Shared.Hands.EntitySystems; diff --git a/Content.Shared/Interaction/SharedInteractionSystem.cs b/Content.Shared/Interaction/SharedInteractionSystem.cs index 7981deaee6..4a9a43ca2c 100644 --- a/Content.Shared/Interaction/SharedInteractionSystem.cs +++ b/Content.Shared/Interaction/SharedInteractionSystem.cs @@ -34,7 +34,7 @@ using Robust.Shared.Network; using Robust.Shared.Physics; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Random; using Robust.Shared.Serialization; using Robust.Shared.Timing; diff --git a/Content.Shared/Mind/Components/MindContainerComponent.cs b/Content.Shared/Mind/Components/MindContainerComponent.cs index 62b26cbd35..ca0f14d994 100644 --- a/Content.Shared/Mind/Components/MindContainerComponent.cs +++ b/Content.Shared/Mind/Components/MindContainerComponent.cs @@ -1,25 +1,24 @@ using System.Diagnostics.CodeAnalysis; -using Robust.Shared.GameStates; namespace Content.Shared.Mind.Components { /// - /// This component indicates that this entity may have mind, which is simply an entity with a . - /// The mind entity is not actually stored in a "container", but is simply stored in nullspace. + /// Stores a on a mob. /// - [RegisterComponent, Access(typeof(SharedMindSystem)), NetworkedComponent, AutoGenerateComponentState] + [RegisterComponent, Access(typeof(SharedMindSystem))] public sealed partial class MindContainerComponent : Component { /// /// The mind controlling this mob. Can be null. /// - [DataField, AutoNetworkedField] + [ViewVariables] [Access(typeof(SharedMindSystem), Other = AccessPermissions.ReadWriteExecute)] // FIXME Friends public EntityUid? Mind { get; set; } /// /// True if we have a mind, false otherwise. /// + [ViewVariables] [MemberNotNullWhen(true, nameof(Mind))] public bool HasMind => Mind != null; @@ -27,7 +26,7 @@ namespace Content.Shared.Mind.Components /// Whether examining should show information about the mind or not. /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("showExamineInfo"), AutoNetworkedField] + [DataField("showExamineInfo")] public bool ShowExamineInfo { get; set; } /// @@ -39,59 +38,19 @@ namespace Content.Shared.Mind.Components public bool GhostOnShutdown { get; set; } = true; } - public abstract class MindEvent : EntityEventArgs + public sealed class MindRemovedMessage : EntityEventArgs { - public readonly Entity Mind; - public readonly Entity Container; + public EntityUid OldMindId; + public MindComponent OldMind; - public MindEvent(Entity mind, Entity container) + public MindRemovedMessage(EntityUid oldMindId, MindComponent oldMind) { - Mind = mind; - Container = container; + OldMindId = oldMindId; + OldMind = oldMind; } } - /// - /// Event raised directed at a mind-container when a mind gets removed. - /// - public sealed class MindRemovedMessage : MindEvent + public sealed class MindAddedMessage : EntityEventArgs { - public MindRemovedMessage(Entity mind, Entity container) - : base(mind, container) - { - } - } - - /// - /// Event raised directed at a mind when it gets removed from a mind-container. - /// - public sealed class MindGotRemovedEvent : MindEvent - { - public MindGotRemovedEvent(Entity mind, Entity container) - : base(mind, container) - { - } - } - - /// - /// Event raised directed at a mind-container when a mind gets added. - /// - public sealed class MindAddedMessage : MindEvent - { - public MindAddedMessage(Entity mind, Entity container) - : base(mind, container) - { - } - } - - /// - /// Event raised directed at a mind when it gets added to a mind-container. - /// - public sealed class MindGotAddedEvent : MindEvent - { - public MindGotAddedEvent(Entity mind, Entity container) - : base(mind, container) - { - } } } diff --git a/Content.Shared/Mind/MindComponent.cs b/Content.Shared/Mind/MindComponent.cs index b147a2dbbe..3ea92c3ce7 100644 --- a/Content.Shared/Mind/MindComponent.cs +++ b/Content.Shared/Mind/MindComponent.cs @@ -1,86 +1,84 @@ using Content.Shared.GameTicking; using Content.Shared.Mind.Components; -using Robust.Shared.GameStates; using Robust.Shared.Network; -using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Shared.Mind { /// - /// This component stores information about a player/mob mind. The component will be attached to a mind-entity - /// which is stored in null-space. The entity that is currently "possessed" by the mind will have a - /// . + /// This is added as a component to mind entities, not to player entities. + /// for the one that is added to players. + /// A mind represents the IC "mind" of a player. + /// Roles are attached as components to its owning entity. /// /// - /// Roles are attached as components on the mind-entity entity. /// Think of it like this: if a player is supposed to have their memories, /// their mind follows along. /// /// Things such as respawning do not follow, because you're a new character. /// Getting borged, cloned, turned into a catbeast, etc... will keep it following you. - /// - /// Minds are stored in null-space, and are thus generally not set to players unless that player is the owner - /// of the mind. As a result it should be safe to network "secret" information like roles & objectives /// - [RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] + [RegisterComponent] public sealed partial class MindComponent : Component { - [DataField, AutoNetworkedField] - public List Objectives = new(); + internal readonly List Objectives = new(); /// /// The session ID of the player owning this mind. /// - [DataField, AutoNetworkedField, Access(typeof(SharedMindSystem))] + [ViewVariables, Access(typeof(SharedMindSystem))] public NetUserId? UserId { get; set; } /// /// The session ID of the original owner, if any. /// May end up used for round-end information (as the owner may have abandoned Mind since) /// - [DataField, AutoNetworkedField, Access(typeof(SharedMindSystem))] + [ViewVariables, Access(typeof(SharedMindSystem))] public NetUserId? OriginalOwnerUserId { get; set; } /// - /// The first entity that this mind controlled. Used for round end information. + /// Entity UID for the first entity that this mind controlled. Used for round end. /// Might be relevant if the player has ghosted since. /// - [DataField, AutoNetworkedField] - public NetEntity? OriginalOwnedEntity; - // This is a net entity, because this field currently ddoes not get set to null when this entity is deleted. - // This is a lazy way to ensure that people check that the entity still exists. - // TODO MIND Fix this properly by adding an OriginalMindContainerComponent or something like that. + [ViewVariables] public EntityUid? OriginalOwnedEntity; [ViewVariables] public bool IsVisitingEntity => VisitingEntity != null; - [DataField, AutoNetworkedField, Access(typeof(SharedMindSystem))] + [ViewVariables, Access(typeof(SharedMindSystem))] public EntityUid? VisitingEntity { get; set; } [ViewVariables] public EntityUid? CurrentEntity => VisitingEntity ?? OwnedEntity; - [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)] + [ViewVariables(VVAccess.ReadWrite)] public string? CharacterName { get; set; } /// /// The time of death for this Mind. /// Can be null - will be null if the Mind is not considered "dead". /// - [DataField] + [ViewVariables] public TimeSpan? TimeOfDeath { get; set; } + /// + /// The component currently owned by this mind. + /// Can be null. + /// + [ViewVariables] public MindContainerComponent? OwnedComponent; + /// /// The entity currently owned by this mind. /// Can be null. /// - [DataField, AutoNetworkedField, Access(typeof(SharedMindSystem))] + [ViewVariables, Access(typeof(SharedMindSystem))] public EntityUid? OwnedEntity { get; set; } + // TODO move objectives out of mind component /// /// An enumerable over all the objective entities this mind has. /// - [ViewVariables, Obsolete("Use Objectives field")] + [ViewVariables] public IEnumerable AllObjectives => Objectives; /// @@ -102,7 +100,6 @@ namespace Content.Shared.Mind /// Can be null, in which case the player is currently not logged in. /// [ViewVariables, Access(typeof(SharedMindSystem), typeof(SharedGameTicker))] - // TODO remove this after moving IPlayerManager functions to shared public ICommonSession? Session { get; set; } } } diff --git a/Content.Shared/Mind/SharedMindSystem.cs b/Content.Shared/Mind/SharedMindSystem.cs index 66a0325963..cc4ac4af23 100644 --- a/Content.Shared/Mind/SharedMindSystem.cs +++ b/Content.Shared/Mind/SharedMindSystem.cs @@ -1,5 +1,4 @@ using System.Diagnostics.CodeAnalysis; -using System.Linq; using Content.Shared.Administration.Logs; using Content.Shared.Database; using Content.Shared.Examine; @@ -13,7 +12,7 @@ using Content.Shared.Objectives.Systems; using Content.Shared.Players; using Robust.Shared.Map; using Robust.Shared.Network; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Utility; namespace Content.Shared.Mind; @@ -26,7 +25,7 @@ public abstract class SharedMindSystem : EntitySystem [Dependency] private readonly SharedPlayerSystem _player = default!; [Dependency] private readonly MetaDataSystem _metadata = default!; - [ViewVariables] + // This is dictionary is required to track the minds of disconnected players that may have had their entity deleted. protected readonly Dictionary UserMinds = new(); public override void Initialize() @@ -37,7 +36,6 @@ public abstract class SharedMindSystem : EntitySystem SubscribeLocalEvent(OnSuicide); SubscribeLocalEvent(OnVisitingTerminating); SubscribeLocalEvent(OnReset); - SubscribeLocalEvent(OnMindStartup); } public override void Shutdown() @@ -46,29 +44,6 @@ public abstract class SharedMindSystem : EntitySystem WipeAllMinds(); } - private void OnMindStartup(EntityUid uid, MindComponent component, ComponentStartup args) - { - if (component.UserId == null) - return; - - if (UserMinds.TryAdd(component.UserId.Value, uid)) - return; - - var existing = UserMinds[component.UserId.Value]; - if (existing == uid) - return; - - if (!Exists(existing)) - { - Log.Error($"Found deleted entity in mind dictionary while initializing mind {ToPrettyString(uid)}"); - UserMinds[component.UserId.Value] = uid; - return; - } - - Log.Error($"Encountered a user {component.UserId} that is already assigned to a mind while initializing mind {ToPrettyString(uid)}. Ignoring user field."); - component.UserId = null; - } - private void OnReset(RoundRestartCleanupEvent ev) { WipeAllMinds(); @@ -76,22 +51,12 @@ public abstract class SharedMindSystem : EntitySystem public virtual void WipeAllMinds() { - Log.Info($"Wiping all minds"); - foreach (var mind in UserMinds.Values.ToArray()) + foreach (var mind in UserMinds.Values) { WipeMind(mind); } - if (UserMinds.Count == 0) - return; - - foreach (var mind in UserMinds.Values) - { - if (Exists(mind)) - Log.Error($"Failed to wipe mind: {ToPrettyString(mind)}"); - } - - UserMinds.Clear(); + DebugTools.Assert(UserMinds.Count == 0); } public EntityUid? GetMind(NetUserId user) @@ -115,26 +80,6 @@ public abstract class SharedMindSystem : EntitySystem return false; } - public bool TryGetMind(NetUserId user, [NotNullWhen(true)] out Entity? mind) - { - if (!TryGetMind(user, out var mindId, out var mindComp)) - { - mind = null; - return false; - } - - mind = (mindId.Value, mindComp); - return true; - } - - public Entity GetOrCreateMind(NetUserId user) - { - if (!TryGetMind(user, out var mind)) - mind = CreateMind(user); - - return mind.Value; - } - private void OnVisitingTerminating(EntityUid uid, VisitingMindComponent component, ref EntityTerminatingEvent args) { if (component.MindId != null) @@ -183,7 +128,7 @@ public abstract class SharedMindSystem : EntitySystem return null; } - public Entity CreateMind(NetUserId? userId, string? name = null) + public EntityUid CreateMind(NetUserId? userId, string? name = null) { var mindId = Spawn(null, MapCoordinates.Nullspace); _metadata.SetEntityName(mindId, name == null ? "mind" : $"mind ({name})"); @@ -191,7 +136,7 @@ public abstract class SharedMindSystem : EntitySystem mind.CharacterName = name; SetUserId(mindId, userId, mind); - return (mindId, mind); + return mindId; } /// @@ -250,7 +195,7 @@ public abstract class SharedMindSystem : EntitySystem /// Cleans up the VisitingEntity. /// /// - protected void RemoveVisitingEntity(EntityUid mindId, MindComponent mind) + protected void RemoveVisitingEntity(MindComponent mind) { if (mind.VisitingEntity == null) return; @@ -265,7 +210,6 @@ public abstract class SharedMindSystem : EntitySystem RemCompDeferred(oldVisitingEnt, visitComp); } - Dirty(mindId, mind); RaiseLocalEvent(oldVisitingEnt, new MindUnvisitedMessage(), true); } @@ -284,7 +228,7 @@ public abstract class SharedMindSystem : EntitySystem if (mindId == null || !Resolve(mindId.Value, ref mind, false)) return; - TransferTo(mindId.Value, null, createGhost:false, mind: mind); + TransferTo(mindId.Value, null, mind: mind); SetUserId(mindId.Value, null, mind: mind); } @@ -409,11 +353,11 @@ public abstract class SharedMindSystem : EntitySystem } public bool TryGetMind( - ContentPlayerData contentPlayer, + PlayerData player, out EntityUid mindId, [NotNullWhen(true)] out MindComponent? mind) { - mindId = contentPlayer.Mind ?? default; + mindId = player.Mind ?? default; return TryComp(mindId, out mind); } @@ -447,6 +391,21 @@ public abstract class SharedMindSystem : EntitySystem return TryComp(mindContainer.Mind, out role); } + /// + /// Sets the Mind's OwnedComponent and OwnedEntity + /// + /// Mind to set OwnedComponent and OwnedEntity on + /// Entity owned by + /// MindContainerComponent owned by + protected void SetOwnedEntity(MindComponent mind, EntityUid? uid, MindContainerComponent? mindContainerComponent) + { + if (uid != null) + Resolve(uid.Value, ref mindContainerComponent); + + mind.OwnedEntity = uid; + mind.OwnedComponent = mindContainerComponent; + } + /// /// Sets the Mind's UserId, Session, and updates the player's PlayerData. This should have no direct effect on the /// entity that any mind is connected to, except as a side effect of the fact that it may change a player's diff --git a/Content.Shared/Movement/Events/MoveInputEvent.cs b/Content.Shared/Movement/Events/MoveInputEvent.cs index 89e5636acd..8e1b43f8bd 100644 --- a/Content.Shared/Movement/Events/MoveInputEvent.cs +++ b/Content.Shared/Movement/Events/MoveInputEvent.cs @@ -1,3 +1,5 @@ +using Robust.Shared.Players; + namespace Content.Shared.Movement.Events; /// diff --git a/Content.Shared/Movement/Systems/SharedContentEyeSystem.cs b/Content.Shared/Movement/Systems/SharedContentEyeSystem.cs index 4b81619fd0..27e0080c87 100644 --- a/Content.Shared/Movement/Systems/SharedContentEyeSystem.cs +++ b/Content.Shared/Movement/Systems/SharedContentEyeSystem.cs @@ -5,7 +5,7 @@ using Content.Shared.Ghost; using Content.Shared.Input; using Content.Shared.Movement.Components; using Robust.Shared.Input.Binding; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Serialization; namespace Content.Shared.Movement.Systems; diff --git a/Content.Shared/Movement/Systems/SharedMoverController.Input.cs b/Content.Shared/Movement/Systems/SharedMoverController.Input.cs index 1d323a9187..425322408e 100644 --- a/Content.Shared/Movement/Systems/SharedMoverController.Input.cs +++ b/Content.Shared/Movement/Systems/SharedMoverController.Input.cs @@ -6,7 +6,7 @@ using Content.Shared.Movement.Components; using Content.Shared.Movement.Events; using Robust.Shared.Input; using Robust.Shared.Input.Binding; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Serialization; using Robust.Shared.Timing; using Robust.Shared.Utility; diff --git a/Content.Shared/Players/ContentPlayerData.cs b/Content.Shared/Players/PlayerData.cs similarity index 73% rename from Content.Shared/Players/ContentPlayerData.cs rename to Content.Shared/Players/PlayerData.cs index 7545eb58fc..c6274c950b 100644 --- a/Content.Shared/Players/ContentPlayerData.cs +++ b/Content.Shared/Players/PlayerData.cs @@ -1,15 +1,16 @@ using Content.Shared.GameTicking; using Content.Shared.Mind; using Robust.Shared.Network; +using Robust.Shared.Player; namespace Content.Shared.Players; /// /// Content side for all data that tracks a player session. -/// Use to retrieve this from an . +/// Use to retrieve this from an . /// Not currently used on the client. /// -public sealed class ContentPlayerData +public sealed class PlayerData { /// /// The session ID of the player owning this data. @@ -37,9 +38,21 @@ public sealed class ContentPlayerData /// public bool ExplicitlyDeadminned { get; set; } - public ContentPlayerData(NetUserId userId, string name) + public PlayerData(NetUserId userId, string name) { UserId = userId; Name = name; } -} \ No newline at end of file +} + + +public static class PlayerDataExt +{ + /// + /// Gets the correctly cast instance of content player data from an engine player data storage. + /// + public static PlayerData? ContentData(this IPlayerData data) + { + return (PlayerData?) data.ContentDataUncast; + } +} diff --git a/Content.Shared/Players/PlayerDataExt.cs b/Content.Shared/Players/PlayerDataExt.cs deleted file mode 100644 index eba4d8339d..0000000000 --- a/Content.Shared/Players/PlayerDataExt.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Robust.Shared.Player; - -namespace Content.Shared.Players; - -public static class PlayerDataExt -{ - /// - /// Gets the correctly cast instance of content player data from an engine player data storage. - /// - public static ContentPlayerData? ContentData(this SessionData data) - { - return (ContentPlayerData?) data.ContentDataUncast; - } - - /// - /// Gets the correctly cast instance of content player data from an engine player data storage. - /// - public static ContentPlayerData? ContentData(this ICommonSession session) - { - return session.Data.ContentData(); - } - - /// - /// Gets the mind that is associated with this player. - /// - public static EntityUid? GetMind(this ICommonSession session) - { - return session.Data.ContentData()?.Mind; - } -} \ No newline at end of file diff --git a/Content.Shared/Players/SharedPlayerSystem.cs b/Content.Shared/Players/SharedPlayerSystem.cs index 7271c5688a..6fc7ad6a40 100644 --- a/Content.Shared/Players/SharedPlayerSystem.cs +++ b/Content.Shared/Players/SharedPlayerSystem.cs @@ -1,4 +1,4 @@ -using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Shared.Players; @@ -8,5 +8,5 @@ namespace Content.Shared.Players; /// public abstract class SharedPlayerSystem : EntitySystem { - public abstract ContentPlayerData? ContentData(ICommonSession? session); + public abstract PlayerData? ContentData(ICommonSession? session); } diff --git a/Content.Shared/Popups/SharedPopupSystem.cs b/Content.Shared/Popups/SharedPopupSystem.cs index e4565b90e8..50013a5435 100644 --- a/Content.Shared/Popups/SharedPopupSystem.cs +++ b/Content.Shared/Popups/SharedPopupSystem.cs @@ -1,5 +1,6 @@ using Robust.Shared.Map; using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Serialization; namespace Content.Shared.Popups diff --git a/Content.Shared/Pulling/Systems/SharedPullingSystem.cs b/Content.Shared/Pulling/Systems/SharedPullingSystem.cs index 0c139ee9e3..6f19d048b4 100644 --- a/Content.Shared/Pulling/Systems/SharedPullingSystem.cs +++ b/Content.Shared/Pulling/Systems/SharedPullingSystem.cs @@ -12,7 +12,7 @@ using Robust.Shared.Map; using Robust.Shared.Physics; using Robust.Shared.Physics.Events; using Robust.Shared.Physics.Systems; -using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Shared.Pulling { diff --git a/Content.Shared/Roles/Jobs/SharedJobSystem.cs b/Content.Shared/Roles/Jobs/SharedJobSystem.cs index af97ea1350..ac18d04e9c 100644 --- a/Content.Shared/Roles/Jobs/SharedJobSystem.cs +++ b/Content.Shared/Roles/Jobs/SharedJobSystem.cs @@ -2,7 +2,7 @@ using System.Linq; using Content.Shared.Players; using Content.Shared.Players.PlayTimeTracking; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Utility; diff --git a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs index 62af6067d0..4b740b8d3c 100644 --- a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs +++ b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs @@ -23,7 +23,7 @@ using Robust.Shared.Audio; using Robust.Shared.Map; using Robust.Shared.Physics; using Robust.Shared.Physics.Systems; -using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Timing; diff --git a/RobustToolbox b/RobustToolbox index 9750b113c8..554e0777b1 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit 9750b113c81e7535d892326568760bc976072436 +Subproject commit 554e0777b1ba6ba096d8f4407d5c35ecc7b0f22f From 0880145ac8e891f517b3d7837105c35f080faba0 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Wed, 25 Oct 2023 01:23:56 +1100 Subject: [PATCH 029/102] Mind tweaks & fixes (#21203) --- Content.Client/Mind/MindSystem.cs | 20 +++++ .../Tests/Minds/MindTests.cs | 19 ++--- .../Administration/Commands/ControlMob.cs | 11 +-- .../Administration/Systems/AdminVerbSystem.cs | 13 +-- .../GameTicking/GameTicker.RoundFlow.cs | 3 +- Content.Server/Mind/Commands/RenameCommand.cs | 1 + Content.Server/Mind/MindSystem.cs | 82 ++++++++++++------ .../Silicons/Laws/SiliconLawSystem.cs | 2 +- .../Mind/Components/MindContainerComponent.cs | 65 +++++++++++--- Content.Shared/Mind/MindComponent.cs | 47 +++++----- Content.Shared/Mind/SharedMindSystem.cs | 85 ++++++++++++++----- 11 files changed, 237 insertions(+), 111 deletions(-) diff --git a/Content.Client/Mind/MindSystem.cs b/Content.Client/Mind/MindSystem.cs index 87d9e9ddbe..cc43c349e4 100644 --- a/Content.Client/Mind/MindSystem.cs +++ b/Content.Client/Mind/MindSystem.cs @@ -4,4 +4,24 @@ namespace Content.Client.Mind; public sealed class MindSystem : SharedMindSystem { + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnHandleState); + } + + private void OnHandleState(EntityUid uid, MindComponent component, ref AfterAutoHandleStateEvent args) + { + // Because minds are generally not networked, there might be weird situations were a client thinks multiple + // users share a mind? E.g., if an admin periodical gets sent all minds via some PVS override, but doesn't get + // sent intermediate states? Not sure if this is actually possible, but better to be safe. + foreach (var (user, mind) in UserMinds) + { + if (mind == uid) + UserMinds.Remove(user); + } + + if (component.UserId != null) + UserMinds[component.UserId.Value] = uid; + } } diff --git a/Content.IntegrationTests/Tests/Minds/MindTests.cs b/Content.IntegrationTests/Tests/Minds/MindTests.cs index fb2fef43ed..3ad61bcdf0 100644 --- a/Content.IntegrationTests/Tests/Minds/MindTests.cs +++ b/Content.IntegrationTests/Tests/Minds/MindTests.cs @@ -67,13 +67,12 @@ public sealed partial class MindTests var entity = entMan.SpawnEntity(null, new MapCoordinates()); var mindComp = entMan.EnsureComponent(entity); - var mindId = mindSystem.CreateMind(null); - var mind = entMan.GetComponent(mindId); + var mind = mindSystem.CreateMind(null); - Assert.That(mind.UserId, Is.EqualTo(null)); + Assert.That(mind.Comp.UserId, Is.EqualTo(null)); - mindSystem.TransferTo(mindId, entity, mind: mind); - Assert.That(mindSystem.GetMind(entity, mindComp), Is.EqualTo(mindId)); + mindSystem.TransferTo(mind, entity, mind: mind); + Assert.That(mindSystem.GetMind(entity, mindComp), Is.EqualTo(mind.Owner)); }); await pair.CleanReturnAsync(); @@ -94,11 +93,11 @@ public sealed partial class MindTests var entity = entMan.SpawnEntity(null, new MapCoordinates()); var mindComp = entMan.EnsureComponent(entity); - var mindId = mindSystem.CreateMind(null); + var mindId = mindSystem.CreateMind(null).Owner; mindSystem.TransferTo(mindId, entity); Assert.That(mindSystem.GetMind(entity, mindComp), Is.EqualTo(mindId)); - var mind2 = mindSystem.CreateMind(null); + var mind2 = mindSystem.CreateMind(null).Owner; mindSystem.TransferTo(mind2, entity); Assert.Multiple(() => { @@ -184,7 +183,7 @@ public sealed partial class MindTests var mindComp = entMan.EnsureComponent(entity); entMan.EnsureComponent(targetEntity); - var mind = mindSystem.CreateMind(null); + var mind = mindSystem.CreateMind(null).Owner; mindSystem.TransferTo(mind, entity); @@ -276,7 +275,7 @@ public sealed partial class MindTests var entity = entMan.SpawnEntity(null, new MapCoordinates()); var mindComp = entMan.EnsureComponent(entity); - var mindId = mindSystem.CreateMind(null); + var mindId = mindSystem.CreateMind(null).Owner; var mind = entMan.EnsureComponent(mindId); Assert.That(mind.UserId, Is.EqualTo(null)); @@ -334,7 +333,7 @@ public sealed partial class MindTests public async Task TestPlayerCanGhost() { // Client is needed to spawn session - await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true }); + await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true, DummyTicker = false }); var server = pair.Server; var entMan = server.ResolveDependency(); diff --git a/Content.Server/Administration/Commands/ControlMob.cs b/Content.Server/Administration/Commands/ControlMob.cs index 2d205e44d3..8fc74c61d4 100644 --- a/Content.Server/Administration/Commands/ControlMob.cs +++ b/Content.Server/Administration/Commands/ControlMob.cs @@ -1,5 +1,5 @@ +using Content.Server.Mind; using Content.Shared.Administration; -using Content.Shared.Mind; using Robust.Server.Player; using Robust.Shared.Console; @@ -42,14 +42,7 @@ namespace Content.Server.Administration.Commands return; } - var mindSystem = _entities.System(); - if (!mindSystem.TryGetMind(target, out var mindId, out var mind)) - { - shell.WriteLine(Loc.GetString("shell-entity-is-not-mob")); - return; - } - - mindSystem.TransferTo(mindId, target, mind: mind); + _entities.System().ControlMob(player.UserId, target); } } } diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.cs b/Content.Server/Administration/Systems/AdminVerbSystem.cs index c7e23374a3..0f0c562356 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.cs @@ -6,6 +6,7 @@ using Content.Server.Disposal.Tube; using Content.Server.Disposal.Tube.Components; using Content.Server.EUI; using Content.Server.Ghost.Roles; +using Content.Server.Mind; using Content.Server.Mind.Commands; using Content.Server.Prayer; using Content.Server.Xenoarchaeology.XenoArtifacts; @@ -18,7 +19,6 @@ using Content.Shared.Database; using Content.Shared.Examine; using Content.Shared.GameTicking; using Content.Shared.Inventory; -using Content.Shared.Mind; using Content.Shared.Mind.Components; using Content.Shared.Popups; using Content.Shared.Verbs; @@ -56,7 +56,7 @@ namespace Content.Server.Administration.Systems [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; [Dependency] private readonly PrayerSystem _prayerSystem = default!; [Dependency] private readonly EuiManager _eui = default!; - [Dependency] private readonly SharedMindSystem _mindSystem = default!; + [Dependency] private readonly MindSystem _mindSystem = default!; [Dependency] private readonly ToolshedManager _toolshed = default!; [Dependency] private readonly RejuvenateSystem _rejuvenate = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; @@ -277,12 +277,7 @@ namespace Content.Server.Administration.Systems // TODO VERB ICON control mob icon Act = () => { - MakeSentientCommand.MakeSentient(args.Target, EntityManager); - - if (!_minds.TryGetMind(player, out var mindId, out var mind)) - return; - - _mindSystem.TransferTo(mindId, args.Target, ghostCheckOverride: true, mind: mind); + _mindSystem.ControlMob(args.User, args.Target); }, Impact = LogImpact.High, ConfirmationPopup = true @@ -358,7 +353,7 @@ namespace Content.Server.Administration.Systems var message = ExamineSystemShared.InRangeUnOccluded(args.User, args.Target) ? Loc.GetString("in-range-unoccluded-verb-on-activate-not-occluded") : Loc.GetString("in-range-unoccluded-verb-on-activate-occluded"); - + _popup.PopupEntity(message, args.Target, args.User); } }; diff --git a/Content.Server/GameTicking/GameTicker.RoundFlow.cs b/Content.Server/GameTicking/GameTicker.RoundFlow.cs index df2aafa901..a10196a43e 100644 --- a/Content.Server/GameTicking/GameTicker.RoundFlow.cs +++ b/Content.Server/GameTicking/GameTicker.RoundFlow.cs @@ -360,8 +360,7 @@ namespace Content.Server.GameTicking else if (mind.CurrentEntity != null && TryName(mind.CurrentEntity.Value, out var icName)) playerIcName = icName; - var entity = mind.OriginalOwnedEntity; - if (Exists(entity)) + if (TryGetEntity(mind.OriginalOwnedEntity, out var entity)) _pvsOverride.AddGlobalOverride(entity.Value, recursive: true); var roles = _roles.MindGetAllRoles(mindId); diff --git a/Content.Server/Mind/Commands/RenameCommand.cs b/Content.Server/Mind/Commands/RenameCommand.cs index 5674da4ffd..2d65adc508 100644 --- a/Content.Server/Mind/Commands/RenameCommand.cs +++ b/Content.Server/Mind/Commands/RenameCommand.cs @@ -54,6 +54,7 @@ public sealed class RenameCommand : IConsoleCommand { // Mind mind.CharacterName = name; + _entManager.Dirty(mindId, mind); } // Id Cards diff --git a/Content.Server/Mind/MindSystem.cs b/Content.Server/Mind/MindSystem.cs index 373007fd1b..d2721db7b6 100644 --- a/Content.Server/Mind/MindSystem.cs +++ b/Content.Server/Mind/MindSystem.cs @@ -1,6 +1,7 @@ using System.Diagnostics.CodeAnalysis; using Content.Server.Administration.Logs; using Content.Server.GameTicking; +using Content.Server.Mind.Commands; using Content.Shared.Database; using Content.Shared.Ghost; using Content.Shared.Mind; @@ -46,20 +47,14 @@ public sealed class MindSystem : SharedMindSystem mind.UserId = null; } - if (!TryComp(mind.OwnedEntity, out MetaDataComponent? meta) || meta.EntityLifeStage >= EntityLifeStage.Terminating) - return; + if (mind.OwnedEntity != null && !TerminatingOrDeleted(mind.OwnedEntity.Value)) + TransferTo(uid, null, mind: mind, createGhost: false); - RaiseLocalEvent(mind.OwnedEntity.Value, new MindRemovedMessage(uid, mind), true); mind.OwnedEntity = null; - mind.OwnedComponent = null; } private void OnMindContainerTerminating(EntityUid uid, MindContainerComponent component, ref EntityTerminatingEvent args) { - // Let's not create ghosts if not in the middle of the round. - if (_gameTicker.RunLevel == GameRunLevel.PreRoundLobby) - return; - if (!TryGetMind(uid, out var mindId, out var mind, component)) return; @@ -77,6 +72,11 @@ public sealed class MindSystem : SharedMindSystem TransferTo(mindId, null, createGhost: false, mind: mind); + // Let's not create ghosts if not in the middle of the round. + if (_gameTicker.RunLevel == GameRunLevel.PreRoundLobby) + return; + + // I just love convoluted entity shutdown logic that results in more entities being spawned. if (component.GhostOnShutdown && mind.Session != null) { var xform = Transform(uid); @@ -198,7 +198,7 @@ public sealed class MindSystem : SharedMindSystem if (mind.VisitingEntity == null) return; - RemoveVisitingEntity(mind); + RemoveVisitingEntity(mindId, mind); if (mind.Session == null || mind.Session.AttachedEntity == mind.VisitingEntity) return; @@ -219,11 +219,10 @@ public sealed class MindSystem : SharedMindSystem if (mind == null && !Resolve(mindId, ref mind)) return; - base.TransferTo(mindId, entity, ghostCheckOverride, createGhost, mind); - if (entity == mind.OwnedEntity) return; + Dirty(mindId, mind); MindContainerComponent? component = null; var alreadyAttached = false; @@ -247,27 +246,33 @@ public sealed class MindSystem : SharedMindSystem } else if (createGhost) { + // TODO remove this option. + // Transfer-to-null should just detach a mind. + // If people want to create a ghost, that should be done explicitly via some TransferToGhost() method, not + // not implicitly via optional arguments. + var position = Deleted(mind.OwnedEntity) ? _gameTicker.GetObserverSpawnPoint().ToMap(EntityManager, _transform) : Transform(mind.OwnedEntity.Value).MapPosition; entity = Spawn("MobObserver", position); + component = EnsureComp(entity.Value); var ghostComponent = Comp(entity.Value); _ghosts.SetCanReturnToBody(ghostComponent, false); } - var oldComp = mind.OwnedComponent; var oldEntity = mind.OwnedEntity; - if (oldComp != null && oldEntity != null) + if (TryComp(oldEntity, out MindContainerComponent? oldContainer)) { - if (oldComp.Mind != null) - _pvsOverride.ClearOverride(oldComp.Mind.Value); - oldComp.Mind = null; - RaiseLocalEvent(oldEntity.Value, new MindRemovedMessage(oldEntity.Value, mind), true); + oldContainer.Mind = null; + mind.OwnedEntity = null; + Entity mindEnt = (mindId, mind); + Entity containerEnt = (oldEntity.Value, oldContainer); + RaiseLocalEvent(oldEntity.Value, new MindRemovedMessage(mindEnt, containerEnt)); + RaiseLocalEvent(mindId, new MindGotRemovedEvent(mindEnt, containerEnt)); + Dirty(oldEntity.Value, oldContainer); } - SetOwnedEntity(mind, entity, component); - // Don't do the full deletion cleanup if we're transferring to our VisitingEntity if (alreadyAttached) { @@ -281,7 +286,7 @@ public sealed class MindSystem : SharedMindSystem || !TryComp(mind.VisitingEntity!, out GhostComponent? ghostComponent) // visiting entity is not a Ghost || !ghostComponent.CanReturnToBody)) // it is a ghost, but cannot return to body anyway, so it's okay { - RemoveVisitingEntity(mind); + RemoveVisitingEntity(mindId, mind); } // Player is CURRENTLY connected. @@ -292,11 +297,16 @@ public sealed class MindSystem : SharedMindSystem Log.Info($"Session {session.Name} transferred to entity {entity}."); } - if (mind.OwnedComponent != null) + if (entity != null) { - mind.OwnedComponent.Mind = mindId; - RaiseLocalEvent(mind.OwnedEntity!.Value, new MindAddedMessage(), true); - mind.OriginalOwnedEntity ??= mind.OwnedEntity; + component!.Mind = mindId; + mind.OwnedEntity = entity; + mind.OriginalOwnedEntity ??= GetNetEntity(mind.OwnedEntity); + Entity mindEnt = (mindId, mind); + Entity containerEnt = (entity.Value, component); + RaiseLocalEvent(entity.Value, new MindAddedMessage(mindEnt, containerEnt)); + RaiseLocalEvent(mindId, new MindGotAddedEvent(mindEnt, containerEnt)); + Dirty(entity.Value, component); } } @@ -313,6 +323,7 @@ public sealed class MindSystem : SharedMindSystem if (mind.UserId == userId) return; + Dirty(mindId, mind); _pvsOverride.ClearOverride(mindId); if (userId != null && !_players.TryGetPlayerData(userId.Value, out _)) { @@ -363,4 +374,27 @@ public sealed class MindSystem : SharedMindSystem if (_players.GetPlayerData(userId.Value).ContentData() is { } data) data.Mind = mindId; } + + public void ControlMob(EntityUid user, EntityUid target) + { + if (TryComp(user, out ActorComponent? actor)) + ControlMob(actor.PlayerSession.UserId, target); + } + + public void ControlMob(NetUserId user, EntityUid target) + { + var (mindId, mind) = GetOrCreateMind(user); + + if (mind.CurrentEntity == target) + return; + + if (mind.OwnedEntity == target) + { + UnVisit(mindId, mind); + return; + } + + MakeSentientCommand.MakeSentient(target, EntityManager); + TransferTo(mindId, target, ghostCheckOverride: true, mind: mind); + } } diff --git a/Content.Server/Silicons/Laws/SiliconLawSystem.cs b/Content.Server/Silicons/Laws/SiliconLawSystem.cs index 1d5c2e35e8..beb760ec8f 100644 --- a/Content.Server/Silicons/Laws/SiliconLawSystem.cs +++ b/Content.Server/Silicons/Laws/SiliconLawSystem.cs @@ -170,7 +170,7 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem if (component.AntagonistRole == null) return; - _roles.MindTryRemoveRole(args.OldMindId); + _roles.MindTryRemoveRole(args.Mind); } private void EnsureEmaggedRole(EntityUid uid, EmagSiliconLawComponent component) diff --git a/Content.Shared/Mind/Components/MindContainerComponent.cs b/Content.Shared/Mind/Components/MindContainerComponent.cs index ca0f14d994..62b26cbd35 100644 --- a/Content.Shared/Mind/Components/MindContainerComponent.cs +++ b/Content.Shared/Mind/Components/MindContainerComponent.cs @@ -1,24 +1,25 @@ using System.Diagnostics.CodeAnalysis; +using Robust.Shared.GameStates; namespace Content.Shared.Mind.Components { /// - /// Stores a on a mob. + /// This component indicates that this entity may have mind, which is simply an entity with a . + /// The mind entity is not actually stored in a "container", but is simply stored in nullspace. /// - [RegisterComponent, Access(typeof(SharedMindSystem))] + [RegisterComponent, Access(typeof(SharedMindSystem)), NetworkedComponent, AutoGenerateComponentState] public sealed partial class MindContainerComponent : Component { /// /// The mind controlling this mob. Can be null. /// - [ViewVariables] + [DataField, AutoNetworkedField] [Access(typeof(SharedMindSystem), Other = AccessPermissions.ReadWriteExecute)] // FIXME Friends public EntityUid? Mind { get; set; } /// /// True if we have a mind, false otherwise. /// - [ViewVariables] [MemberNotNullWhen(true, nameof(Mind))] public bool HasMind => Mind != null; @@ -26,7 +27,7 @@ namespace Content.Shared.Mind.Components /// Whether examining should show information about the mind or not. /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("showExamineInfo")] + [DataField("showExamineInfo"), AutoNetworkedField] public bool ShowExamineInfo { get; set; } /// @@ -38,19 +39,59 @@ namespace Content.Shared.Mind.Components public bool GhostOnShutdown { get; set; } = true; } - public sealed class MindRemovedMessage : EntityEventArgs + public abstract class MindEvent : EntityEventArgs { - public EntityUid OldMindId; - public MindComponent OldMind; + public readonly Entity Mind; + public readonly Entity Container; - public MindRemovedMessage(EntityUid oldMindId, MindComponent oldMind) + public MindEvent(Entity mind, Entity container) { - OldMindId = oldMindId; - OldMind = oldMind; + Mind = mind; + Container = container; } } - public sealed class MindAddedMessage : EntityEventArgs + /// + /// Event raised directed at a mind-container when a mind gets removed. + /// + public sealed class MindRemovedMessage : MindEvent { + public MindRemovedMessage(Entity mind, Entity container) + : base(mind, container) + { + } + } + + /// + /// Event raised directed at a mind when it gets removed from a mind-container. + /// + public sealed class MindGotRemovedEvent : MindEvent + { + public MindGotRemovedEvent(Entity mind, Entity container) + : base(mind, container) + { + } + } + + /// + /// Event raised directed at a mind-container when a mind gets added. + /// + public sealed class MindAddedMessage : MindEvent + { + public MindAddedMessage(Entity mind, Entity container) + : base(mind, container) + { + } + } + + /// + /// Event raised directed at a mind when it gets added to a mind-container. + /// + public sealed class MindGotAddedEvent : MindEvent + { + public MindGotAddedEvent(Entity mind, Entity container) + : base(mind, container) + { + } } } diff --git a/Content.Shared/Mind/MindComponent.cs b/Content.Shared/Mind/MindComponent.cs index 3ea92c3ce7..465db6a3d8 100644 --- a/Content.Shared/Mind/MindComponent.cs +++ b/Content.Shared/Mind/MindComponent.cs @@ -1,84 +1,86 @@ using Content.Shared.GameTicking; using Content.Shared.Mind.Components; +using Robust.Shared.GameStates; using Robust.Shared.Network; using Robust.Shared.Players; namespace Content.Shared.Mind { /// - /// This is added as a component to mind entities, not to player entities. - /// for the one that is added to players. - /// A mind represents the IC "mind" of a player. - /// Roles are attached as components to its owning entity. + /// This component stores information about a player/mob mind. The component will be attached to a mind-entity + /// which is stored in null-space. The entity that is currently "possessed" by the mind will have a + /// . /// /// + /// Roles are attached as components on the mind-entity entity. /// Think of it like this: if a player is supposed to have their memories, /// their mind follows along. /// /// Things such as respawning do not follow, because you're a new character. /// Getting borged, cloned, turned into a catbeast, etc... will keep it following you. + /// + /// Minds are stored in null-space, and are thus generally not set to players unless that player is the owner + /// of the mind. As a result it should be safe to network "secret" information like roles & objectives /// - [RegisterComponent] + [RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] public sealed partial class MindComponent : Component { - internal readonly List Objectives = new(); + [DataField, AutoNetworkedField] + public List Objectives = new(); /// /// The session ID of the player owning this mind. /// - [ViewVariables, Access(typeof(SharedMindSystem))] + [DataField, AutoNetworkedField, Access(typeof(SharedMindSystem))] public NetUserId? UserId { get; set; } /// /// The session ID of the original owner, if any. /// May end up used for round-end information (as the owner may have abandoned Mind since) /// - [ViewVariables, Access(typeof(SharedMindSystem))] + [DataField, AutoNetworkedField, Access(typeof(SharedMindSystem))] public NetUserId? OriginalOwnerUserId { get; set; } /// - /// Entity UID for the first entity that this mind controlled. Used for round end. + /// The first entity that this mind controlled. Used for round end information. /// Might be relevant if the player has ghosted since. /// - [ViewVariables] public EntityUid? OriginalOwnedEntity; + [DataField, AutoNetworkedField] + public NetEntity? OriginalOwnedEntity; + // This is a net entity, because this field currently ddoes not get set to null when this entity is deleted. + // This is a lazy way to ensure that people check that the entity still exists. + // TODO MIND Fix this properly by adding an OriginalMindContainerComponent or something like that. [ViewVariables] public bool IsVisitingEntity => VisitingEntity != null; - [ViewVariables, Access(typeof(SharedMindSystem))] + [DataField, AutoNetworkedField, Access(typeof(SharedMindSystem))] public EntityUid? VisitingEntity { get; set; } [ViewVariables] public EntityUid? CurrentEntity => VisitingEntity ?? OwnedEntity; - [ViewVariables(VVAccess.ReadWrite)] + [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)] public string? CharacterName { get; set; } /// /// The time of death for this Mind. /// Can be null - will be null if the Mind is not considered "dead". /// - [ViewVariables] + [DataField] public TimeSpan? TimeOfDeath { get; set; } - /// - /// The component currently owned by this mind. - /// Can be null. - /// - [ViewVariables] public MindContainerComponent? OwnedComponent; - /// /// The entity currently owned by this mind. /// Can be null. /// - [ViewVariables, Access(typeof(SharedMindSystem))] + [DataField, AutoNetworkedField, Access(typeof(SharedMindSystem))] public EntityUid? OwnedEntity { get; set; } - // TODO move objectives out of mind component /// /// An enumerable over all the objective entities this mind has. /// - [ViewVariables] + [ViewVariables, Obsolete("Use Objectives field")] public IEnumerable AllObjectives => Objectives; /// @@ -100,6 +102,7 @@ namespace Content.Shared.Mind /// Can be null, in which case the player is currently not logged in. /// [ViewVariables, Access(typeof(SharedMindSystem), typeof(SharedGameTicker))] + // TODO remove this after moving IPlayerManager functions to shared public ICommonSession? Session { get; set; } } } diff --git a/Content.Shared/Mind/SharedMindSystem.cs b/Content.Shared/Mind/SharedMindSystem.cs index cc4ac4af23..6fc1c01dc2 100644 --- a/Content.Shared/Mind/SharedMindSystem.cs +++ b/Content.Shared/Mind/SharedMindSystem.cs @@ -1,4 +1,5 @@ using System.Diagnostics.CodeAnalysis; +using System.Linq; using Content.Shared.Administration.Logs; using Content.Shared.Database; using Content.Shared.Examine; @@ -25,7 +26,7 @@ public abstract class SharedMindSystem : EntitySystem [Dependency] private readonly SharedPlayerSystem _player = default!; [Dependency] private readonly MetaDataSystem _metadata = default!; - // This is dictionary is required to track the minds of disconnected players that may have had their entity deleted. + [ViewVariables] protected readonly Dictionary UserMinds = new(); public override void Initialize() @@ -36,6 +37,7 @@ public abstract class SharedMindSystem : EntitySystem SubscribeLocalEvent(OnSuicide); SubscribeLocalEvent(OnVisitingTerminating); SubscribeLocalEvent(OnReset); + SubscribeLocalEvent(OnMindStartup); } public override void Shutdown() @@ -44,6 +46,29 @@ public abstract class SharedMindSystem : EntitySystem WipeAllMinds(); } + private void OnMindStartup(EntityUid uid, MindComponent component, ComponentStartup args) + { + if (component.UserId == null) + return; + + if (UserMinds.TryAdd(component.UserId.Value, uid)) + return; + + var existing = UserMinds[component.UserId.Value]; + if (existing == uid) + return; + + if (!Exists(existing)) + { + Log.Error($"Found deleted entity in mind dictionary while initializing mind {ToPrettyString(uid)}"); + UserMinds[component.UserId.Value] = uid; + return; + } + + Log.Error($"Encountered a user {component.UserId} that is already assigned to a mind while initializing mind {ToPrettyString(uid)}. Ignoring user field."); + component.UserId = null; + } + private void OnReset(RoundRestartCleanupEvent ev) { WipeAllMinds(); @@ -51,12 +76,22 @@ public abstract class SharedMindSystem : EntitySystem public virtual void WipeAllMinds() { - foreach (var mind in UserMinds.Values) + Log.Info($"Wiping all minds"); + foreach (var mind in UserMinds.Values.ToArray()) { WipeMind(mind); } - DebugTools.Assert(UserMinds.Count == 0); + if (UserMinds.Count == 0) + return; + + foreach (var mind in UserMinds.Values) + { + if (Exists(mind)) + Log.Error($"Failed to wipe mind: {ToPrettyString(mind)}"); + } + + UserMinds.Clear(); } public EntityUid? GetMind(NetUserId user) @@ -80,6 +115,26 @@ public abstract class SharedMindSystem : EntitySystem return false; } + public bool TryGetMind(NetUserId user, [NotNullWhen(true)] out Entity? mind) + { + if (!TryGetMind(user, out var mindId, out var mindComp)) + { + mind = null; + return false; + } + + mind = (mindId.Value, mindComp); + return true; + } + + public Entity GetOrCreateMind(NetUserId user) + { + if (!TryGetMind(user, out var mind)) + mind = CreateMind(user); + + return mind.Value; + } + private void OnVisitingTerminating(EntityUid uid, VisitingMindComponent component, ref EntityTerminatingEvent args) { if (component.MindId != null) @@ -128,7 +183,7 @@ public abstract class SharedMindSystem : EntitySystem return null; } - public EntityUid CreateMind(NetUserId? userId, string? name = null) + public Entity CreateMind(NetUserId? userId, string? name = null) { var mindId = Spawn(null, MapCoordinates.Nullspace); _metadata.SetEntityName(mindId, name == null ? "mind" : $"mind ({name})"); @@ -136,7 +191,7 @@ public abstract class SharedMindSystem : EntitySystem mind.CharacterName = name; SetUserId(mindId, userId, mind); - return mindId; + return (mindId, mind); } /// @@ -195,7 +250,7 @@ public abstract class SharedMindSystem : EntitySystem /// Cleans up the VisitingEntity. /// /// - protected void RemoveVisitingEntity(MindComponent mind) + protected void RemoveVisitingEntity(EntityUid mindId, MindComponent mind) { if (mind.VisitingEntity == null) return; @@ -210,6 +265,7 @@ public abstract class SharedMindSystem : EntitySystem RemCompDeferred(oldVisitingEnt, visitComp); } + Dirty(mindId, mind); RaiseLocalEvent(oldVisitingEnt, new MindUnvisitedMessage(), true); } @@ -228,7 +284,7 @@ public abstract class SharedMindSystem : EntitySystem if (mindId == null || !Resolve(mindId.Value, ref mind, false)) return; - TransferTo(mindId.Value, null, mind: mind); + TransferTo(mindId.Value, null, createGhost:false, mind: mind); SetUserId(mindId.Value, null, mind: mind); } @@ -391,21 +447,6 @@ public abstract class SharedMindSystem : EntitySystem return TryComp(mindContainer.Mind, out role); } - /// - /// Sets the Mind's OwnedComponent and OwnedEntity - /// - /// Mind to set OwnedComponent and OwnedEntity on - /// Entity owned by - /// MindContainerComponent owned by - protected void SetOwnedEntity(MindComponent mind, EntityUid? uid, MindContainerComponent? mindContainerComponent) - { - if (uid != null) - Resolve(uid.Value, ref mindContainerComponent); - - mind.OwnedEntity = uid; - mind.OwnedComponent = mindContainerComponent; - } - /// /// Sets the Mind's UserId, Session, and updates the player's PlayerData. This should have no direct effect on the /// entity that any mind is connected to, except as a side effect of the fact that it may change a player's From 7c226160964a99535a22f2e03417ea23f8f62c6a Mon Sep 17 00:00:00 2001 From: Fluffiest Floofers Date: Tue, 24 Oct 2023 22:36:47 +0200 Subject: [PATCH 030/102] Update deathhead_r_leg.png (#21226) --- .../Moth/moth_parts.rsi/deathhead_r_leg.png | Bin 423 -> 552 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Resources/Textures/Mobs/Customization/Moth/moth_parts.rsi/deathhead_r_leg.png b/Resources/Textures/Mobs/Customization/Moth/moth_parts.rsi/deathhead_r_leg.png index 41df319be947effbdfeb8ccdf2a28889b8c67323..7169cda3bb757237018453d32d99c386f02a6157 100644 GIT binary patch literal 552 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+7*Bb+IEGZ*dNXUU*Wmz>1clO-af~ZHx??r zkhZY6`rwta#q8M&f3RqESXg-dX42hKSWvXGS@Z~hK|$yL)q*m<3ThAk@&B=i)U*A5 zee&c3y*-OOZpid)u+eB>!h_ayom|2_C1|>b{sT9!N(%{|BJF))t2;Hi_zHINX&ru8 zV0@YHz_ZyNwg$|vD)a8S{Q3QL$Go_h_%fys{p|~Q{kC2^tF&dq%EMQLuZyPHGD{_h ze&H_D{{DEEl&AP975C)3dEpiFmKXlydUv7ec;$PU;so(b)-yl%?SH;2Z=18gAuW&Y z1l}il3}64;>B|5ANyK5x!6w7F3E%d2SQpK?_F(?Y607)xTUKi7k+VhjzxE8C{N$rW ze5)p2KWQA8z3x-(f7_QUb5`av9$~9!+cWXnuM@i@8+z*%&UU?5F8bZ3@JL3dF;!c> zS)%T`NBDyyx4tuYRJiQQ-5M2~Dwgo~JL7yN9tO?bO5dF}WPb-nJ%gvKpUXO@geCwN Cz3gKE literal 423 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!SkfJR9T^xl_H+M9WCijWi-X*q z7}lMWc?slj7I;J!GcfQS24TkI`72U@g6#o5A+GKPJ~}!&x?lid07*0kTox_`5z$5k zKv^vMuB!Mb{;t&Nuk}=-17w9D2k|4ieh9LPi?~qj+n6@@Z zDyP{bES}<+%338G$LMG7q%ms>SACcH4CZ*(=_YwHqC6bmzKa7j7I?ZihDb=hJ$RJy zumJFVdQ&MBb@0E8=oHvj+t From 13c5ac7f622311fc49988b49b69a064a90146b49 Mon Sep 17 00:00:00 2001 From: liltenhead <104418166+liltenhead@users.noreply.github.com> Date: Tue, 24 Oct 2023 13:37:16 -0700 Subject: [PATCH 031/102] Add hint for the examine trigger effect (#21166) * examine locale * examine trigger desc --- Resources/Locale/en-US/xenoarchaeology/artifact-hints.ftl | 1 + Resources/Prototypes/XenoArch/artifact_triggers.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/Resources/Locale/en-US/xenoarchaeology/artifact-hints.ftl b/Resources/Locale/en-US/xenoarchaeology/artifact-hints.ftl index 48a6f49408..3b63271996 100644 --- a/Resources/Locale/en-US/xenoarchaeology/artifact-hints.ftl +++ b/Resources/Locale/en-US/xenoarchaeology/artifact-hints.ftl @@ -36,3 +36,4 @@ artifact-trigger-hint-pressure = Extreme pressure artifact-trigger-hint-regular-gases = Standard atmospheric gases artifact-trigger-hint-plasma = Gaseous plasma artifact-trigger-hint-land = Active deceleration +artifact-trigger-hint-examine = Examination diff --git a/Resources/Prototypes/XenoArch/artifact_triggers.yml b/Resources/Prototypes/XenoArch/artifact_triggers.yml index 3308eed185..6e128cef1c 100644 --- a/Resources/Prototypes/XenoArch/artifact_triggers.yml +++ b/Resources/Prototypes/XenoArch/artifact_triggers.yml @@ -14,6 +14,7 @@ - type: artifactTrigger id: TriggerExamine targetDepth: 0 + triggerHint: artifact-trigger-hint-examine components: - type: ArtifactExamineTrigger From dd30b3fb7a06ec1d47d47ef66c1edc2f5dc7b42d Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 24 Oct 2023 16:38:22 -0400 Subject: [PATCH 032/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 2d5a514f05..5bed2a94d0 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,10 +1,4 @@ Entries: -- author: brainfood1183 - changes: - - {message: Syndicate clowns may now purchase a holoclown injector via their syndicate - uplink., type: Add} - id: 4550 - time: '2023-08-13T07:18:10.0000000+00:00' - author: Errant changes: - {message: The various laser guns are now called rifles or pistols., type: Tweak} @@ -2908,3 +2902,8 @@ Entries: sending you to the farplanes., type: Fix} id: 5049 time: '2023-10-24T10:44:09.0000000+00:00' +- author: liltenhead + changes: + - {message: Fixed the "examine" trigger for artifacts not having a hint., type: Fix} + id: 5050 + time: '2023-10-24T20:37:16.0000000+00:00' From b59cc50df064713f7f24e43a2bc74bbdcba0a6cf Mon Sep 17 00:00:00 2001 From: Stealthbomber16 <100171035+Stealthbomber16@users.noreply.github.com> Date: Tue, 24 Oct 2023 15:38:43 -0500 Subject: [PATCH 033/102] cornmeal is actually obtainable now (#21162) * do the thing * lets find out * Update Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml Co-authored-by: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com> --------- Co-authored-by: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com> --- .../Prototypes/Entities/Objects/Consumable/Food/produce.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml index 62def229de..699997c123 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml @@ -815,6 +815,7 @@ - type: Produce seedId: corn - type: Extractable + grindableSolutionName: food juiceSolution: reagents: - ReagentId: Cornoil From 968e6e64f6f29e6fd582ad9ea824db2c335aeb47 Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 24 Oct 2023 16:39:47 -0400 Subject: [PATCH 034/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 5bed2a94d0..a9f29092e9 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: Errant - changes: - - {message: The various laser guns are now called rifles or pistols., type: Tweak} - - {message: Retro laser blasters now deal 20% more damage., type: Tweak} - - {message: Laser deliveries now contain 3 laser rifles instead of 3 retro laser - blasters., type: Tweak} - id: 4551 - time: '2023-08-13T07:18:49.0000000+00:00' - author: chromiumboy changes: - {message: Added guidebook entries for the Access Configurator and how to install @@ -2907,3 +2899,8 @@ Entries: - {message: Fixed the "examine" trigger for artifacts not having a hint., type: Fix} id: 5050 time: '2023-10-24T20:37:16.0000000+00:00' +- author: Stealthbomber16 + changes: + - {message: You can actually grind corn into cornmeal now., type: Fix} + id: 5051 + time: '2023-10-24T20:38:43.0000000+00:00' From ed36abcb5f16cdb83730cc01afba169ffddaea4d Mon Sep 17 00:00:00 2001 From: Myakot <30875116+Myakot@users.noreply.github.com> Date: Wed, 25 Oct 2023 03:58:33 +0700 Subject: [PATCH 035/102] Healing skeletons by pouring milk over them (and clean pie remains off their skulls) (#21231) * mvp done - skellies can heal by spillink regular milk on themselves and clean themselves off creaming with water * added other types of healing milk, also made a separate reaction to oat milk - it has almost no calcium in it * fixed indent error, made a dumb mistake --- Resources/Locale/en-US/species/skeleton.ftl | 2 ++ .../Entities/Mobs/Species/skeleton.yml | 34 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 Resources/Locale/en-US/species/skeleton.ftl diff --git a/Resources/Locale/en-US/species/skeleton.ftl b/Resources/Locale/en-US/species/skeleton.ftl new file mode 100644 index 0000000000..efc8fe974f --- /dev/null +++ b/Resources/Locale/en-US/species/skeleton.ftl @@ -0,0 +1,2 @@ +skeleton-healed-by-milk-popup = Calcium restored. +skeleton-sprayed-by-oat-milk-popup = Feels like fake milk. You feel nothing. diff --git a/Resources/Prototypes/Entities/Mobs/Species/skeleton.yml b/Resources/Prototypes/Entities/Mobs/Species/skeleton.yml index 15e83b0908..f4f66d6c0c 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/skeleton.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/skeleton.yml @@ -64,6 +64,40 @@ - MobMask layer: - MobLayer + - type: Reactive + groups: + Flammable: [ Touch ] + Extinguish: [ Touch ] + reactions: + - reagents: [ Water, SpaceCleaner ] + methods: [ Touch ] + effects: + - !type:WashCreamPieReaction + - reagents: [ Milk, MilkGoat, MilkSoy, MilkSpoiled ] + # add new types of milk to reagents as they appear, oat milk isn't on the list + # because turns out oat milk has 1/30th the amount of calcium in it compared to the rest + # even if it's a meme - I did research + methods: [ Touch ] + effects: # TODO: when magic is around - make a milk transformation to a skeleton monster + - !type:HealthChange + scaled: true + damage: + groups: + Burn: -1 # healing obviously up to discussion + Brute: -1 # these groups are the only 2 possible ways to damage a skeleton + - !type:PopupMessage + type: Local + visualType: Large + messages: [ "skeleton-healed-by-milk-popup" ] + probability: 0.25 + - reagents: [ MilkOat ] + methods: [ Touch ] + effects: + - !type:PopupMessage + type: Local + visualType: Large + messages: [ "skeleton-sprayed-by-oat-milk-popup" ] + probability: 0.5 - type: entity parent: BaseSpeciesDummy From 7ef9bac76276938dc224b35ca5a0344cb955c3e1 Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 24 Oct 2023 16:59:53 -0400 Subject: [PATCH 036/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index a9f29092e9..d8befb10e6 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,10 +1,4 @@ Entries: -- author: chromiumboy - changes: - - {message: Added guidebook entries for the Access Configurator and how to install - Airlock Safeguards, type: Add} - id: 4552 - time: '2023-08-13T07:19:28.0000000+00:00' - author: CrigCrag changes: - {message: 'Space Station staff are no longer immune to the toxic and caustic effects @@ -2904,3 +2898,8 @@ Entries: - {message: You can actually grind corn into cornmeal now., type: Fix} id: 5051 time: '2023-10-24T20:38:43.0000000+00:00' +- author: Myakot + changes: + - {message: Skeletons can now heal by pouring milk over themselves, type: Add} + id: 5052 + time: '2023-10-24T20:58:34.0000000+00:00' From 4df2f91f54b9e6926179d080a84609e5d8c17942 Mon Sep 17 00:00:00 2001 From: TemporalOroboros Date: Tue, 24 Oct 2023 14:00:22 -0700 Subject: [PATCH 037/102] Fix anomaly locators frantically beeping when entering detection range. (#21178) * reset beep timer when out of range * prevent deficit from impacting beep timing --- Content.Server/Pinpointer/ProximityBeeperSystem.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Content.Server/Pinpointer/ProximityBeeperSystem.cs b/Content.Server/Pinpointer/ProximityBeeperSystem.cs index b473d97372..d52223e2b4 100644 --- a/Content.Server/Pinpointer/ProximityBeeperSystem.cs +++ b/Content.Server/Pinpointer/ProximityBeeperSystem.cs @@ -80,7 +80,10 @@ public sealed class ProximityBeeperSystem : EntitySystem var scalingFactor = distance / component.MaximumDistance; var interval = (component.MaxBeepInterval - component.MinBeepInterval) * scalingFactor + component.MinBeepInterval; + component.NextBeepTime += interval; + if (component.NextBeepTime < _timing.CurTime) // Prevents spending time out of range accumulating a deficit which causes a series of very rapid beeps when comeing into range. + component.NextBeepTime = _timing.CurTime + interval; } /// From 33593b768658e46fd87ea385de265d61fe6b30b1 Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 24 Oct 2023 17:01:26 -0400 Subject: [PATCH 038/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index d8befb10e6..d24e0aba89 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: CrigCrag - changes: - - {message: 'Space Station staff are no longer immune to the toxic and caustic effects - of some pyrotechnic chemicals, as well as bleach. Drinking bleach now makes - you scream as your stomach lining is reduced to goop.', type: Tweak} - - {message: Phenol is now (accurately) toxic., type: Tweak} - id: 4553 - time: '2023-08-13T07:22:08.0000000+00:00' - author: CrigCrag changes: - {message: Added jugs to the medical fabricator., type: Add} @@ -2903,3 +2895,9 @@ Entries: - {message: Skeletons can now heal by pouring milk over themselves, type: Add} id: 5052 time: '2023-10-24T20:58:34.0000000+00:00' +- author: TemporalOroboros + changes: + - {message: Fixed anomaly locators frantically beeping when they first enter detection + range for an anomaly., type: Fix} + id: 5053 + time: '2023-10-24T21:00:23.0000000+00:00' From ef7f3b1f64055b83a4cb822c191eaf03f5016260 Mon Sep 17 00:00:00 2001 From: "Mr. 27" <45323883+27alaing@users.noreply.github.com> Date: Tue, 24 Oct 2023 20:56:18 -0400 Subject: [PATCH 039/102] Remove "mk --> mmm, okay" and "u --> you" to chatsan anti slang (#21177) --- .../Locale/en-US/speech/speech-chatsan.ftl | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Resources/Locale/en-US/speech/speech-chatsan.ftl b/Resources/Locale/en-US/speech/speech-chatsan.ftl index 756dfc3f99..4c8cf5db54 100644 --- a/Resources/Locale/en-US/speech/speech-chatsan.ftl +++ b/Resources/Locale/en-US/speech/speech-chatsan.ftl @@ -10,8 +10,8 @@ chatsan-replacement-3 = on god chatsan-word-4 = wtf chatsan-replacement-4 = what the fuck -chatsan-word-5 = ffs -chatsan-replacement-5 = for fuck's sake +chatsan-word-5 = wth +chatsan-replacement-5 = what the heck chatsan-word-6 = tf chatsan-replacement-6 = the fuck @@ -31,14 +31,14 @@ chatsan-replacement-10 = i don't care chatsan-word-12 = tbh chatsan-replacement-12 = to be honest -chatsan-word-13 = u -chatsan-replacement-13 = you +chatsan-word-13 = lmk +chatsan-replacement-13 = let me know chatsan-word-14 = ur chatsan-replacement-14 = your -chatsan-word-15 = mk -chatsan-replacement-15 = mmm, okay +chatsan-word-15 = ffs +chatsan-replacement-15 = for fuck's sake chatsan-word-16 = iirc chatsan-replacement-16 = if i remember correctly @@ -109,8 +109,8 @@ chatsan-word-39 = etc chatsan-word-40 = etc. chatsan-replacement-etcetera = etcetera -chatsan-word-41 = fyi -chatsan-replacement-41 = for your information +chatsan-word-41 = wyd +chatsan-replacement-41 = what are you doing -chatsan-word-42 = wyd -chatsan-replacement-42 = what you doing +chatsan-word-42 = ofc +chatsan-replacement-42 = of course From f0c5aa15b883a14bcd7e88569fc3d2b07b1a77b3 Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 24 Oct 2023 20:57:26 -0400 Subject: [PATCH 040/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index d24e0aba89..bcac13d3bc 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,10 +1,4 @@ Entries: -- author: CrigCrag - changes: - - {message: Added jugs to the medical fabricator., type: Add} - - {message: Jugs now take up more space in bags., type: Tweak} - id: 4554 - time: '2023-08-13T07:23:37.0000000+00:00' - author: CrigCrag changes: - {message: Many basic elements from the periodic table are now mildly toxic or @@ -2901,3 +2895,10 @@ Entries: range for an anomaly., type: Fix} id: 5053 time: '2023-10-24T21:00:23.0000000+00:00' +- author: 27alaing + changes: + - {message: The anti-slang system allows for more leeway with certain phrases now., + type: Tweak} + - {message: 'The supply radio channel can be used with ":u" again.', type: Fix} + id: 5054 + time: '2023-10-25T00:56:19.0000000+00:00' From 3007200832d61ed8e3423ecd231a291ff45c4410 Mon Sep 17 00:00:00 2001 From: TemporalOroboros Date: Tue, 24 Oct 2023 18:45:42 -0700 Subject: [PATCH 041/102] Adds AttemptEntity(Uns|S)tickEvent. (#20728) * try-stick * convert spider charge to attempt-stick-events --- .../Ninja/Systems/SpiderChargeSystem.cs | 19 +++++++---- .../Sticky/Events/EntityStuckEvent.cs | 23 +++++++++++++ Content.Server/Sticky/Systems/StickySystem.cs | 33 ++++++++++++++++--- 3 files changed, 63 insertions(+), 12 deletions(-) diff --git a/Content.Server/Ninja/Systems/SpiderChargeSystem.cs b/Content.Server/Ninja/Systems/SpiderChargeSystem.cs index 6f3c3b3f9d..0182bd7ca7 100644 --- a/Content.Server/Ninja/Systems/SpiderChargeSystem.cs +++ b/Content.Server/Ninja/Systems/SpiderChargeSystem.cs @@ -23,7 +23,7 @@ public sealed class SpiderChargeSystem : EntitySystem { base.Initialize(); - SubscribeLocalEvent(BeforePlant); + SubscribeLocalEvent(OnAttemptStick); SubscribeLocalEvent(OnStuck); SubscribeLocalEvent(OnExplode); } @@ -31,14 +31,17 @@ public sealed class SpiderChargeSystem : EntitySystem /// /// Require that the planter is a ninja and the charge is near the target warp point. /// - private void BeforePlant(EntityUid uid, SpiderChargeComponent comp, BeforeRangedInteractEvent args) + private void OnAttemptStick(EntityUid uid, SpiderChargeComponent comp, AttemptEntityStickEvent args) { + if (args.Cancelled) + return; + var user = args.User; if (!_mind.TryGetRole(user, out var role)) { _popup.PopupEntity(Loc.GetString("spider-charge-not-ninja"), user, user); - args.Handled = true; + args.Cancelled = true; return; } @@ -47,12 +50,14 @@ public sealed class SpiderChargeSystem : EntitySystem return; // assumes warp point still exists - var target = Transform(role.SpiderChargeTarget.Value).MapPosition; - var coords = args.ClickLocation.ToMap(EntityManager, _transform); - if (!coords.InRange(target, comp.Range)) + var targetXform = Transform(role.SpiderChargeTarget.Value); + var locXform = Transform(args.Target); + if (locXform.MapID != targetXform.MapID || + (_transform.GetWorldPosition(locXform) - _transform.GetWorldPosition(targetXform)).LengthSquared() > comp.Range * comp.Range) { _popup.PopupEntity(Loc.GetString("spider-charge-too-far"), user, user); - args.Handled = true; + args.Cancelled = true; + return; } } diff --git a/Content.Server/Sticky/Events/EntityStuckEvent.cs b/Content.Server/Sticky/Events/EntityStuckEvent.cs index b924436489..7857fad7d5 100644 --- a/Content.Server/Sticky/Events/EntityStuckEvent.cs +++ b/Content.Server/Sticky/Events/EntityStuckEvent.cs @@ -1,5 +1,28 @@ namespace Content.Server.Sticky.Events; +/// +/// Risen on sticky entity to see if it can stick to another entity. +/// +[ByRefEvent] +public record struct AttemptEntityStickEvent(EntityUid Target, EntityUid User) +{ + public readonly EntityUid Target = Target; + public readonly EntityUid User = User; + public bool Cancelled = false; +} + +/// +/// Risen on sticky entity to see if it can unstick from another entity. +/// +[ByRefEvent] +public record struct AttemptEntityUnstickEvent(EntityUid Target, EntityUid User) +{ + public readonly EntityUid Target = Target; + public readonly EntityUid User = User; + public bool Cancelled = false; +} + + /// /// Risen on sticky entity when it was stuck to other entity. /// diff --git a/Content.Server/Sticky/Systems/StickySystem.cs b/Content.Server/Sticky/Systems/StickySystem.cs index 330b878c05..bcc1be39a9 100644 --- a/Content.Server/Sticky/Systems/StickySystem.cs +++ b/Content.Server/Sticky/Systems/StickySystem.cs @@ -56,7 +56,7 @@ public sealed class StickySystem : EntitySystem { DoContactInteraction = true, Text = Loc.GetString("comp-sticky-unstick-verb-text"), - Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/VerbIcons/eject.svg.192dpi.png")), + Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/eject.svg.192dpi.png")), Act = () => StartUnsticking(uid, args.User, component) }); } @@ -72,6 +72,11 @@ public sealed class StickySystem : EntitySystem if (component.Blacklist != null && component.Blacklist.IsValid(target)) return false; + var attemptEv = new AttemptEntityStickEvent(target, user); + RaiseLocalEvent(uid, ref attemptEv); + if (attemptEv.Cancelled) + return false; + // check if delay is not zero to start do after var delay = (float) component.StickDelay.TotalSeconds; if (delay > 0) @@ -120,6 +125,14 @@ public sealed class StickySystem : EntitySystem if (!Resolve(uid, ref component)) return; + if (component.StuckTo is not { } stuckTo) + return; + + var attemptEv = new AttemptEntityUnstickEvent(stuckTo, user); + RaiseLocalEvent(uid, ref attemptEv); + if (attemptEv.Cancelled) + return; + var delay = (float) component.UnstickDelay.TotalSeconds; if (delay > 0) { @@ -152,6 +165,11 @@ public sealed class StickySystem : EntitySystem if (!Resolve(uid, ref component)) return; + var attemptEv = new AttemptEntityStickEvent(target, user); + RaiseLocalEvent(uid, ref attemptEv); + if (attemptEv.Cancelled) + return; + // add container to entity and insert sticker into it var container = _containerSystem.EnsureContainer(target, StickerSlotId); container.ShowContents = true; @@ -179,12 +197,17 @@ public sealed class StickySystem : EntitySystem { if (!Resolve(uid, ref component)) return; - if (component.StuckTo == null) + + if (component.StuckTo is not { } stuckTo) + return; + + var attemptEv = new AttemptEntityUnstickEvent(stuckTo, user); + RaiseLocalEvent(uid, ref attemptEv); + if (attemptEv.Cancelled) return; // try to remove sticky item from target container - var target = component.StuckTo.Value; - if (!_containerSystem.TryGetContainer(target, StickerSlotId, out var container) || !container.Remove(uid)) + if (!_containerSystem.TryGetContainer(stuckTo, StickerSlotId, out var container) || !container.Remove(uid)) return; // delete container if it's now empty if (container.ContainedEntities.Count == 0) @@ -207,6 +230,6 @@ public sealed class StickySystem : EntitySystem } component.StuckTo = null; - RaiseLocalEvent(uid, new EntityUnstuckEvent(target, user), true); + RaiseLocalEvent(uid, new EntityUnstuckEvent(stuckTo, user), true); } } From 4b10cab617f9c72bf26d6d0f50644ff8377a8308 Mon Sep 17 00:00:00 2001 From: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com> Date: Tue, 24 Oct 2023 19:07:47 -0700 Subject: [PATCH 042/102] Change ListContainer to send null when selected is removed from the data (#20595) --- .../UI/CustomControls/PlayerListControl.xaml.cs | 6 +++--- Content.Client/Storage/StorageBoundUserInterface.cs | 4 ++-- Content.Client/UserInterface/Controls/ListContainer.cs | 8 +++++++- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Content.Client/Administration/UI/CustomControls/PlayerListControl.xaml.cs b/Content.Client/Administration/UI/CustomControls/PlayerListControl.xaml.cs index 6142e3a831..5fa28bf1ac 100644 --- a/Content.Client/Administration/UI/CustomControls/PlayerListControl.xaml.cs +++ b/Content.Client/Administration/UI/CustomControls/PlayerListControl.xaml.cs @@ -22,7 +22,7 @@ namespace Content.Client.Administration.UI.CustomControls private List _playerList = new(); private readonly List _sortedPlayerList = new(); - public event Action? OnSelectionChanged; + public event Action? OnSelectionChanged; public IReadOnlyList PlayerInfo => _playerList; public Func? OverrideText; @@ -46,9 +46,9 @@ namespace Content.Client.Administration.UI.CustomControls BackgroundPanel.PanelOverride = new StyleBoxFlat {BackgroundColor = new Color(32, 32, 40)}; } - private void PlayerListItemPressed(BaseButton.ButtonEventArgs args, ListData data) + private void PlayerListItemPressed(BaseButton.ButtonEventArgs? args, ListData? data) { - if (data is not PlayerListData {Info: var selectedPlayer}) + if (args == null || data is not PlayerListData {Info: var selectedPlayer}) return; if (args.Event.Function == EngineKeyFunctions.UIClick) { diff --git a/Content.Client/Storage/StorageBoundUserInterface.cs b/Content.Client/Storage/StorageBoundUserInterface.cs index 1842417a6e..9a3340e5b0 100644 --- a/Content.Client/Storage/StorageBoundUserInterface.cs +++ b/Content.Client/Storage/StorageBoundUserInterface.cs @@ -61,9 +61,9 @@ namespace Content.Client.Storage _window?.BuildEntityList(uid, component); } - public void InteractWithItem(BaseButton.ButtonEventArgs args, ListData cData) + public void InteractWithItem(BaseButton.ButtonEventArgs? args, ListData? cData) { - if (cData is not EntityListData { Uid: var entity }) + if (args == null || cData is not EntityListData { Uid: var entity }) return; if (args.Event.Function == EngineKeyFunctions.UIClick) diff --git a/Content.Client/UserInterface/Controls/ListContainer.cs b/Content.Client/UserInterface/Controls/ListContainer.cs index d1bb103926..c66ef33d3f 100644 --- a/Content.Client/UserInterface/Controls/ListContainer.cs +++ b/Content.Client/UserInterface/Controls/ListContainer.cs @@ -22,7 +22,7 @@ public sealed class ListContainer : Control } public bool Toggle { get; set; } public Action? GenerateItem; - public Action? ItemPressed; + public Action? ItemPressed; public IReadOnlyList Data => _data; private const int DefaultSeparation = 3; @@ -92,6 +92,12 @@ public sealed class ListContainer : Control _data = data.ToList(); _updateChildren = true; InvalidateArrange(); + + if (_selected != null && !data.Contains(_selected)) + { + _selected = null; + ItemPressed?.Invoke(null, null); + } } public void DirtyList() From 6e007b0d0b88fd558777cf8dd565fab1a124314a Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Wed, 25 Oct 2023 00:51:32 -0400 Subject: [PATCH 043/102] fix feeding unremovable items (#21234) --- Content.Server/Nutrition/EntitySystems/FoodSystem.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Content.Server/Nutrition/EntitySystems/FoodSystem.cs b/Content.Server/Nutrition/EntitySystems/FoodSystem.cs index 8406ce222d..ff4ec41dd9 100644 --- a/Content.Server/Nutrition/EntitySystems/FoodSystem.cs +++ b/Content.Server/Nutrition/EntitySystems/FoodSystem.cs @@ -17,6 +17,7 @@ using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.IdentityManagement; using Content.Shared.Interaction; +using Content.Shared.Interaction.Components; using Content.Shared.Interaction.Events; using Content.Shared.Inventory; using Content.Shared.Mobs.Systems; @@ -101,6 +102,9 @@ public sealed class FoodSystem : EntitySystem if (!TryComp(target, out var body)) return (false, false); + if (HasComp(food)) + return (false, false); + if (_openable.IsClosed(food, user)) return (false, true); From 9025ccaa9d06cfaaefe95fb650dd109cb8a9f37f Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 25 Oct 2023 00:52:36 -0400 Subject: [PATCH 044/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index bcac13d3bc..033a23561b 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,13 +1,4 @@ Entries: -- author: CrigCrag - changes: - - {message: Many basic elements from the periodic table are now mildly toxic or - caustic. Watch what you drink!, type: Tweak} - - {message: Crewmembers who drink lithium have reported very minor cases of serious - brain damage. Doctors should watch out for people who are laughing and screaming - at nothing., type: Tweak} - id: 4555 - time: '2023-08-13T07:24:11.0000000+00:00' - author: CrigCrag changes: - {message: 'Nanotrasen stopped watering down their acid to save money. Drinking @@ -2902,3 +2893,9 @@ Entries: - {message: 'The supply radio channel can be used with ":u" again.', type: Fix} id: 5054 time: '2023-10-25T00:56:19.0000000+00:00' +- author: EmoGarbage404 + changes: + - {message: Medical cyborgs' stethoscopes can no longer be fed to moths to obtain + a free hand., type: Fix} + id: 5055 + time: '2023-10-25T04:51:32.0000000+00:00' From b6a8f5e780dc025f3c3ed0efa3fa63c7f2adf1fd Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Wed, 25 Oct 2023 13:57:23 +0100 Subject: [PATCH 045/102] Power switchable refactor (#20419) Co-authored-by: deltanedas <@deltanedas:kde.org> --- .../Power/Generator/GeneratorWindow.xaml.cs | 15 ++- .../Power/Generator/PowerSwitchableSystem.cs | 7 + .../Generator/PortableGeneratorSystem.cs | 12 +- .../PowerSwitchableGeneratorSystem.cs | 111 ---------------- .../Power/Generator/PowerSwitchableSystem.cs | 123 ++++++++++++++++++ .../Generator/PowerSwitchableComponent.cs | 82 ++++++++++++ .../PowerSwitchableGeneratorComponent.cs | 61 --------- .../SharedPowerSwitchableGeneratorSystem.cs | 23 ---- .../Generator/SharedPowerSwitchableSystem.cs | 72 ++++++++++ .../en-US/power/components/generator.ftl | 23 ++-- .../Power/Generation/portable_generator.yml | 33 +++-- 11 files changed, 332 insertions(+), 230 deletions(-) create mode 100644 Content.Client/Power/Generator/PowerSwitchableSystem.cs delete mode 100644 Content.Server/Power/Generator/PowerSwitchableGeneratorSystem.cs create mode 100644 Content.Server/Power/Generator/PowerSwitchableSystem.cs create mode 100644 Content.Shared/Power/Generator/PowerSwitchableComponent.cs delete mode 100644 Content.Shared/Power/Generator/PowerSwitchableGeneratorComponent.cs delete mode 100644 Content.Shared/Power/Generator/SharedPowerSwitchableGeneratorSystem.cs create mode 100644 Content.Shared/Power/Generator/SharedPowerSwitchableSystem.cs diff --git a/Content.Client/Power/Generator/GeneratorWindow.xaml.cs b/Content.Client/Power/Generator/GeneratorWindow.xaml.cs index d3949807b7..0b8f94ceae 100644 --- a/Content.Client/Power/Generator/GeneratorWindow.xaml.cs +++ b/Content.Client/Power/Generator/GeneratorWindow.xaml.cs @@ -14,6 +14,7 @@ public sealed partial class GeneratorWindow : FancyWindow [Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly ILocalizationManager _loc = default!; + private readonly SharedPowerSwitchableSystem _switchable; private readonly FuelGeneratorComponent? _component; private PortableGeneratorComponentBuiState? _lastState; @@ -24,6 +25,7 @@ public sealed partial class GeneratorWindow : FancyWindow IoCManager.InjectDependencies(this); _entityManager.TryGetComponent(entity, out _component); + _switchable = _entityManager.System(); EntityView.SetEntity(entity); TargetPower.IsValid += IsValid; @@ -99,17 +101,16 @@ public sealed partial class GeneratorWindow : FancyWindow StatusLabel.SetOnlyStyleClass("Danger"); } - var canSwitch = _entityManager.TryGetComponent(_entity, out PowerSwitchableGeneratorComponent? switchable); + var canSwitch = _entityManager.TryGetComponent(_entity, out PowerSwitchableComponent? switchable); OutputSwitchLabel.Visible = canSwitch; OutputSwitchButton.Visible = canSwitch; - if (canSwitch) + if (switchable != null) { - var isHV = switchable!.ActiveOutput == PowerSwitchableGeneratorOutput.HV; - OutputSwitchLabel.Text = - Loc.GetString(isHV ? "portable-generator-ui-switch-hv" : "portable-generator-ui-switch-mv"); - OutputSwitchButton.Text = - Loc.GetString(isHV ? "portable-generator-ui-switch-to-mv" : "portable-generator-ui-switch-to-hv"); + var voltage = _switchable.VoltageString(_switchable.GetVoltage(_entity, switchable)); + OutputSwitchLabel.Text = Loc.GetString("portable-generator-ui-current-output", ("voltage", voltage)); + var nextVoltage = _switchable.VoltageString(_switchable.GetNextVoltage(_entity, switchable)); + OutputSwitchButton.Text = Loc.GetString("power-switchable-switch-voltage", ("voltage", nextVoltage)); OutputSwitchButton.Disabled = state.On; } diff --git a/Content.Client/Power/Generator/PowerSwitchableSystem.cs b/Content.Client/Power/Generator/PowerSwitchableSystem.cs new file mode 100644 index 0000000000..b235dee77d --- /dev/null +++ b/Content.Client/Power/Generator/PowerSwitchableSystem.cs @@ -0,0 +1,7 @@ +using Content.Shared.Power.Generator; + +namespace Content.Client.Power.Generator; + +public sealed class PowerSwitchableSystem : SharedPowerSwitchableSystem +{ +} diff --git a/Content.Server/Power/Generator/PortableGeneratorSystem.cs b/Content.Server/Power/Generator/PortableGeneratorSystem.cs index 416f509978..1180665ad1 100644 --- a/Content.Server/Power/Generator/PortableGeneratorSystem.cs +++ b/Content.Server/Power/Generator/PortableGeneratorSystem.cs @@ -22,7 +22,7 @@ public sealed class PortableGeneratorSystem : SharedPortableGeneratorSystem [Dependency] private readonly AudioSystem _audio = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly GeneratorSystem _generator = default!; - [Dependency] private readonly PowerSwitchableGeneratorSystem _switchableGenerator = default!; + [Dependency] private readonly PowerSwitchableSystem _switchable = default!; public override void Initialize() { @@ -36,6 +36,8 @@ public sealed class PortableGeneratorSystem : SharedPortableGeneratorSystem SubscribeLocalEvent(GeneratorStartMessage); SubscribeLocalEvent(GeneratorStopMessage); SubscribeLocalEvent(GeneratorSwitchOutputMessage); + + SubscribeLocalEvent(OnSwitchPowerCheck); } private void GeneratorSwitchOutputMessage(EntityUid uid, PortableGeneratorComponent component, PortableGeneratorSwitchOutputMessage args) @@ -47,7 +49,7 @@ public sealed class PortableGeneratorSystem : SharedPortableGeneratorSystem if (fuelGenerator.On) return; - _switchableGenerator.ToggleActiveOutput(uid, args.Session.AttachedEntity.Value); + _switchable.Cycle(uid, args.Session.AttachedEntity.Value); } private void GeneratorStopMessage(EntityUid uid, PortableGeneratorComponent component, PortableGeneratorStopMessage args) @@ -164,6 +166,12 @@ public sealed class PortableGeneratorSystem : SharedPortableGeneratorSystem } } + private void OnSwitchPowerCheck(EntityUid uid, FuelGeneratorComponent comp, ref SwitchPowerCheckEvent args) + { + if (comp.On) + args.DisableMessage = Loc.GetString("fuel-generator-verb-disable-on"); + } + public override void Update(float frameTime) { var query = EntityQueryEnumerator(); diff --git a/Content.Server/Power/Generator/PowerSwitchableGeneratorSystem.cs b/Content.Server/Power/Generator/PowerSwitchableGeneratorSystem.cs deleted file mode 100644 index b81d77ea9f..0000000000 --- a/Content.Server/Power/Generator/PowerSwitchableGeneratorSystem.cs +++ /dev/null @@ -1,111 +0,0 @@ -using Content.Server.NodeContainer; -using Content.Server.NodeContainer.EntitySystems; -using Content.Server.Popups; -using Content.Server.Power.Components; -using Content.Server.Power.Nodes; -using Content.Shared.Power.Generator; -using Content.Shared.Verbs; -using Robust.Server.GameObjects; -using Robust.Shared.Player; -using Robust.Shared.Utility; - -namespace Content.Server.Power.Generator; - -/// -/// Implements power-switchable generators. -/// -/// -/// -/// -public sealed class PowerSwitchableGeneratorSystem : SharedPowerSwitchableGeneratorSystem -{ - [Dependency] private readonly NodeGroupSystem _nodeGroup = default!; - [Dependency] private readonly PopupSystem _popup = default!; - [Dependency] private readonly AudioSystem _audio = default!; - - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent>(GetInteractionVerbs); - } - - private void GetInteractionVerbs( - EntityUid uid, - PowerSwitchableGeneratorComponent component, - GetVerbsEvent args) - { - if (!args.CanAccess || !args.CanInteract) - return; - - var isCurrentlyHV = component.ActiveOutput == PowerSwitchableGeneratorOutput.HV; - var msg = isCurrentlyHV ? "power-switchable-generator-verb-mv" : "power-switchable-generator-verb-hv"; - - var isOn = TryComp(uid, out FuelGeneratorComponent? fuelGenerator) && fuelGenerator.On; - - InteractionVerb verb = new() - { - Act = () => - { - - var verbIsOn = TryComp(uid, out FuelGeneratorComponent? verbFuelGenerator) && verbFuelGenerator.On; - if (verbIsOn) - return; - - ToggleActiveOutput(uid, args.User, component); - }, - Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/zap.svg.192dpi.png")), - Text = Loc.GetString(msg), - }; - - if (isOn) - { - verb.Message = Loc.GetString("power-switchable-generator-verb-disable-on"); - verb.Disabled = true; - } - - args.Verbs.Add(verb); - } - - public void ToggleActiveOutput(EntityUid uid, EntityUid user, PowerSwitchableGeneratorComponent? component = null) - { - if (!Resolve(uid, ref component)) - return; - - var supplier = Comp(uid); - var nodeContainer = Comp(uid); - var outputMV = (CableDeviceNode) nodeContainer.Nodes[component.NodeOutputMV]; - var outputHV = (CableDeviceNode) nodeContainer.Nodes[component.NodeOutputHV]; - - if (component.ActiveOutput == PowerSwitchableGeneratorOutput.HV) - { - component.ActiveOutput = PowerSwitchableGeneratorOutput.MV; - supplier.Voltage = Voltage.Medium; - - // Switching around the voltage on the power supplier is "enough", - // but we also want to disconnect the cable nodes so it doesn't show up in power monitors etc. - outputMV.Enabled = true; - outputHV.Enabled = false; - } - else - { - component.ActiveOutput = PowerSwitchableGeneratorOutput.HV; - supplier.Voltage = Voltage.High; - - outputMV.Enabled = false; - outputHV.Enabled = true; - } - - _popup.PopupEntity( - Loc.GetString("power-switchable-generator-switched-output"), - uid, - user); - - _audio.Play(component.SwitchSound, Filter.Pvs(uid), uid, true); - - Dirty(uid, component); - - _nodeGroup.QueueReflood(outputMV); - _nodeGroup.QueueReflood(outputHV); - } -} diff --git a/Content.Server/Power/Generator/PowerSwitchableSystem.cs b/Content.Server/Power/Generator/PowerSwitchableSystem.cs new file mode 100644 index 0000000000..ae7960cf8f --- /dev/null +++ b/Content.Server/Power/Generator/PowerSwitchableSystem.cs @@ -0,0 +1,123 @@ +using Content.Server.NodeContainer; +using Content.Server.NodeContainer.EntitySystems; +using Content.Server.Popups; +using Content.Server.Power.Components; +using Content.Server.Power.Nodes; +using Content.Shared.Power.Generator; +using Content.Shared.Timing; +using Content.Shared.Verbs; +using Robust.Server.GameObjects; +using Robust.Shared.Player; +using Robust.Shared.Utility; + +namespace Content.Server.Power.Generator; + +/// +/// Implements server logic for power-switchable devices. +/// +/// +/// +/// +public sealed class PowerSwitchableSystem : SharedPowerSwitchableSystem +{ + [Dependency] private readonly AudioSystem _audio = default!; + [Dependency] private readonly NodeGroupSystem _nodeGroup = default!; + [Dependency] private readonly PopupSystem _popup = default!; + [Dependency] private readonly UseDelaySystem _useDelay = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent>(GetVerbs); + } + + private void GetVerbs(EntityUid uid, PowerSwitchableComponent comp, GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract) + return; + + var voltage = VoltageColor(GetNextVoltage(uid, comp)); + var msg = Loc.GetString("power-switchable-switch-voltage", ("voltage", voltage)); + + InteractionVerb verb = new() + { + Act = () => + { + // don't need to check it again since if its disabled server wont let the verb act + Cycle(uid, args.User, comp); + }, + Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/zap.svg.192dpi.png")), + Text = msg + }; + + var ev = new SwitchPowerCheckEvent(); + RaiseLocalEvent(uid, ref ev); + if (ev.DisableMessage != null) + { + verb.Message = ev.DisableMessage; + verb.Disabled = true; + } + + args.Verbs.Add(verb); + } + + /// + /// Cycles voltage then updates nodes and optionally power supplier to match it. + /// + public void Cycle(EntityUid uid, EntityUid user, PowerSwitchableComponent? comp = null) + { + if (!Resolve(uid, ref comp)) + return; + + // no sound spamming + if (TryComp(uid, out var useDelay) && _useDelay.ActiveDelay(uid)) + return; + + comp.ActiveIndex = NextIndex(uid, comp); + Dirty(uid, comp); + + var voltage = GetVoltage(uid, comp); + + if (TryComp(uid, out var supplier)) + { + // convert to nodegroupid (goofy server Voltage enum is just alias for it) + switch (voltage) + { + case SwitchableVoltage.HV: + supplier.Voltage = Voltage.High; + break; + case SwitchableVoltage.MV: + supplier.Voltage = Voltage.Medium; + break; + case SwitchableVoltage.LV: + supplier.Voltage = Voltage.Apc; + break; + } + } + + // Switching around the voltage on the power supplier is "enough", + // but we also want to disconnect the cable nodes so it doesn't show up in power monitors etc. + var nodeContainer = Comp(uid); + foreach (var cable in comp.Cables) + { + var node = (CableDeviceNode) nodeContainer.Nodes[cable.Node]; + node.Enabled = cable.Voltage == voltage; + _nodeGroup.QueueReflood(node); + } + + var popup = Loc.GetString(comp.SwitchText, ("voltage", VoltageString(voltage))); + _popup.PopupEntity(popup, uid, user); + + _audio.PlayPvs(comp.SwitchSound, uid); + + _useDelay.BeginDelay(uid, useDelay); + } +} + +/// +/// Raised on a to see if its verb should work. +/// If is non-null, the verb is disabled with that as the message. +/// +[ByRefEvent] +public record struct SwitchPowerCheckEvent(string? DisableMessage = null); diff --git a/Content.Shared/Power/Generator/PowerSwitchableComponent.cs b/Content.Shared/Power/Generator/PowerSwitchableComponent.cs new file mode 100644 index 0000000000..39118b21e5 --- /dev/null +++ b/Content.Shared/Power/Generator/PowerSwitchableComponent.cs @@ -0,0 +1,82 @@ +using Robust.Shared.Audio; +using Robust.Shared.GameStates; +using Robust.Shared.Serialization; + +namespace Content.Shared.Power.Generator; + +/// +/// Enables a device to switch between HV, MV and LV connectors. +/// For generators this means changing output wires. +/// +/// +/// Must have CableDeviceNodes for each output in . +/// If its a generator PowerSupplierComponent is also required. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(SharedPowerSwitchableSystem))] +public sealed partial class PowerSwitchableComponent : Component +{ + /// + /// Index into that the device is currently using. + /// + [DataField, AutoNetworkedField] + public int ActiveIndex; + + /// + /// Sound that plays when the cable is switched. + /// + [DataField] + public SoundSpecifier? SwitchSound = new SoundPathSpecifier("/Audio/Machines/button.ogg"); + + /// + /// Locale id for text shown when examined. + /// It is given "voltage" as a colored voltage string. + /// + [DataField(required: true)] + public string ExamineText = string.Empty; + + /// + /// Locale id for the popup shown when switching voltages. + /// It is given "voltage" as a colored voltage string. + /// + [DataField(required: true)] + public string SwitchText = string.Empty; + + /// + /// Cable voltages and their nodes which can be cycled between. + /// Each node name must match a cable node in its NodeContainer. + /// + [DataField(required: true)] + public List Cables = new(); +} + +/// +/// Cable voltage and node name for cycling. +/// +[DataDefinition] +public sealed partial class PowerSwitchableCable +{ + /// + /// Voltage that the cable uses. + /// + [DataField(required: true)] + public SwitchableVoltage Voltage; + + /// + /// Name of the node for the cable. + /// Must be a CableDeviceNode + /// + [DataField(required: true)] + public string Node = string.Empty; +} + +/// +/// Cable voltage to cycle between. +/// +[Serializable, NetSerializable] +public enum SwitchableVoltage : byte +{ + HV, + MV, + LV +} diff --git a/Content.Shared/Power/Generator/PowerSwitchableGeneratorComponent.cs b/Content.Shared/Power/Generator/PowerSwitchableGeneratorComponent.cs deleted file mode 100644 index 464538f507..0000000000 --- a/Content.Shared/Power/Generator/PowerSwitchableGeneratorComponent.cs +++ /dev/null @@ -1,61 +0,0 @@ -using Robust.Shared.Audio; -using Robust.Shared.GameStates; -using Robust.Shared.Serialization; - -namespace Content.Shared.Power.Generator; - -/// -/// Enables a generator to switch between HV and MV output. -/// -/// -/// Must have CableDeviceNodes for both and , and also a PowerSupplierComponent. -/// -[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] -[Access(typeof(SharedPowerSwitchableGeneratorSystem))] -public sealed partial class PowerSwitchableGeneratorComponent : Component -{ - /// - /// Which output the portable generator is currently connected to. - /// - [DataField("activeOutput")] - [AutoNetworkedField] - public PowerSwitchableGeneratorOutput ActiveOutput { get; set; } - - /// - /// Sound that plays when the output is switched. - /// - /// - [DataField("switchSound")] - public SoundSpecifier? SwitchSound { get; set; } - - /// - /// Which node is the MV output? - /// - [DataField("nodeOutputMV")] - public string NodeOutputMV { get; set; } = "output_mv"; - - /// - /// Which node is the HV output? - /// - [DataField("nodeOutputHV")] - public string NodeOutputHV { get; set; } = "output_hv"; -} - -/// -/// Possible power output for power-switchable generators. -/// -/// -[Serializable, NetSerializable] -public enum PowerSwitchableGeneratorOutput : byte -{ - /// - /// The generator is set to connect to a high-voltage power network. - /// - HV, - - /// - /// The generator is set to connect to a medium-voltage power network. - /// - MV -} - diff --git a/Content.Shared/Power/Generator/SharedPowerSwitchableGeneratorSystem.cs b/Content.Shared/Power/Generator/SharedPowerSwitchableGeneratorSystem.cs deleted file mode 100644 index 5d3793c471..0000000000 --- a/Content.Shared/Power/Generator/SharedPowerSwitchableGeneratorSystem.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Content.Shared.Examine; - -namespace Content.Shared.Power.Generator; - -/// -/// Shared logic for power-switchable generators. -/// -/// -public abstract class SharedPowerSwitchableGeneratorSystem : EntitySystem -{ - public override void Initialize() - { - SubscribeLocalEvent(GeneratorExamined); - } - - private void GeneratorExamined(EntityUid uid, PowerSwitchableGeneratorComponent component, ExaminedEvent args) - { - // Show which output is currently selected. - args.PushMarkup(Loc.GetString( - "power-switchable-generator-examine", - ("output", component.ActiveOutput.ToString()))); - } -} diff --git a/Content.Shared/Power/Generator/SharedPowerSwitchableSystem.cs b/Content.Shared/Power/Generator/SharedPowerSwitchableSystem.cs new file mode 100644 index 0000000000..c1787b6078 --- /dev/null +++ b/Content.Shared/Power/Generator/SharedPowerSwitchableSystem.cs @@ -0,0 +1,72 @@ +using Content.Shared.Examine; + +namespace Content.Shared.Power.Generator; + +/// +/// Shared logic for power-switchable devices. +/// +/// +public abstract class SharedPowerSwitchableSystem : EntitySystem +{ + public override void Initialize() + { + SubscribeLocalEvent(OnExamined); + } + + private void OnExamined(EntityUid uid, PowerSwitchableComponent comp, ExaminedEvent args) + { + // Show which voltage is currently selected. + var voltage = VoltageColor(GetVoltage(uid, comp)); + args.PushMarkup(Loc.GetString(comp.ExamineText, ("voltage", voltage))); + } + + /// + /// Helper to get the colored markup string for a voltage type. + /// + public string VoltageColor(SwitchableVoltage voltage) + { + return Loc.GetString("power-switchable-voltage", ("voltage", VoltageString(voltage))); + } + + /// + /// Converts from "hv" to "HV" since for some reason the enum gets made lowercase??? + /// + public string VoltageString(SwitchableVoltage voltage) + { + return voltage.ToString().ToUpper(); + } + + /// + /// Returns index of the next cable type index to cycle to. + /// + public int NextIndex(EntityUid uid, PowerSwitchableComponent? comp = null) + { + if (!Resolve(uid, ref comp)) + return 0; + + // loop back at the end + return (comp.ActiveIndex + 1) % comp.Cables.Count; + } + + /// + /// Returns the current cable voltage being used by a power-switchable device. + /// + public SwitchableVoltage GetVoltage(EntityUid uid, PowerSwitchableComponent? comp = null) + { + if (!Resolve(uid, ref comp)) + return default; + + return comp.Cables[comp.ActiveIndex].Voltage; + } + + /// + /// Returns the cable's next voltage to cycle to being used by a power-switchable device. + /// + public SwitchableVoltage GetNextVoltage(EntityUid uid, PowerSwitchableComponent? comp = null) + { + if (!Resolve(uid, ref comp)) + return default; + + return comp.Cables[NextIndex(uid, comp)].Voltage; + } +} diff --git a/Resources/Locale/en-US/power/components/generator.ftl b/Resources/Locale/en-US/power/components/generator.ftl index 2a8016287f..c66db1086b 100644 --- a/Resources/Locale/en-US/power/components/generator.ftl +++ b/Resources/Locale/en-US/power/components/generator.ftl @@ -22,19 +22,16 @@ portable-generator-ui-clogged = Contaminants detected in fuel tank! portable-generator-ui-eject = Eject portable-generator-ui-eta = (~{ $minutes } min) portable-generator-ui-unanchored = Unanchored +portable-generator-ui-current-output = Current output: {$voltage} -power-switchable-generator-examine = The power output is set to { $output -> -[HV] [color=orange]HV[/color] -*[MV] [color=yellow]MV[/color] - }. +power-switchable-generator-examine = The power output is set to {$voltage}. +power-switchable-generator-switched = Switched output to {$voltage}! -portable-generator-ui-switch-hv = Current output: HV -portable-generator-ui-switch-mv = Current output: MV +power-switchable-voltage = { $voltage -> + [HV] [color=orange]HV[/color] + [MV] [color=yellow]MV[/color] + *[LV] [color=green]LV[/color] +} +power-switchable-switch-voltage = Switch to {$voltage} -portable-generator-ui-switch-to-hv = Switch to HV -portable-generator-ui-switch-to-mv = Switch to MV - -power-switchable-generator-verb-hv = Switch output to HV -power-switchable-generator-verb-mv = Switch output to MV -power-switchable-generator-verb-disable-on = Turn the generator off first! -power-switchable-generator-switched-output = Output switched! +fuel-generator-verb-disable-on = Turn the generator off first! diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml index 261b9a344c..c49497b774 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml @@ -96,19 +96,26 @@ parent: PortableGeneratorBase id: PortableGeneratorSwitchableBase components: - - type: PowerSwitchableGenerator - switchSound: - path: /Audio/Machines/button.ogg - - type: NodeContainer - examinable: true - nodes: - output_hv: - !type:CableDeviceNode - nodeGroupID: HVPower - output_mv: - !type:CableDeviceNode - nodeGroupID: MVPower - enabled: false + - type: PowerSwitchable + examineText: power-switchable-generator-examine + switchText: power-switchable-generator-switched + cables: + - voltage: HV + node: output_hv + - voltage: MV + node: output_mv + - type: UseDelay + delay: 1 + - type: NodeContainer + examinable: true + nodes: + output_hv: + !type:CableDeviceNode + nodeGroupID: HVPower + output_mv: + !type:CableDeviceNode + nodeGroupID: MVPower + enabled: false - type: entity name: P.A.C.M.A.N.-type portable generator From 33c82d60c0abc92c93874685920105c3a83cc7b8 Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Wed, 25 Oct 2023 13:58:12 +0100 Subject: [PATCH 046/102] simple space mobs cant be flashed (#20784) Co-authored-by: deltanedas <@deltanedas:kde.org> --- Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml index fb9cedbe11..e828cddd1f 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml @@ -53,7 +53,6 @@ - type: Body prototype: Animal - type: Climbing - - type: Flashable - type: NameIdentifier group: GenericNumber - type: SlowOnDamage From 88a29450d9941c9109537aa2310d49c051538dae Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Wed, 25 Oct 2023 14:00:08 +0100 Subject: [PATCH 047/102] give roundstart borgs names (#20081) Co-authored-by: deltanedas <@deltanedas:kde.org> --- Resources/Prototypes/Datasets/Names/borg.yml | 18 ++++++++++++++++++ .../Entities/Mobs/Player/silicon.yml | 2 ++ 2 files changed, 20 insertions(+) create mode 100644 Resources/Prototypes/Datasets/Names/borg.yml diff --git a/Resources/Prototypes/Datasets/Names/borg.yml b/Resources/Prototypes/Datasets/Names/borg.yml new file mode 100644 index 0000000000..6d98cd42c7 --- /dev/null +++ b/Resources/Prototypes/Datasets/Names/borg.yml @@ -0,0 +1,18 @@ +# only used roundstart, names can be changed after +- type: dataset + id: names_borg + values: + - Bob + - Joe + - Beep + - Beep II + - Boombox + - Tour Guide-otron + - Taffy + - Boop + - Boop II + - Buzz + - Buzz II + - Toaster + - Head of Robots + - EVA 1 diff --git a/Resources/Prototypes/Entities/Mobs/Player/silicon.yml b/Resources/Prototypes/Entities/Mobs/Player/silicon.yml index e5c0a61677..c5f2e80fc3 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/silicon.yml @@ -259,6 +259,8 @@ cell_slot: name: power-cell-slot-component-slot-name-default startingItem: PowerCellMedium + - type: RandomMetadata + nameSegments: [names_borg] - type: entity id: PlayerBorgBattery From 0253270a9ac9e13d7080e9007e5bbc5fe7211d6d Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Wed, 25 Oct 2023 09:01:16 -0400 Subject: [PATCH 048/102] fix searching on vending machines (#21233) --- .../VendingMachines/UI/VendingMachineMenu.xaml | 2 +- .../VendingMachines/UI/VendingMachineMenu.xaml.cs | 7 ++++--- .../VendingMachineBoundUserInterface.cs | 12 +++++++----- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Content.Client/VendingMachines/UI/VendingMachineMenu.xaml b/Content.Client/VendingMachines/UI/VendingMachineMenu.xaml index dcd6ed91a7..abc7252e40 100644 --- a/Content.Client/VendingMachines/UI/VendingMachineMenu.xaml +++ b/Content.Client/VendingMachines/UI/VendingMachineMenu.xaml @@ -1,6 +1,6 @@  - + diff --git a/Content.Client/VendingMachines/UI/VendingMachineMenu.xaml.cs b/Content.Client/VendingMachines/UI/VendingMachineMenu.xaml.cs index b436a9d234..a2741cc17a 100644 --- a/Content.Client/VendingMachines/UI/VendingMachineMenu.xaml.cs +++ b/Content.Client/VendingMachines/UI/VendingMachineMenu.xaml.cs @@ -6,7 +6,6 @@ using Robust.Client.Graphics; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; using Robust.Client.UserInterface.XAML; -using Robust.Shared.Graphics; using Robust.Shared.Prototypes; namespace Content.Client.VendingMachines.UI @@ -32,7 +31,6 @@ namespace Content.Client.VendingMachines.UI VendingContents.OnItemSelected += args => { - SearchBar.Text = string.Empty; OnItemSelected?.Invoke(args); }; } @@ -41,8 +39,10 @@ namespace Content.Client.VendingMachines.UI /// Populates the list of available items on the vending machine interface /// and sets icons based on their prototypes /// - public void Populate(List inventory, string? filter = null) + public void Populate(List inventory, out List filteredInventory, string? filter = null) { + filteredInventory = new(); + if (inventory.Count == 0) { VendingContents.Clear(); @@ -93,6 +93,7 @@ namespace Content.Client.VendingMachines.UI vendingItem.Text = $"{itemName} [{entry.Amount}]"; vendingItem.Icon = icon; + filteredInventory.Add(i); } SetSizeAfterUpdate(longestEntry.Length, inventory.Count); diff --git a/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs b/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs index ab310144d5..6f28ddb31f 100644 --- a/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs +++ b/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs @@ -1,6 +1,5 @@ using Content.Client.VendingMachines.UI; using Content.Shared.VendingMachines; -using Robust.Client.GameObjects; using Robust.Client.UserInterface.Controls; using System.Linq; @@ -14,6 +13,9 @@ namespace Content.Client.VendingMachines [ViewVariables] private List _cachedInventory = new(); + [ViewVariables] + private List _cachedFilteredIndex = new(); + public VendingMachineBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } @@ -32,7 +34,7 @@ namespace Content.Client.VendingMachines _menu.OnItemSelected += OnItemSelected; _menu.OnSearchChanged += OnSearchChanged; - _menu.Populate(_cachedInventory); + _menu.Populate(_cachedInventory, out _cachedFilteredIndex); _menu.OpenCentered(); } @@ -46,7 +48,7 @@ namespace Content.Client.VendingMachines _cachedInventory = newState.Inventory; - _menu?.Populate(_cachedInventory); + _menu?.Populate(_cachedInventory, out _cachedFilteredIndex, _menu.SearchBar.Text); } private void OnItemSelected(ItemList.ItemListSelectedEventArgs args) @@ -54,7 +56,7 @@ namespace Content.Client.VendingMachines if (_cachedInventory.Count == 0) return; - var selectedItem = _cachedInventory.ElementAtOrDefault(args.ItemIndex); + var selectedItem = _cachedInventory.ElementAtOrDefault(_cachedFilteredIndex.ElementAtOrDefault(args.ItemIndex)); if (selectedItem == null) return; @@ -78,7 +80,7 @@ namespace Content.Client.VendingMachines private void OnSearchChanged(string? filter) { - _menu?.Populate(_cachedInventory, filter); + _menu?.Populate(_cachedInventory, out _cachedFilteredIndex, filter); } } } From 07a956e79001dd4ff19de7693a1d92a1ca4b5b75 Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Wed, 25 Oct 2023 14:26:26 +0100 Subject: [PATCH 049/102] syndicate snack box (#21024) Co-authored-by: deltanedas <@deltanedas:kde.org> --- .../Locale/en-US/store/uplink-catalog.ftl | 3 ++ .../Prototypes/Catalog/uplink_catalog.yml | 10 ++++ .../Consumable/Food/Containers/box.yml | 51 +++++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/Resources/Locale/en-US/store/uplink-catalog.ftl b/Resources/Locale/en-US/store/uplink-catalog.ftl index 9254a2a8ad..b85fd29c9d 100644 --- a/Resources/Locale/en-US/store/uplink-catalog.ftl +++ b/Resources/Locale/en-US/store/uplink-catalog.ftl @@ -269,6 +269,9 @@ uplink-decoy-disk-desc = A piece of plastic with a lenticular printing, made to uplink-cigarettes-name = Syndicate Smokes Packet uplink-cigarettes-desc = Elite cigarettes for elite agents. Infused with medicine for when you need to do more than calm your nerves. +uplink-snack-box-name = Syndicate Snack Box +uplink-snack-box-desc = A box of delicious snacks and drinks to eat alone or with your team. Includes 1 toy you didn't want. + uplink-eshield-name = Energy Shield uplink-eshield-desc = Exotic energy shield that reflects almost all laser beams, as well as a little protection from bullets and other physical attacks. diff --git a/Resources/Prototypes/Catalog/uplink_catalog.yml b/Resources/Prototypes/Catalog/uplink_catalog.yml index d1be4e4d1b..e52d9f56bb 100644 --- a/Resources/Prototypes/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Catalog/uplink_catalog.yml @@ -1125,6 +1125,16 @@ categories: - UplinkMisc +- type: listing + id: UplinkSnackBox + name: uplink-snack-box-name + description: uplink-snack-box-desc + productEntity: HappyHonkNukieSnacks + cost: + Telecrystal: 1 + categories: + - UplinkMisc + - type: listing id: UplinkEshield name: uplink-eshield-name diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/box.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/box.yml index 4d7c06cd43..5130b9d7e2 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/box.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/box.yml @@ -577,6 +577,57 @@ - id: PlushieNuke orGroup: GiftPool +- type: entity + parent: HappyHonkNukie + id: HappyHonkNukieSnacks + suffix: Toy Unsafe, Snacks + name: syndicate snack box + components: + - type: Item + size: 64 + - type: Storage + capacity: 64 # need more room for goodies + - type: StorageFill + contents: + # toy + - id: C4 + prob: 0.02 + orGroup: GiftPool + - id: ToyMarauder + orGroup: GiftPool + - id: ToyMauler + orGroup: GiftPool + - id: ToyNuke + orGroup: GiftPool + - id: ToySword + orGroup: GiftPool + - id: BalloonSyn + prob: 0.6 + orGroup: GiftPool + - id: PlushieNuke + orGroup: GiftPool + # drinks - 4 cans, up to 2 blood-red brews + - id: DrinkNukieCan + prob: 0.2 + orGroup: Drink1Pool + - id: DrinkColaCan + orGroup: Drink1Pool + - id: DrinkNukieCan + prob: 0.2 + orGroup: Drink2Pool + - id: DrinkColaCan + orGroup: Drink2Pool + - id: DrinkColaCan + amount: 2 + # food + - id: FoodSaladValid + prob: 0.05 + amount: 4 + orGroup: FoodPool + - id: FoodSnackSyndi + amount: 4 + orGroup: FoodPool + - type: entity id: HappyHonkCluwne parent: HappyHonk From 80c57170e92365ab109de8a1a872772eaa569816 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Thu, 26 Oct 2023 00:28:34 +1100 Subject: [PATCH 050/102] Fix DockingControl (#21238) --- Content.Client/Shuttles/UI/DockingControl.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Content.Client/Shuttles/UI/DockingControl.cs b/Content.Client/Shuttles/UI/DockingControl.cs index 92d9959110..c0ddeff86c 100644 --- a/Content.Client/Shuttles/UI/DockingControl.cs +++ b/Content.Client/Shuttles/UI/DockingControl.cs @@ -89,7 +89,7 @@ public class DockingControl : Control // Draw the fixtures around the dock before drawing it if (_entManager.TryGetComponent(GridEntity, out var fixtures)) { - foreach (var (_, fixture) in fixtures.Fixtures) + foreach (var fixture in fixtures.Fixtures.Values) { var poly = (PolygonShape) fixture.Shape; @@ -151,7 +151,7 @@ public class DockingControl : Control var xformQuery = _entManager.GetEntityQuery(); _grids.Clear(); - _mapManager.FindGridsIntersecting(gridXform.MapID, new Box2(worldPos - RangeVector, worldPos + RangeVector)); + _mapManager.FindGridsIntersecting(gridXform.MapID, new Box2(worldPos - RangeVector, worldPos + RangeVector), ref _grids); foreach (var grid in _grids) { From 94cda6a2530002b81723f8fd71cf505c77cd9acf Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Wed, 25 Oct 2023 16:36:22 +0300 Subject: [PATCH 051/102] Shadow Dimension visual pack (#21237) Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> --- .../Entities/Objects/Decoration/flora.yml | 49 +++++++++++ .../Entities/Structures/Walls/asteroid.yml | 4 +- .../Entities/Tiles/shadow_basalt.yml | 83 ++++++++++++++++++ Resources/Prototypes/Tiles/floors.yml | 20 +++++ .../Flora/flora_shadow_trees.rsi/meta.json | 29 ++++++ .../Flora/flora_shadow_trees.rsi/tree01.png | Bin 0 -> 5323 bytes .../Flora/flora_shadow_trees.rsi/tree02.png | Bin 0 -> 4671 bytes .../Flora/flora_shadow_trees.rsi/tree03.png | Bin 0 -> 5093 bytes .../Flora/flora_shadow_trees.rsi/tree04.png | Bin 0 -> 5216 bytes .../Flora/flora_shadow_trees.rsi/tree05.png | Bin 0 -> 4801 bytes .../Flora/flora_shadow_trees.rsi/tree06.png | Bin 0 -> 5196 bytes .../Tiles/Planet/shadowbasalt.rsi/basalt1.png | Bin 0 -> 968 bytes .../Tiles/Planet/shadowbasalt.rsi/basalt2.png | Bin 0 -> 1016 bytes .../Tiles/Planet/shadowbasalt.rsi/basalt3.png | Bin 0 -> 1310 bytes .../Tiles/Planet/shadowbasalt.rsi/basalt4.png | Bin 0 -> 867 bytes .../Tiles/Planet/shadowbasalt.rsi/basalt5.png | Bin 0 -> 736 bytes .../Tiles/Planet/shadowbasalt.rsi/meta.json | 66 ++++++++++++++ Resources/Textures/Tiles/attributions.yml | 5 ++ Resources/Textures/Tiles/chromite.png | Bin 0 -> 3171 bytes 19 files changed, 254 insertions(+), 2 deletions(-) create mode 100644 Resources/Prototypes/Entities/Tiles/shadow_basalt.yml create mode 100644 Resources/Textures/Objects/Decoration/Flora/flora_shadow_trees.rsi/meta.json create mode 100644 Resources/Textures/Objects/Decoration/Flora/flora_shadow_trees.rsi/tree01.png create mode 100644 Resources/Textures/Objects/Decoration/Flora/flora_shadow_trees.rsi/tree02.png create mode 100644 Resources/Textures/Objects/Decoration/Flora/flora_shadow_trees.rsi/tree03.png create mode 100644 Resources/Textures/Objects/Decoration/Flora/flora_shadow_trees.rsi/tree04.png create mode 100644 Resources/Textures/Objects/Decoration/Flora/flora_shadow_trees.rsi/tree05.png create mode 100644 Resources/Textures/Objects/Decoration/Flora/flora_shadow_trees.rsi/tree06.png create mode 100644 Resources/Textures/Tiles/Planet/shadowbasalt.rsi/basalt1.png create mode 100644 Resources/Textures/Tiles/Planet/shadowbasalt.rsi/basalt2.png create mode 100644 Resources/Textures/Tiles/Planet/shadowbasalt.rsi/basalt3.png create mode 100644 Resources/Textures/Tiles/Planet/shadowbasalt.rsi/basalt4.png create mode 100644 Resources/Textures/Tiles/Planet/shadowbasalt.rsi/basalt5.png create mode 100644 Resources/Textures/Tiles/Planet/shadowbasalt.rsi/meta.json create mode 100644 Resources/Textures/Tiles/chromite.png diff --git a/Resources/Prototypes/Entities/Objects/Decoration/flora.yml b/Resources/Prototypes/Entities/Objects/Decoration/flora.yml index 9577cc1c4b..374a9a272c 100644 --- a/Resources/Prototypes/Entities/Objects/Decoration/flora.yml +++ b/Resources/Prototypes/Entities/Objects/Decoration/flora.yml @@ -392,3 +392,52 @@ components: - type: Sprite state: treestumpconifer + +- type: entity + parent: FloraTree01 + id: ShadowTree01 + name: tree + components: + - type: Sprite + sprite: Objects/Decoration/Flora/flora_shadow_trees.rsi + state: tree01 + +- type: entity + parent: ShadowTree01 + id: ShadowTree02 + name: tree + components: + - type: Sprite + state: tree02 + +- type: entity + parent: ShadowTree01 + id: ShadowTree03 + name: tree + components: + - type: Sprite + state: tree03 + +- type: entity + parent: ShadowTree01 + id: ShadowTree04 + name: tree + components: + - type: Sprite + state: tree04 + +- type: entity + parent: ShadowTree01 + id: ShadowTree05 + name: tree + components: + - type: Sprite + state: tree05 + +- type: entity + parent: ShadowTree01 + id: ShadowTree06 + name: tree + components: + - type: Sprite + state: tree06 \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml index 9b513b2da1..9d5ff1b473 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml @@ -1000,7 +1000,7 @@ state: rock_chromite_north - map: [ "enum.EdgeLayer.West" ] state: rock_chromite_west - - state: rock_chromite + - state: rock_gold - type: entity id: WallRockChromitePlasma @@ -1195,7 +1195,7 @@ state: rock_andesite_north - map: [ "enum.EdgeLayer.West" ] state: rock_andesite_west - - state: rock_andesite + - state: rock_gold - type: entity id: WallRockAndesitePlasma diff --git a/Resources/Prototypes/Entities/Tiles/shadow_basalt.yml b/Resources/Prototypes/Entities/Tiles/shadow_basalt.yml new file mode 100644 index 0000000000..e5835239cf --- /dev/null +++ b/Resources/Prototypes/Entities/Tiles/shadow_basalt.yml @@ -0,0 +1,83 @@ +- type: entity + id: ShadowBasaltOne + name: shadowstone + description: Cold rock + placement: + mode: SnapgridCenter + components: + - type: Clickable + - type: Sprite + sprite: /Textures/Tiles/Planet/shadowbasalt.rsi + layers: + - state: basalt1 + shader: unshaded + drawdepth: LowFloors + - type: SyncSprite + - type: RequiresTile + - type: Transform + anchored: true + - type: Tag + tags: + - HideContextMenu + +- type: entity + id: ShadowBasaltTwo + parent: BasaltOne + placement: + mode: SnapgridCenter + components: + - type: Sprite + layers: + - state: basalt2 + shader: unshaded + +- type: entity + id: ShadowBasaltThree + parent: BasaltOne + placement: + mode: SnapgridCenter + components: + - type: Sprite + layers: + - state: basalt3 + shader: unshaded + +- type: entity + id: ShadowBasaltFour + parent: BasaltOne + placement: + mode: SnapgridCenter + components: + - type: Sprite + layers: + - state: basalt4 + shader: unshaded + +- type: entity + id: ShadowBasaltFive + parent: BasaltOne + placement: + mode: SnapgridCenter + components: + - type: Sprite + layers: + - state: basalt5 + shader: unshaded + +- type: entity + id: ShadowBasaltRandom + parent: ShadowBasaltOne + suffix: Random + components: + - type: RandomSprite + available: + - 0: + basalt1: "" + - 0: + basalt2: "" + - 0: + basalt3: "" + - 0: + basalt4: "" + - 0: + basalt5: "" \ No newline at end of file diff --git a/Resources/Prototypes/Tiles/floors.yml b/Resources/Prototypes/Tiles/floors.yml index 908cd466a3..43dbd76b10 100644 --- a/Resources/Prototypes/Tiles/floors.yml +++ b/Resources/Prototypes/Tiles/floors.yml @@ -1622,6 +1622,26 @@ itemDrop: FloorTileItemWeb heatCapacity: 10000 +- type: tile + id: FloorChromite + name: tiles-chromite + sprite: /Textures/Tiles/chromite.png + variants: 7 + placementVariants: + - 1.0 + - 1.0 + - 1.0 + - 1.0 + - 1.0 + - 1.0 + - 1.0 + baseTurf: Space + isSubfloor: true + canCrowbar: false + footstepSounds: + collection: FootstepAsteroid + heatCapacity: 10000 + #Hull tiles - type: tile id: FloorHull diff --git a/Resources/Textures/Objects/Decoration/Flora/flora_shadow_trees.rsi/meta.json b/Resources/Textures/Objects/Decoration/Flora/flora_shadow_trees.rsi/meta.json new file mode 100644 index 0000000000..8f86af7053 --- /dev/null +++ b/Resources/Textures/Objects/Decoration/Flora/flora_shadow_trees.rsi/meta.json @@ -0,0 +1,29 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/blob/e00cae8d065f9cf520688cc0dd0e15ba5bef12a9/icons/obj/flora/jungleflora.dmi and recolor by TheShuEd", + "size": { + "x": 96, + "y": 96 + }, + "states": [ + { + "name": "tree01" + }, + { + "name": "tree02" + }, + { + "name": "tree03" + }, + { + "name": "tree04" + }, + { + "name": "tree05" + }, + { + "name": "tree06" + } + ] +} diff --git a/Resources/Textures/Objects/Decoration/Flora/flora_shadow_trees.rsi/tree01.png b/Resources/Textures/Objects/Decoration/Flora/flora_shadow_trees.rsi/tree01.png new file mode 100644 index 0000000000000000000000000000000000000000..99ca699d42035126a734630df4f811b04aa872ec GIT binary patch literal 5323 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Decoration/Flora/flora_shadow_trees.rsi/tree02.png b/Resources/Textures/Objects/Decoration/Flora/flora_shadow_trees.rsi/tree02.png new file mode 100644 index 0000000000000000000000000000000000000000..4aa9a2913f696ec2c0f200b2d876199bb3f76e18 GIT binary patch literal 4671 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 YIKfl>3IBdZe;ESQm9>@N3fAHO1De_~tN;K2 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Decoration/Flora/flora_shadow_trees.rsi/tree05.png b/Resources/Textures/Objects/Decoration/Flora/flora_shadow_trees.rsi/tree05.png new file mode 100644 index 0000000000000000000000000000000000000000..8b2cd2a30b03c07122e7b56f69c937dcd3676fae GIT binary patch literal 4801 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 O0;nlzE7r-|ME?&SElaTg literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Decoration/Flora/flora_shadow_trees.rsi/tree06.png b/Resources/Textures/Objects/Decoration/Flora/flora_shadow_trees.rsi/tree06.png new file mode 100644 index 0000000000000000000000000000000000000000..888fbfd25b1ea23965517af129a9e40765ef41dd GIT binary patch literal 5196 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 B&nf@_ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/shadowbasalt.rsi/basalt1.png b/Resources/Textures/Tiles/Planet/shadowbasalt.rsi/basalt1.png new file mode 100644 index 0000000000000000000000000000000000000000..e8f873286cba8a7cbb2e32bd29148f927418bd65 GIT binary patch literal 968 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/shadowbasalt.rsi/meta.json b/Resources/Textures/Tiles/Planet/shadowbasalt.rsi/meta.json new file mode 100644 index 0000000000..0d71d4b561 --- /dev/null +++ b/Resources/Textures/Tiles/Planet/shadowbasalt.rsi/meta.json @@ -0,0 +1,66 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "taken from tgstation @ commit a0ca7b3f46132517f71f08bfda465667d133b5d7 and edited by TheShuEd", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "basalt1", + "delays": [ + [ + 2, + 2, + 2, + 2 + ] + ] + }, + { + "name": "basalt2", + "delays": [ + [ + 2, + 2, + 2, + 2 + ] + ] + }, + { + "name": "basalt3", + "delays": [ + [ + 2, + 2, + 2, + 2 + ] + ] + }, + { + "name": "basalt4", + "delays": [ + [ + 2, + 2, + 2, + 2 + ] + ] + }, + { + "name": "basalt5", + "delays": [ + [ + 2, + 2, + 2, + 2 + ] + ] + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Tiles/attributions.yml b/Resources/Textures/Tiles/attributions.yml index 641100fe42..b732333dd7 100644 --- a/Resources/Textures/Tiles/attributions.yml +++ b/Resources/Textures/Tiles/attributions.yml @@ -95,3 +95,8 @@ license: "CC-BY-SA-3.0" copyright: "taken at https://github.com/ParadiseSS13/Paradise/blob/8b7f4c8b69c74c6de5a755272eb8d3520f3d87c7/icons/turf/floors.dmi" source: "https://github.com/ParadiseSS13/Paradise" + +- files: ["chromite.png"] + license: "CC-BY-NC-SA-3.0" + copyright: "taken at commit 0587dd16e28108bdf0b0a28e2caae4319845e861, and recolored by TheShuEd" + source: "https://github.com/Mojave-Sun/mojave-sun-13" \ No newline at end of file diff --git a/Resources/Textures/Tiles/chromite.png b/Resources/Textures/Tiles/chromite.png new file mode 100644 index 0000000000000000000000000000000000000000..631b9bf84e747ad3134996d965bf722f3dd13e34 GIT binary patch literal 3171 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 JPDHLkV1lO{iqrrA literal 0 HcmV?d00001 From 6b04aaf96406ceccdc6dc49fe2709d043b866da0 Mon Sep 17 00:00:00 2001 From: Doru991 <75124791+Doru991@users.noreply.github.com> Date: Wed, 25 Oct 2023 16:52:49 +0300 Subject: [PATCH 052/102] Potato battery update + potato AI (#21142) Co-authored-by: metalgearsloth --- .../Containers/ItemSlot/ItemSlotsComponent.cs | 3 + .../Containers/ItemSlot/ItemSlotsSystem.cs | 2 +- Resources/Locale/en-US/pai/pai-system.ftl | 2 + .../Objects/Consumable/Food/produce.yml | 3 + .../Prototypes/Entities/Objects/Fun/pai.yml | 29 +++++++ .../Entities/Objects/Misc/potatoai_chip.yml | 17 ++++ .../Entities/Objects/Power/powercells.yml | 11 ++- .../Objects/Specific/Robotics/mmi.yml | 2 +- .../Entities/Structures/Power/chargers.yml | 3 + .../Crafting/Graphs/improvised/potato.yml | 74 ++++++++++++++++++ .../Prototypes/Recipes/Crafting/potato.yml | 32 ++++++++ Resources/Prototypes/tags.yml | 9 +++ .../Objects/Fun/pai.rsi/icon-potato-off.png | Bin 0 -> 483 bytes .../Textures/Objects/Fun/pai.rsi/meta.json | 17 +++- .../Objects/Fun/pai.rsi/potato-base.png | Bin 0 -> 476 bytes .../Fun/pai.rsi/potato-off-overlay.png | Bin 0 -> 162 bytes .../Objects/Fun/pai.rsi/potato-on-overlay.png | Bin 0 -> 159 bytes .../Fun/pai.rsi/potato-searching-overlay.png | Bin 0 -> 186 bytes .../Objects/Misc/potatoai_chip.rsi/icon.png | Bin 0 -> 235 bytes .../Objects/Misc/potatoai_chip.rsi/meta.json | 14 ++++ .../Objects/Power/power_cells.rsi/meta.json | 2 +- .../Objects/Power/power_cells.rsi/potato.png | Bin 946 -> 463 bytes .../Specific/Robotics/mmi.rsi/meta.json | 2 +- 23 files changed, 215 insertions(+), 7 deletions(-) create mode 100644 Resources/Prototypes/Entities/Objects/Misc/potatoai_chip.yml create mode 100644 Resources/Prototypes/Recipes/Crafting/Graphs/improvised/potato.yml create mode 100644 Resources/Prototypes/Recipes/Crafting/potato.yml create mode 100644 Resources/Textures/Objects/Fun/pai.rsi/icon-potato-off.png create mode 100644 Resources/Textures/Objects/Fun/pai.rsi/potato-base.png create mode 100644 Resources/Textures/Objects/Fun/pai.rsi/potato-off-overlay.png create mode 100644 Resources/Textures/Objects/Fun/pai.rsi/potato-on-overlay.png create mode 100644 Resources/Textures/Objects/Fun/pai.rsi/potato-searching-overlay.png create mode 100644 Resources/Textures/Objects/Misc/potatoai_chip.rsi/icon.png create mode 100644 Resources/Textures/Objects/Misc/potatoai_chip.rsi/meta.json diff --git a/Content.Shared/Containers/ItemSlot/ItemSlotsComponent.cs b/Content.Shared/Containers/ItemSlot/ItemSlotsComponent.cs index effba18210..9310617634 100644 --- a/Content.Shared/Containers/ItemSlot/ItemSlotsComponent.cs +++ b/Content.Shared/Containers/ItemSlot/ItemSlotsComponent.cs @@ -71,6 +71,9 @@ namespace Content.Shared.Containers.ItemSlots [DataField("whitelist")] public EntityWhitelist? Whitelist; + [DataField("blacklist")] + public EntityWhitelist? Blacklist; + [DataField("insertSound")] public SoundSpecifier InsertSound = new SoundPathSpecifier("/Audio/Weapons/Guns/MagIn/revolver_magin.ogg"); diff --git a/Content.Shared/Containers/ItemSlot/ItemSlotsSystem.cs b/Content.Shared/Containers/ItemSlot/ItemSlotsSystem.cs index 902b56427a..9194a8208e 100644 --- a/Content.Shared/Containers/ItemSlot/ItemSlotsSystem.cs +++ b/Content.Shared/Containers/ItemSlot/ItemSlotsSystem.cs @@ -255,7 +255,7 @@ namespace Content.Shared.Containers.ItemSlots if (!swap && slot.HasItem) return false; - if (slot.Whitelist != null && !slot.Whitelist.IsValid(usedUid)) + if ((slot.Whitelist != null && !slot.Whitelist.IsValid(usedUid)) || (slot.Blacklist != null && slot.Blacklist.IsValid(usedUid))) { if (_netManager.IsClient && _timing.IsFirstTimePredicted && popup.HasValue && !string.IsNullOrWhiteSpace(slot.WhitelistFailPopup)) _popupSystem.PopupEntity(Loc.GetString(slot.WhitelistFailPopup), uid, popup.Value); diff --git a/Resources/Locale/en-US/pai/pai-system.ftl b/Resources/Locale/en-US/pai/pai-system.ftl index d8ee6eaa08..d64d7f5623 100644 --- a/Resources/Locale/en-US/pai/pai-system.ftl +++ b/Resources/Locale/en-US/pai/pai-system.ftl @@ -9,6 +9,8 @@ pai-system-role-description = Be someone's electronic pal! pai-system-role-name-syndicate = Syndicate personal ai pai-system-role-description-syndicate = Be someone's Syndicate pal! (Memories *not* included.) +pai-system-role-name-potato = potato artificial intelligence +pai-system-role-description-potato = It's a toy for children. And now you live in it. pai-system-wipe-device-verb-text = Remove pAI pai-system-wiped-device = The pAI was wiped from the device. diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml index 699997c123..6439b2eb6c 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml @@ -556,6 +556,9 @@ reagents: - ReagentId: JuicePotato Quantity: 10 + - type: Tag + tags: + - Potato - type: entity name: tomato diff --git a/Resources/Prototypes/Entities/Objects/Fun/pai.yml b/Resources/Prototypes/Entities/Objects/Fun/pai.yml index 6c0dc8f4ba..b9da6775c9 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/pai.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/pai.yml @@ -80,6 +80,7 @@ - state: pai-base - state: syndicate-pai-off-overlay shader: unshaded + map: ["screen"] - type: ToggleableGhostRole roleName: pai-system-role-name-syndicate roleDescription: pai-system-role-description-syndicate @@ -98,6 +99,34 @@ Searching: { state: syndicate-pai-searching-overlay } On: { state: syndicate-pai-on-overlay } +- type: entity + parent: PersonalAI + id: PotatoAI + name: potato artificial intelligence + description: It's a potato. You forced it to be sentient, you monster. + components: + - type: Sprite + sprite: Objects/Fun/pai.rsi + layers: + - state: potato-base + - state: potato-off-overlay + shader: unshaded + map: ["screen"] + - type: ToggleableGhostRole + roleName: pai-system-role-name-potato + roleDescription: pai-system-role-description-potato + - type: Appearance + - type: GenericVisualizer + visuals: + enum.ToggleableGhostRoleVisuals.Status: + screen: + Off: { state: potato-off-overlay } + Searching: { state: potato-searching-overlay } + On: { state: potato-on-overlay } + - type: Construction + graph: PotatoAI + node: potatoai + - type: entity id: ActionPAIPlayMidi name: Play MIDI diff --git a/Resources/Prototypes/Entities/Objects/Misc/potatoai_chip.yml b/Resources/Prototypes/Entities/Objects/Misc/potatoai_chip.yml new file mode 100644 index 0000000000..528aa30a14 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Misc/potatoai_chip.yml @@ -0,0 +1,17 @@ +- type: entity + id: PotatoAIChip + name: supercompact AI chip + parent: BaseItem + description: This high-tech AI chip requires a voltage of exactly 1.1V to function correctly. + components: + - type: Sprite + sprite: Objects/Misc/potatoai_chip.rsi + state: icon + - type: Item + size: 3 + - type: Tag + tags: + - SmallAIChip + - type: Construction + graph: PotatoAIChip + node: potatoaichip \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Objects/Power/powercells.yml b/Resources/Prototypes/Entities/Objects/Power/powercells.yml index 82c1bb37e9..4ed3e207c5 100644 --- a/Resources/Prototypes/Entities/Objects/Power/powercells.yml +++ b/Resources/Prototypes/Entities/Objects/Power/powercells.yml @@ -42,8 +42,15 @@ layers: - state: potato - type: Battery - maxCharge: 200 - startingCharge: 200 + maxCharge: 70 + startingCharge: 70 + - type: Tag + tags: + - DroneUsable + - PotatoBattery + - type: Construction + graph: PowerCellPotato + node: potatobattery - type: entity name: small-capacity power cell diff --git a/Resources/Prototypes/Entities/Objects/Specific/Robotics/mmi.yml b/Resources/Prototypes/Entities/Objects/Specific/Robotics/mmi.yml index 6382d69e58..b4e69b3780 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Robotics/mmi.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Robotics/mmi.yml @@ -116,4 +116,4 @@ base: Off: { state: posibrain } Searching: { state: posibrain-searching } - On: { state: posibrain-occupied } + On: { state: posibrain-occupied } \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Structures/Power/chargers.yml b/Resources/Prototypes/Entities/Structures/Power/chargers.yml index e5edc63df3..7630610bd8 100644 --- a/Resources/Prototypes/Entities/Structures/Power/chargers.yml +++ b/Resources/Prototypes/Entities/Structures/Power/chargers.yml @@ -85,6 +85,9 @@ whitelist: components: - PowerCell + blacklist: + tags: + - PotatoBattery - type: entity parent: BaseItemRecharger diff --git a/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/potato.yml b/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/potato.yml new file mode 100644 index 0000000000..e3f972cfda --- /dev/null +++ b/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/potato.yml @@ -0,0 +1,74 @@ +- type: constructionGraph + id: PowerCellPotato + start: start + graph: + - node: start + edges: + - to: potatobattery + steps: + - tag: Potato + name: a potato + icon: + sprite: Objects/Specific/Hydroponics/potato.rsi + state: produce + doAfter: 1 + - material: MetalRod + amount: 2 + doAfter: 1 + - material: Cable + amount: 1 + doAfter: 1 + - node: potatobattery + entity: PowerCellPotato + +- type: constructionGraph + id: PotatoAI + start: start + graph: + - node: start + edges: + - to: potatoai + steps: + - tag: PotatoBattery + name: a potato battery + icon: + sprite: Objects/Power/power_cells.rsi + state: potato + doAfter: 1 + - tag: SmallAIChip + name: a super-compact AI chip + icon: + sprite: Objects/Misc/potatoai_chip.rsi + state: icon + - node: potatoai + entity: PotatoAI + +- type: constructionGraph + id: PotatoAIChip + start: start + graph: + - node: start + edges: + - to: potatoaichip + steps: + - material: Steel + amount: 1 + doAfter: 1 + - material: Glass + amount: 1 + doAfter: 1 + - material: Cable + amount: 2 + doAfter: 1 + - tag: CapacitorStockPart + name: capacitor + icon: + sprite: Objects/Misc/stock_parts.rsi + state: capacitor + - tag: CapacitorStockPart + name: capacitor + icon: + sprite: Objects/Misc/stock_parts.rsi + state: capacitor + - node: potatoaichip + entity: PotatoAIChip \ No newline at end of file diff --git a/Resources/Prototypes/Recipes/Crafting/potato.yml b/Resources/Prototypes/Recipes/Crafting/potato.yml new file mode 100644 index 0000000000..17f2cc4013 --- /dev/null +++ b/Resources/Prototypes/Recipes/Crafting/potato.yml @@ -0,0 +1,32 @@ +- type: construction + name: potato battery + id: PowerCellPotato + graph: PowerCellPotato + startNode: start + targetNode: potatobattery + category: construction-category-misc + description: A truly ingenious source of power. + icon: { sprite: Objects/Power/power_cells.rsi, state: potato } + objectType: Item + +- type: construction + name: potato artificial intelligence + id: PotatoAI + graph: PotatoAI + startNode: start + targetNode: potatoai + category: construction-category-misc + description: The potato happens to be the perfect power source for this chip. + icon: { sprite: Objects/Fun/pai.rsi, state: icon-potato-off } + objectType: Item + +- type: construction + name: supercompact AI chip + id: PotatoAIChip + graph: PotatoAIChip + startNode: start + targetNode: potatoaichip + category: construction-category-misc + description: A masterfully(?) crafted AI chip, requiring a similarly improvised power source. + icon: { sprite: Objects/Misc/potatoai_chip.rsi, state: icon } + objectType: Item \ No newline at end of file diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index a74fde7710..67a27be416 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -839,6 +839,12 @@ - type: Tag id: PlushieSharkGrey +- type: Tag + id: Potato + +- type: Tag + id: PotatoBattery + - type: Tag id: PowerCellSmall @@ -924,6 +930,9 @@ - type: Tag id: SkeletonMotorcycleKeys +- type: Tag + id: SmallAIChip + - type: Tag id: SmallMech diff --git a/Resources/Textures/Objects/Fun/pai.rsi/icon-potato-off.png b/Resources/Textures/Objects/Fun/pai.rsi/icon-potato-off.png new file mode 100644 index 0000000000000000000000000000000000000000..806d02d6f3d43be3a12c9ba6f97bb64bbc48a83e GIT binary patch literal 483 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCik*1AIbUZKjy$OZ38X6k5bo+It8O{o2m{)1PuFYyJYFtWAq35p`-R(<^cYeRH;1SDy;VD5;+iVz& zZZ=$s>QM|iHp9{L>2iU^GsUzN?(Uwz6MWS-I(+BxR`)sV9-ddvJ?p(HlDxg*n9=mr zDmT*Xve!mmzF^<_RE;y`^|qC|#m|d)TyCthT3+6#>+$#2^FL2{`x*~B`p-X?(NzuR1fqggQu&X%Q~loCIEIS*`)vg literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Fun/pai.rsi/meta.json b/Resources/Textures/Objects/Fun/pai.rsi/meta.json index 905a3684f8..f819450aa8 100644 --- a/Resources/Textures/Objects/Fun/pai.rsi/meta.json +++ b/Resources/Textures/Objects/Fun/pai.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/9ddb8cf084e292571d4e9c79745db25befbd82fe. pai-searching-overlay heavily modified. Syndicate variants by fedKotikeD", + "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/9ddb8cf084e292571d4e9c79745db25befbd82fe. pai-searching-overlay heavily modified. Syndicate variants by fedKotikeD, and potato by Doru991", "size": { "x": 32, "y": 32 @@ -13,6 +13,9 @@ { "name": "pai-base" }, + { + "name": "potato-base" + }, { "name": "pai-off-overlay" }, @@ -57,6 +60,18 @@ 0.8 ] ] + }, + { + "name": "icon-potato-off" + }, + { + "name": "potato-off-overlay" + }, + { + "name": "potato-on-overlay" + }, + { + "name": "potato-searching-overlay" } ] } diff --git a/Resources/Textures/Objects/Fun/pai.rsi/potato-base.png b/Resources/Textures/Objects/Fun/pai.rsi/potato-base.png new file mode 100644 index 0000000000000000000000000000000000000000..b6e594430cd2bbb9ea259989541f8488b27329d3 GIT binary patch literal 476 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCikL1AIbUZKjy$ak!Iy+67&|8>O zU}a^sZ*tI_CDY#>%qq#rdbulUSEcCx+mjj^8n$%%b*3543T2pAX}_+~ra!}AS-s2p z78jrmpL{-T22%1RL4Lvi@dAdkl4SxwrJMyGk;M!Qd;={+1ukXCw{J?tR zy>@2bzriA%)PZ3>^b4{l4pWM{KtInbjFp00i_>zopr09{|xfB*mh literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Fun/pai.rsi/potato-off-overlay.png b/Resources/Textures/Objects/Fun/pai.rsi/potato-off-overlay.png new file mode 100644 index 0000000000000000000000000000000000000000..0d3f73515881919ee768f51983ede0326c453966 GIT binary patch literal 162 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=Dh+L6~vJ#O${~L32+R$B+p3x5pRqG8k~MUX=GSKae>4-G13+ zR}2`pen0b+h2e+b#?ya8-glI`8~JA6wF7EOaH@*RX5Bh#!-eBO9)qW=pUXO@geCw) C4KgDD literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Fun/pai.rsi/potato-on-overlay.png b/Resources/Textures/Objects/Fun/pai.rsi/potato-on-overlay.png new file mode 100644 index 0000000000000000000000000000000000000000..9926823662aa4a81604e6d89d32e93c3aa436e96 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=Dh+L6~vJ#O${~K@(3G$B+p3x92u;GAIbJ9Lzrv^u}*@XdH`n zfWfSjX1ll<;-=i&bZ(;h|J#p$AMs>h*defyVg3zopr0F8k! A&Hw-a literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Fun/pai.rsi/potato-searching-overlay.png b/Resources/Textures/Objects/Fun/pai.rsi/potato-searching-overlay.png new file mode 100644 index 0000000000000000000000000000000000000000..5d8d7cde30c3b830b6a68e733c93d39ecb5ffd04 GIT binary patch literal 186 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$1AIbUFRV2FeAFDsOL?R|6-Y6c1o;L3|Icv!6faOM180FpWHAE+-yslY z6xHx*019e*x;Tbd_$MbQF}R63Fr4I)kXXng;SheHVMEEi%Jg@qYP XF0ucfcJ*>H^-ePuXy&La6)GmqR*Bt{o|yVpx#5>~=$Fg?Nkl8UxnV@>AHGI{21kNH+>} S#{UPJ$>8bg=d#Wzp$Pyf^iT5u literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/potatoai_chip.rsi/meta.json b/Resources/Textures/Objects/Misc/potatoai_chip.rsi/meta.json new file mode 100644 index 0000000000..dec5a8d3f7 --- /dev/null +++ b/Resources/Textures/Objects/Misc/potatoai_chip.rsi/meta.json @@ -0,0 +1,14 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Drawn by @Doru991 for SS14", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + } + ] +} diff --git a/Resources/Textures/Objects/Power/power_cells.rsi/meta.json b/Resources/Textures/Objects/Power/power_cells.rsi/meta.json index 01c2300621..66dbf30841 100644 --- a/Resources/Textures/Objects/Power/power_cells.rsi/meta.json +++ b/Resources/Textures/Objects/Power/power_cells.rsi/meta.json @@ -5,7 +5,7 @@ "y": 32 }, "license": "CC-BY-SA-3.0", - "copyright": "https://github.com/tgstation/tgstation/commit/7dcdbc1468ffdc8689b984cb6b181d48ae41dbf2", + "copyright": "https://github.com/tgstation/tgstation/commit/7dcdbc1468ffdc8689b984cb6b181d48ae41dbf2, potato based on https://github.com/vgstation-coders/vgstation13/commit/1dbcf389b0ec6b2c51b002df5fef8dd1519f8068 edited by @Doru991", "states": [ { "name": "potato" diff --git a/Resources/Textures/Objects/Power/power_cells.rsi/potato.png b/Resources/Textures/Objects/Power/power_cells.rsi/potato.png index 5b0f7a5fe04b8b62f804fa629e1861933144196d..53572f46a122188df257488e291ff405b8d68d08 100644 GIT binary patch delta 448 zcmdnQex7-PWIZzj1B1(wu46!ou{g-xiDBJ2nU_EgOS+@4BLl<6e(pbstU!KXfKQ04 z%@h-z95pFNag{LnE!}=EcP0J5J?Y)Stc&w(YpaTVot>sk=q=1C*f%+7&XVct8f~ns ztV(jSc2$ZtG&FRk8O{o2m{)1vpJA}9-erA@3((Z%^;*aHfV6Z;kYDhBoPa^ygxeIT zjI+QavY3H^?=T269?xHq0u+4U>Eak-;s16*w@{OUfa}#Gu||_Q*8cd<|CVX>qs1TD ztOWl%j=oRZu$?ieum#nG-=a(Sh#WRtAECFa6We7c~&$a4+VY3ft&jY*;3Ow2ClP z7_M`RR@0JocM;NDF3ZK`e39NQ>Du14$?(m-aPYey&+qwuzkkp3%aa7|<9~+GXaWnY zRT6v3yC2a<6#*y(8A% zU4v_$Tk{T#jem|_>dm+6lA1HK1fJN6IWx< zLA0uXvC$E0lPtpZyNUbu?V*rW(Ppm^YFA*#b_!XQ(2nhV3DzrLe9U+%pCo_JL(t!fZsgH5l`C4haRC6u za*3{|?~qjt0VNV8=x?QB2o%dDg8o*Ayu}}&eEFuA)b0X0ZkTM@*2SsB38xiykA0#= zxPM!Ah>PVC#as?uQ!yTWn2#>Fk78E=2c{;4>B;Zu@9m*jF0rWTPLD(F3KOT#qh{vn z&g2&VCB3Mwlgl7XwZ5p8bOk)14!3Ylt|R6MlqMGBlqHdT>@+on?pgO4{b)0 z6?E;6%gb{a0OYX5@YfTb^KR%*!?B@3t022gsVlQr$M>-u{{f2{psVn%KTQAt002ov JPDHLkV1jHV*y#WO diff --git a/Resources/Textures/Objects/Specific/Robotics/mmi.rsi/meta.json b/Resources/Textures/Objects/Specific/Robotics/mmi.rsi/meta.json index 6499772c7a..fcdd9e1b26 100644 --- a/Resources/Textures/Objects/Specific/Robotics/mmi.rsi/meta.json +++ b/Resources/Textures/Objects/Specific/Robotics/mmi.rsi/meta.json @@ -76,4 +76,4 @@ ] } ] -} \ No newline at end of file +} From 41795720da7eb92ebfc755c8bc86ae3825ad2d45 Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Wed, 25 Oct 2023 18:53:38 -0400 Subject: [PATCH 053/102] [TEST MERGE] Slot-based Storage (#21212) --- Content.Client/Storage/UI/StorageWindow.cs | 44 ++++-- .../Tests/HumanInventoryUniformSlotsTest.cs | 8 +- Content.IntegrationTests/Tests/StackTest.cs | 39 ----- Content.IntegrationTests/Tests/StorageTest.cs | 142 ++++++++++++------ .../EntitySystems/ChemMasterSystem.cs | 6 +- .../Nutrition/EntitySystems/FoodSystem.cs | 3 +- .../Components/SecretStashComponent.cs | 2 +- .../StorageFillVisualizerSystem.cs | 7 +- .../Melee/EnergySword/EnergySwordSystem.cs | 4 +- .../Inventory/InventorySystem.Equip.cs | 2 +- Content.Shared/Item/ItemComponent.cs | 52 ++++++- Content.Shared/Item/ItemToggleComponent.cs | 5 +- Content.Shared/Item/SharedItemSystem.cs | 57 +++++-- .../EntitySystems/MagnetPickupSystem.cs | 5 +- .../EntitySystems/SharedStorageSystem.cs | 134 ++++++++++++----- Content.Shared/Storage/StorageComponent.cs | 33 ++-- .../en-US/components/storage-component.ftl | 7 +- .../en-US/items/components/item-component.ftl | 7 + Resources/Maps/Shuttles/striker.yml | 113 -------------- Resources/Maps/core.yml | 4 - Resources/Maps/europa.yml | 2 - .../Fills/Backpacks/StarterGear/backpack.yml | 5 +- .../Catalog/Fills/Backpacks/duffelbag.yml | 5 + .../Catalog/Fills/Boxes/ammunition.yml | 2 +- .../Catalog/Fills/Boxes/general.yml | 45 +++--- .../Catalog/Fills/Boxes/medical.yml | 5 +- .../Catalog/Fills/Boxes/security.yml | 9 ++ .../Prototypes/Catalog/Fills/Crates/fun.yml | 4 +- .../Prototypes/Catalog/Fills/Items/belt.yml | 11 +- .../Catalog/Fills/Items/briefcases.yml | 4 + .../Catalog/Fills/Items/firstaidkits.yml | 29 ++-- .../Entities/Clothing/Back/backpacks.yml | 14 +- .../Entities/Clothing/Back/duffel.yml | 11 +- .../Entities/Clothing/Back/satchel.yml | 6 +- .../Entities/Clothing/Back/specific.yml | 2 +- .../Clothing/Belt/base_clothingbelt.yml | 7 +- .../Entities/Clothing/Belt/belts.yml | 20 +-- .../Entities/Clothing/Belt/quiver.yml | 3 +- .../Entities/Clothing/Belt/waist_bags.yml | 7 +- .../Entities/Clothing/Ears/headsets.yml | 2 + .../Clothing/Eyes/base_clothingeyes.yml | 2 + .../Clothing/Hands/base_clothinghands.yml | 2 + .../Clothing/Head/base_clothinghead.yml | 6 +- .../Entities/Clothing/Head/hats.yml | 6 +- .../Clothing/Masks/base_clothingmask.yml | 2 + .../Clothing/Neck/base_clothingneck.yml | 2 +- .../Entities/Clothing/Neck/pins.yml | 2 +- .../OuterClothing/base_clothingouter.yml | 12 +- .../Clothing/OuterClothing/hardsuits.yml | 2 +- .../Entities/Clothing/OuterClothing/suits.yml | 4 +- .../Clothing/OuterClothing/wintercoats.yml | 2 +- .../Clothing/Shoes/base_clothingshoes.yml | 4 +- .../Entities/Clothing/Shoes/specific.yml | 2 +- .../Entities/Clothing/base_clothing.yml | 2 + .../Entities/Debugging/debug_sweps.yml | 2 +- .../Prototypes/Entities/Mobs/NPCs/animals.yml | 6 +- .../Prototypes/Entities/Mobs/NPCs/silicon.yml | 4 +- .../Objects/Consumable/Drinks/drinks_cans.yml | 4 +- .../Objects/Consumable/Food/Baked/bread.yml | 2 +- .../Objects/Consumable/Food/Baked/cake.yml | 6 +- .../Consumable/Food/Baked/donkpocket.yml | 2 +- .../Objects/Consumable/Food/Baked/donut.yml | 2 +- .../Objects/Consumable/Food/Baked/misc.yml | 2 +- .../Objects/Consumable/Food/Baked/pizza.yml | 4 +- .../Consumable/Food/Containers/box.yml | 29 ++-- .../Consumable/Food/Containers/tin.yml | 4 +- .../Entities/Objects/Consumable/Food/egg.yml | 4 +- .../Entities/Objects/Consumable/Food/meat.yml | 4 +- .../Objects/Consumable/Food/produce.yml | 18 +-- .../Objects/Consumable/Food/skewer.yml | 2 +- .../Objects/Consumable/Food/snacks.yml | 10 +- .../Smokeables/Cigarettes/cartons.yml | 4 +- .../Smokeables/Cigarettes/cigarette.yml | 4 +- .../Smokeables/Cigarettes/joints.yml | 4 +- .../Smokeables/Cigarettes/packs.yml | 9 +- .../Smokeables/Cigarettes/rolling_paper.yml | 11 +- .../Consumable/Smokeables/Cigars/case.yml | 4 +- .../Consumable/Smokeables/Cigars/cigar.yml | 4 +- .../Consumable/Smokeables/Pipes/pipe.yml | 2 +- .../Entities/Objects/Decoration/lidsalami.yml | 2 +- .../Entities/Objects/Decoration/present.yml | 4 +- .../Objects/Devices/Electronics/triggers.yml | 2 +- .../Syndicate_Gadgets/chimp_upgrade_kit.yml | 6 +- .../Objects/Devices/forensic_scanner.yml | 2 +- .../Entities/Objects/Devices/pda.yml | 2 +- .../Fun/Instruments/base_instruments.yml | 2 +- .../Fun/Instruments/instruments_brass.yml | 8 +- .../Fun/Instruments/instruments_misc.yml | 16 +- .../Instruments/instruments_percussion.yml | 10 +- .../Fun/Instruments/instruments_string.yml | 16 +- .../Fun/Instruments/instruments_wind.yml | 20 +-- .../Entities/Objects/Fun/bike_horn.yml | 8 +- .../Entities/Objects/Fun/crayons.yml | 7 +- .../Prototypes/Entities/Objects/Fun/darts.yml | 8 +- .../Prototypes/Entities/Objects/Fun/dice.yml | 2 +- .../Entities/Objects/Fun/dice_bag.yml | 7 +- .../Entities/Objects/Fun/puppet.yml | 2 +- .../Prototypes/Entities/Objects/Fun/toys.yml | 26 ++-- .../Objects/Materials/Sheets/glass.yml | 19 +-- .../Objects/Materials/Sheets/metal.yml | 12 +- .../Objects/Materials/Sheets/other.yml | 15 +- .../Entities/Objects/Materials/ingots.yml | 8 +- .../Entities/Objects/Materials/materials.yml | 45 +----- .../Entities/Objects/Materials/ore.yml | 17 +-- .../Entities/Objects/Materials/parts.yml | 8 +- .../Entities/Objects/Materials/shards.yml | 2 +- .../Entities/Objects/Misc/bedsheets.yml | 2 +- .../Prototypes/Entities/Objects/Misc/box.yml | 4 +- .../Entities/Objects/Misc/briefcases.yml | 12 +- .../Entities/Objects/Misc/eggspider.yml | 2 +- .../Objects/Misc/fire_extinguisher.yml | 2 +- .../Entities/Objects/Misc/fluff_lights.yml | 4 +- .../Entities/Objects/Misc/handcuffs.yml | 10 +- .../Objects/Misc/identification_cards.yml | 1 + .../Entities/Objects/Misc/implanters.yml | 2 +- .../Objects/Misc/improvised_gun_parts.yml | 8 +- .../Entities/Objects/Misc/machine_parts.yml | 2 +- .../Entities/Objects/Misc/medalcase.yml | 5 +- .../Entities/Objects/Misc/monkeycube.yml | 2 - .../Entities/Objects/Misc/paper.yml | 23 +-- .../Entities/Objects/Misc/potatoai_chip.yml | 4 +- .../Objects/Misc/subdermal_implants.yml | 5 +- .../Entities/Objects/Power/antimatter_jar.yml | 2 +- .../Objects/Power/antimatter_part.yml | 2 +- .../Entities/Objects/Power/powersink.yml | 2 +- .../Entities/Objects/Power/solar_parts.yml | 2 +- .../Entities/Objects/Shields/shields.yml | 12 +- .../Objects/Specific/Chapel/bibles.yml | 6 +- .../Objects/Specific/Chemistry/chem_bag.yml | 4 +- .../Objects/Specific/Forensics/forensics.yml | 2 +- .../Objects/Specific/Hydroponics/leaves.yml | 4 +- .../Objects/Specific/Hydroponics/seeds.yml | 6 +- .../Objects/Specific/Hydroponics/tools.yml | 6 +- .../Objects/Specific/Janitorial/janitor.yml | 8 +- .../Objects/Specific/Janitorial/trashbag.yml | 9 +- .../Objects/Specific/Kitchen/foodcarts.yml | 19 ++- .../Objects/Specific/Librarian/books_bag.yml | 4 +- .../Specific/Mech/mech_construction.yml | 8 +- .../Objects/Specific/Mech/mecha_equipment.yml | 2 +- .../Objects/Specific/Medical/defib.yml | 2 +- .../Objects/Specific/Medical/disease.yml | 4 +- .../Objects/Specific/Medical/healing.yml | 102 +++++++++++-- .../Objects/Specific/Medical/hypospray.yml | 8 +- .../Objects/Specific/Medical/medkits.yml | 7 +- .../Objects/Specific/Medical/morgue.yml | 2 +- .../Objects/Specific/Research/rped.yml | 4 +- .../Objects/Specific/Salvage/ore_bag.yml | 5 +- .../Service/vending_machine_restock.yml | 2 +- .../Xenoarchaeology/item_artifacts.yml | 2 +- .../Objects/Specific/chemical-containers.yml | 2 +- .../Objects/Specific/chemistry-bottles.yml | 2 +- .../Entities/Objects/Specific/chemistry.yml | 12 +- .../Entities/Objects/Specific/syndicate.yml | 8 +- .../Objects/Tools/access_configurator.yml | 12 +- .../Entities/Objects/Tools/bucket.yml | 2 +- .../Entities/Objects/Tools/cable_coils.yml | 14 +- .../Entities/Objects/Tools/cowtools.yml | 2 +- .../Entities/Objects/Tools/fulton.yml | 6 +- .../Entities/Objects/Tools/gas_tanks.yml | 4 +- .../Objects/Tools/inflatable_wall.yml | 10 +- .../Entities/Objects/Tools/jaws_of_life.yml | 4 +- .../Entities/Objects/Tools/jetpacks.yml | 4 +- .../Entities/Objects/Tools/lighters.yml | 2 +- .../Entities/Objects/Tools/matches.yml | 12 +- .../Entities/Objects/Tools/toolbox.yml | 9 +- .../Entities/Objects/Tools/tools.yml | 16 +- .../Entities/Objects/Tools/welders.yml | 4 +- .../Entities/Objects/Vehicles/keys.yml | 2 +- .../Entities/Objects/Weapons/Bombs/funny.yml | 2 +- .../Objects/Weapons/Bombs/plastic.yml | 2 +- .../Entities/Objects/Weapons/Bombs/spider.yml | 2 +- .../Guns/Ammunition/Boxes/antimateriel.yml | 2 +- .../Guns/Ammunition/Boxes/caseless_rifle.yml | 2 +- .../Guns/Ammunition/Boxes/light_rifle.yml | 2 +- .../Weapons/Guns/Ammunition/Boxes/magnum.yml | 2 +- .../Weapons/Guns/Ammunition/Boxes/pistol.yml | 2 +- .../Weapons/Guns/Ammunition/Boxes/rifle.yml | 2 +- .../Ammunition/Cartridges/base_cartridge.yml | 2 +- .../Ammunition/Magazines/caseless_rifle.yml | 6 +- .../Guns/Ammunition/Magazines/heavy_rifle.yml | 2 +- .../Guns/Ammunition/Magazines/light_rifle.yml | 2 +- .../Guns/Ammunition/Magazines/magnum.yml | 2 +- .../Guns/Ammunition/Magazines/pistol.yml | 6 +- .../Guns/Ammunition/Magazines/rifle.yml | 2 +- .../Guns/Ammunition/Magazines/shotgun.yml | 2 +- .../Weapons/Guns/Ammunition/explosives.yml | 6 +- .../Objects/Weapons/Guns/Basic/base_pka.yml | 2 +- .../Objects/Weapons/Guns/Basic/base_staff.yml | 2 +- .../Objects/Weapons/Guns/Basic/base_wand.yml | 2 +- .../Weapons/Guns/Basic/spraynozzle.yml | 2 +- .../Objects/Weapons/Guns/Basic/watergun.yml | 6 +- .../Weapons/Guns/Battery/battery_guns.yml | 14 +- .../Entities/Objects/Weapons/Guns/Bow/bow.yml | 2 +- .../Objects/Weapons/Guns/HMGs/hmgs.yml | 2 +- .../Objects/Weapons/Guns/LMGs/lmgs.yml | 2 +- .../Weapons/Guns/Launchers/launchers.yml | 2 +- .../Objects/Weapons/Guns/Pistols/pistols.yml | 2 +- .../Weapons/Guns/Projectiles/arrows.yml | 2 +- .../Weapons/Guns/Revolvers/revolvers.yml | 6 +- .../Objects/Weapons/Guns/Rifles/rifles.yml | 2 +- .../Objects/Weapons/Guns/SMGs/smgs.yml | 2 +- .../Weapons/Guns/Shotguns/shotguns.yml | 16 +- .../Objects/Weapons/Guns/Snipers/snipers.yml | 2 +- .../Objects/Weapons/Guns/flare_gun.yml | 2 +- .../Objects/Weapons/Guns/pneumatic_cannon.yml | 20 ++- .../Objects/Weapons/Melee/armblade.yml | 2 +- .../Objects/Weapons/Melee/baseball_bat.yml | 2 +- .../Objects/Weapons/Melee/chainsaw.yml | 2 +- .../Entities/Objects/Weapons/Melee/cult.yml | 6 +- .../Objects/Weapons/Melee/e_sword.yml | 8 +- .../Objects/Weapons/Melee/fireaxe.yml | 2 +- .../Entities/Objects/Weapons/Melee/gohei.yml | 2 +- .../Entities/Objects/Weapons/Melee/knife.yml | 24 ++- .../Entities/Objects/Weapons/Melee/mining.yml | 6 +- .../Entities/Objects/Weapons/Melee/needle.yml | 2 +- .../Objects/Weapons/Melee/pickaxe.yml | 2 +- .../Entities/Objects/Weapons/Melee/spear.yml | 2 +- .../Objects/Weapons/Melee/stunprod.yml | 2 +- .../Entities/Objects/Weapons/Melee/sword.yml | 12 +- .../Objects/Weapons/Melee/weapon_toolbox.yml | 2 +- .../Objects/Weapons/Melee/white_cane.yml | 2 +- .../Objects/Weapons/Throwable/bola.yml | 2 +- .../Objects/Weapons/Throwable/grenades.yml | 4 +- .../Entities/Objects/Weapons/security.yml | 6 +- .../Prototypes/Entities/Objects/base_item.yml | 2 +- .../Structures/Furniture/bookshelf.yml | 3 +- .../Entities/Structures/Furniture/chairs.yml | 4 +- .../Entities/Structures/Furniture/dresser.yml | 13 +- .../Structures/Furniture/rollerbeds.yml | 2 +- .../Structures/Piping/Atmospherics/pipes.yml | 2 +- .../Specific/Atmospherics/sensor.yml | 2 +- .../Structures/Storage/filing_cabinets.yml | 6 +- .../Entities/Structures/Storage/ore_box.yml | 3 +- .../XenoArch/Effects/utility_effects.yml | 4 +- 234 files changed, 1052 insertions(+), 1008 deletions(-) delete mode 100644 Content.IntegrationTests/Tests/StackTest.cs diff --git a/Content.Client/Storage/UI/StorageWindow.cs b/Content.Client/Storage/UI/StorageWindow.cs index 1af50cb147..325cbd8a6a 100644 --- a/Content.Client/Storage/UI/StorageWindow.cs +++ b/Content.Client/Storage/UI/StorageWindow.cs @@ -1,16 +1,15 @@ using System.Numerics; -using Robust.Client.GameObjects; +using Content.Client.Message; using Robust.Client.Graphics; using Robust.Client.UserInterface.Controls; -using Robust.Client.UserInterface.CustomControls; using Content.Client.Stylesheets; using Content.Client.UserInterface.Controls; using Content.Shared.IdentityManagement; using Content.Shared.Item; using Content.Shared.Stacks; using Content.Shared.Storage; +using Content.Shared.Storage.EntitySystems; using Robust.Client.UserInterface; -using Robust.Shared.Containers; using static Robust.Client.UserInterface.Controls.BoxContainer; using Direction = Robust.Shared.Maths.Direction; @@ -23,7 +22,9 @@ namespace Content.Client.Storage.UI { private readonly IEntityManager _entityManager; - private readonly Label _information; + private readonly SharedStorageSystem _storage; + + private readonly RichTextLabel _information; public readonly ContainerButton StorageContainerButton; public readonly ListContainer EntityList; private readonly StyleBoxFlat _hoveredBox = new() { BackgroundColor = Color.Black.WithAlpha(0.35f) }; @@ -32,6 +33,7 @@ namespace Content.Client.Storage.UI public StorageWindow(IEntityManager entityManager) { _entityManager = entityManager; + _storage = _entityManager.System(); SetSize = new Vector2(240, 320); Title = Loc.GetString("comp-storage-window-title"); RectClipContent = true; @@ -60,11 +62,14 @@ namespace Content.Client.Storage.UI StorageContainerButton.AddChild(vBox); - _information = new Label + _information = new RichTextLabel { - Text = Loc.GetString("comp-storage-window-volume", ("itemCount", 0), ("usedVolume", 0), ("maxVolume", 0)), VerticalAlignment = VAlignment.Center }; + _information.SetMessage(Loc.GetString("comp-storage-window-volume", + ("itemCount", 0), + ("maxCount", 0), + ("size", SharedItemSystem.GetItemSizeLocale(ItemSize.Normal)))); vBox.AddChild(_information); @@ -101,15 +106,23 @@ namespace Content.Client.Storage.UI EntityList.PopulateList(list); - // Sets information about entire storage container current capacity - if (component.StorageCapacityMax != 0) + SetStorageInformation((entity, component)); + } + + private void SetStorageInformation(Entity uid) + { + if (uid.Comp.MaxSlots != uid.Comp.Container.ContainedEntities.Count + && _storage.GetCumulativeItemSizes(uid, uid.Comp) == _storage.GetMaxTotalWeight((uid, uid.Comp))) { - _information.Text = Loc.GetString("comp-storage-window-volume", ("itemCount", storedCount), - ("usedVolume", component.StorageUsed), ("maxVolume", component.StorageCapacityMax)); + _information.SetMarkup(Loc.GetString("comp-storage-window-volume-full", + ("size", SharedItemSystem.GetItemSizeLocale(_storage.GetMaxItemSize((uid, uid.Comp)))))); } else { - _information.Text = Loc.GetString("comp-storage-window-volume-unlimited", ("itemCount", storedCount)); + _information.SetMarkup(Loc.GetString("comp-storage-window-volume", + ("itemCount", uid.Comp.Container.ContainedEntities.Count), + ("maxCount", uid.Comp.MaxSlots), + ("size", SharedItemSystem.GetItemSizeLocale(_storage.GetMaxItemSize((uid, uid.Comp)))))); } } @@ -122,10 +135,9 @@ namespace Content.Client.Storage.UI || !_entityManager.EntityExists(entity)) return; - _entityManager.TryGetComponent(entity, out ItemComponent? item); _entityManager.TryGetComponent(entity, out StackComponent? stack); + _entityManager.TryGetComponent(entity, out ItemComponent? item); var count = stack?.Count ?? 1; - var size = item?.Size; var spriteView = new SpriteView { @@ -147,12 +159,14 @@ namespace Content.Client.Storage.UI HorizontalExpand = true, ClipText = true, Text = _entityManager.GetComponent(Identity.Entity(entity, _entityManager)).EntityName + - (count > 1 ? $" x {count}" : string.Empty), + (count > 1 ? $" x {count}" : string.Empty) }, new Label { Align = Label.AlignMode.Right, - Text = size.ToString() ?? Loc.GetString("comp-storage-no-item-size"), + Text = item?.Size != null + ? SharedItemSystem.GetItemSizeLocale(item.Size) + : Loc.GetString("comp-storage-no-item-size") } } }); diff --git a/Content.IntegrationTests/Tests/HumanInventoryUniformSlotsTest.cs b/Content.IntegrationTests/Tests/HumanInventoryUniformSlotsTest.cs index 3ea3dd7916..4bba605f0a 100644 --- a/Content.IntegrationTests/Tests/HumanInventoryUniformSlotsTest.cs +++ b/Content.IntegrationTests/Tests/HumanInventoryUniformSlotsTest.cs @@ -26,7 +26,7 @@ namespace Content.IntegrationTests.Tests - type: Clothing slots: [innerclothing] - type: Item - size: 5 + size: Tiny - type: entity name: IDCardDummy @@ -36,7 +36,7 @@ namespace Content.IntegrationTests.Tests slots: - idcard - type: Item - size: 5 + size: Tiny - type: IdCard - type: entity @@ -44,14 +44,14 @@ namespace Content.IntegrationTests.Tests id: FlashlightDummy components: - type: Item - size: 5 + size: Tiny - type: entity name: ToolboxDummy id: ToolboxDummy components: - type: Item - size: 9999 + size: Huge "; [Test] public async Task Test() diff --git a/Content.IntegrationTests/Tests/StackTest.cs b/Content.IntegrationTests/Tests/StackTest.cs deleted file mode 100644 index a34dd7e53d..0000000000 --- a/Content.IntegrationTests/Tests/StackTest.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Content.Shared.Item; -using Content.Shared.Stacks; -using Robust.Shared.GameObjects; -using Robust.Shared.Prototypes; - -namespace Content.IntegrationTests.Tests; - -[TestFixture] -public sealed class StackTest -{ - [Test] - public async Task StackCorrectItemSize() - { - await using var pair = await PoolManager.GetServerClient(); - var server = pair.Server; - - var protoManager = server.ResolveDependency(); - var compFact = server.ResolveDependency(); - - Assert.Multiple(() => - { - foreach (var entity in PoolManager.GetPrototypesWithComponent(server)) - { - if (!entity.TryGetComponent(out var stackComponent, compFact) || - !entity.TryGetComponent(out var itemComponent, compFact)) - continue; - - if (!protoManager.TryIndex(stackComponent.StackTypeId, out var stackProto) || - stackProto.ItemSize == null) - continue; - - var expectedSize = stackProto.ItemSize * stackComponent.Count; - Assert.That(itemComponent.Size, Is.EqualTo(expectedSize), $"Prototype id: {entity.ID} has an item size of {itemComponent.Size} but expected size of {expectedSize}."); - } - }); - - await pair.CleanReturnAsync(); - } -} diff --git a/Content.IntegrationTests/Tests/StorageTest.cs b/Content.IntegrationTests/Tests/StorageTest.cs index ea7f3f5866..de3b7f149d 100644 --- a/Content.IntegrationTests/Tests/StorageTest.cs +++ b/Content.IntegrationTests/Tests/StorageTest.cs @@ -3,11 +3,12 @@ using System.Collections.Generic; using System.Linq; using Content.Server.Storage.Components; using Content.Shared.Item; +using Content.Shared.Prototypes; using Content.Shared.Storage; using Content.Shared.Storage.Components; +using Content.Shared.Storage.EntitySystems; using Robust.Shared.GameObjects; using Robust.Shared.Prototypes; -using Robust.UnitTesting; namespace Content.IntegrationTests.Tests { @@ -32,9 +33,11 @@ namespace Content.IntegrationTests.Tests { if (!proto.TryGetComponent("Storage", out var storage) || storage.Whitelist != null || - !proto.TryGetComponent("Item", out var item)) continue; + storage.MaxItemSize == null || + !proto.TryGetComponent("Item", out var item)) + continue; - Assert.That(storage.StorageCapacityMax, Is.LessThanOrEqualTo(item.Size), $"Found storage arbitrage on {proto.ID}"); + Assert.That(storage.MaxItemSize.Value, Is.LessThan(item.Size), $"Found storage arbitrage on {proto.ID}"); } }); await pair.CleanReturnAsync(); @@ -82,69 +85,120 @@ namespace Content.IntegrationTests.Tests { foreach (var proto in PoolManager.GetPrototypesWithComponent(server)) { - int capacity; - var isEntStorage = false; + if (proto.HasComponent(compFact)) + continue; - if (proto.TryGetComponent("Storage", out var storage)) + if (!proto.TryGetComponent("Storage", out var storage)) { - capacity = storage.StorageCapacityMax; + Assert.Fail($"Entity {proto.ID} has storage-fill without a storage component!"); + continue; } - else if (proto.TryGetComponent("EntityStorage", out var entStorage)) + + proto.TryGetComponent("Item", out var item); + + var maxSize = storage.MaxItemSize ?? + (item?.Size == null + ? SharedStorageSystem.DefaultStorageMaxItemSize + : (ItemSize) Math.Max(0, (int) item.Size - 1)); + + var capacity = storage.MaxTotalWeight ?? + storage.MaxSlots * SharedItemSystem.GetItemSizeWeight(storage.MaxItemSize ?? maxSize); + + var fill = (StorageFillComponent) proto.Components[id].Component; + var size = GetFillSize(fill, false, protoMan); + + Assert.That(size, Is.LessThanOrEqualTo(capacity), $"{proto.ID} storage fill is too large."); + Assert.That(GetFillSize(fill, true, protoMan), Is.LessThanOrEqualTo(storage.MaxSlots), $"{proto.ID} storage fill has too many items."); + + foreach (var entry in fill.Contents) { - capacity = entStorage.Capacity; - isEntStorage = true; + if (entry.PrototypeId == null) + continue; + + if (!protoMan.TryIndex(entry.PrototypeId, out var fillItem)) + continue; + + if (!fillItem.TryGetComponent("Item", out var entryItem)) + continue; + + Assert.That(entryItem.Size, Is.LessThanOrEqualTo(maxSize), + $"Entity {proto.ID} has storage-fill item, {entry.PrototypeId}, that is too large"); } - else + } + }); + + await pair.CleanReturnAsync(); + + } + + [Test] + public async Task TestSufficientSpaceForEntityStorageFill() + { + await using var pair = await PoolManager.GetServerClient(); + var server = pair.Server; + + var protoMan = server.ResolveDependency(); + var compFact = server.ResolveDependency(); + var id = compFact.GetComponentName(typeof(StorageFillComponent)); + + Assert.Multiple(() => + { + foreach (var proto in PoolManager.GetPrototypesWithComponent(server)) + { + if (proto.HasComponent(compFact)) + continue; + + if (!proto.TryGetComponent("EntityStorage", out var entStorage)) { Assert.Fail($"Entity {proto.ID} has storage-fill without a storage component!"); continue; } var fill = (StorageFillComponent) proto.Components[id].Component; - var size = GetFillSize(fill, isEntStorage); - Assert.That(size, Is.LessThanOrEqualTo(capacity), $"{proto.ID} storage fill is too large."); + var size = GetFillSize(fill, true, protoMan); + Assert.That(size, Is.LessThanOrEqualTo(entStorage.Capacity), + $"{proto.ID} storage fill is too large."); } }); + await pair.CleanReturnAsync(); + } - int GetEntrySize(EntitySpawnEntry entry, bool isEntStorage) + private int GetEntrySize(EntitySpawnEntry entry, bool getCount, IPrototypeManager protoMan) + { + if (entry.PrototypeId == null) + return 0; + + if (!protoMan.TryIndex(entry.PrototypeId, out var proto)) { - if (entry.PrototypeId == null) - return 0; - - if (!protoMan.TryIndex(entry.PrototypeId, out var proto)) - { - Assert.Fail($"Unknown prototype: {entry.PrototypeId}"); - return 0; - } - - if (isEntStorage) - return entry.Amount; - - if (proto.TryGetComponent("Item", out var item)) - return item.Size * entry.Amount; - - Assert.Fail($"Prototype is missing item comp: {entry.PrototypeId}"); + Assert.Fail($"Unknown prototype: {entry.PrototypeId}"); return 0; } - int GetFillSize(StorageFillComponent fill, bool isEntStorage) + if (getCount) + return entry.Amount; + + if (proto.TryGetComponent("Item", out var item)) + return SharedItemSystem.GetItemSizeWeight(item.Size) * entry.Amount; + + Assert.Fail($"Prototype is missing item comp: {entry.PrototypeId}"); + return 0; + } + + private int GetFillSize(StorageFillComponent fill, bool getCount, IPrototypeManager protoMan) + { + var totalSize = 0; + var groups = new Dictionary(); + foreach (var entry in fill.Contents) { - var totalSize = 0; - var groups = new Dictionary(); - foreach (var entry in fill.Contents) - { - var size = GetEntrySize(entry, isEntStorage); + var size = GetEntrySize(entry, getCount, protoMan); - if (entry.GroupId == null) - totalSize += size; - else - groups[entry.GroupId] = Math.Max(size, groups.GetValueOrDefault(entry.GroupId)); - } - - return totalSize + groups.Values.Sum(); + if (entry.GroupId == null) + totalSize += size; + else + groups[entry.GroupId] = Math.Max(size, groups.GetValueOrDefault(entry.GroupId)); } - await pair.CleanReturnAsync(); + return totalSize + groups.Values.Sum(); } } } diff --git a/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs b/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs index a831165e68..e9cf661347 100644 --- a/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs @@ -187,7 +187,7 @@ namespace Content.Server.Chemistry.EntitySystems } // Ensure the number is valid. - if (message.Number == 0 || message.Number > storage.StorageCapacityMax - storage.StorageUsed) + if (message.Number == 0 || _storageSystem.HasSpace((chemMaster, storage))) return; // Ensure the amount is valid. @@ -345,7 +345,7 @@ namespace Content.Server.Chemistry.EntitySystems } } - if (!TryComp(container, out StorageComponent? storage)) + if (!TryComp(container, out StorageComponent? storage) || storage.Container == null) return null; var pills = storage.Container?.ContainedEntities.Select((Func) (pill => @@ -358,7 +358,7 @@ namespace Content.Server.Chemistry.EntitySystems if (pills == null) return null; - return new ContainerInfo(name, storage.StorageUsed, storage.StorageCapacityMax) + return new ContainerInfo(name, storage.Container!.ContainedEntities.Count, storage.MaxSlots) { Entities = pills }; diff --git a/Content.Server/Nutrition/EntitySystems/FoodSystem.cs b/Content.Server/Nutrition/EntitySystems/FoodSystem.cs index ff4ec41dd9..758d42356e 100644 --- a/Content.Server/Nutrition/EntitySystems/FoodSystem.cs +++ b/Content.Server/Nutrition/EntitySystems/FoodSystem.cs @@ -1,3 +1,4 @@ +using System.Linq; using Content.Server.Body.Components; using Content.Server.Body.Systems; using Content.Server.Inventory; @@ -122,7 +123,7 @@ public sealed class FoodSystem : EntitySystem return (false, false); // Check for used storage on the food item - if (TryComp(food, out var storageState) && storageState.StorageUsed != 0) + if (TryComp(food, out var storageState) && storageState.Container.ContainedEntities.Any()) { _popup.PopupEntity(Loc.GetString("food-has-used-storage", ("food", food)), user, user); return (false, true); diff --git a/Content.Server/Storage/Components/SecretStashComponent.cs b/Content.Server/Storage/Components/SecretStashComponent.cs index 60d0c829e9..6c7095617c 100644 --- a/Content.Server/Storage/Components/SecretStashComponent.cs +++ b/Content.Server/Storage/Components/SecretStashComponent.cs @@ -19,7 +19,7 @@ namespace Content.Server.Storage.Components /// Max item size that can be fitted into secret stash. /// [DataField("maxItemSize")] - public int MaxItemSize = (int) ReferenceSizes.Pocket; + public ItemSize MaxItemSize = ItemSize.Small; /// /// IC secret stash name. For example "the toilet cistern". diff --git a/Content.Server/Storage/EntitySystems/StorageFillVisualizerSystem.cs b/Content.Server/Storage/EntitySystems/StorageFillVisualizerSystem.cs index ed48de2e45..5fbd328499 100644 --- a/Content.Server/Storage/EntitySystems/StorageFillVisualizerSystem.cs +++ b/Content.Server/Storage/EntitySystems/StorageFillVisualizerSystem.cs @@ -1,7 +1,6 @@ using Content.Shared.Rounding; using Content.Shared.Storage; using Content.Shared.Storage.Components; -using Robust.Server.GameObjects; using Robust.Shared.Containers; namespace Content.Server.Storage.EntitySystems; @@ -13,12 +12,12 @@ public sealed class StorageFillVisualizerSystem : EntitySystem public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnInserted); SubscribeLocalEvent(OnRemoved); } - private void OnInit(EntityUid uid, StorageFillVisualizerComponent component, ComponentInit args) + private void OnStartup(EntityUid uid, StorageFillVisualizerComponent component, ComponentStartup args) { UpdateAppearance(uid, component: component); } @@ -42,7 +41,7 @@ public sealed class StorageFillVisualizerSystem : EntitySystem if (component.MaxFillLevels < 1) return; - var level = ContentHelpers.RoundToEqualLevels(storage.StorageUsed, storage.StorageCapacityMax, component.MaxFillLevels); + var level = ContentHelpers.RoundToEqualLevels(storage.Container.ContainedEntities.Count, storage.MaxSlots, component.MaxFillLevels); _appearance.SetData(uid, StorageFillVisuals.FillLevel, level, appearance); } } diff --git a/Content.Server/Weapons/Melee/EnergySword/EnergySwordSystem.cs b/Content.Server/Weapons/Melee/EnergySword/EnergySwordSystem.cs index fcd42f5a28..80316d64f9 100644 --- a/Content.Server/Weapons/Melee/EnergySword/EnergySwordSystem.cs +++ b/Content.Server/Weapons/Melee/EnergySword/EnergySwordSystem.cs @@ -98,7 +98,7 @@ public sealed class EnergySwordSystem : EntitySystem { if (TryComp(uid, out ItemComponent? item)) { - _item.SetSize(uid, 5, item); + _item.SetSize(uid, ItemSize.Small, item); } if (TryComp(uid, out var malus)) @@ -125,7 +125,7 @@ public sealed class EnergySwordSystem : EntitySystem { if (TryComp(uid, out ItemComponent? item)) { - _item.SetSize(uid, 9999, item); + _item.SetSize(uid, ItemSize.Huge, item); } if (comp.IsSharp) diff --git a/Content.Shared/Inventory/InventorySystem.Equip.cs b/Content.Shared/Inventory/InventorySystem.Equip.cs index 90c9f0e1e0..23c0fbd0a2 100644 --- a/Content.Shared/Inventory/InventorySystem.Equip.cs +++ b/Content.Shared/Inventory/InventorySystem.Equip.cs @@ -264,7 +264,7 @@ public abstract partial class InventorySystem if (slotDefinition.DependsOn != null && !TryGetSlotEntity(target, slotDefinition.DependsOn, out _, inventory)) return false; - var fittingInPocket = slotDefinition.SlotFlags.HasFlag(SlotFlags.POCKET) && item is { Size: <= (int) ReferenceSizes.Pocket }; + var fittingInPocket = slotDefinition.SlotFlags.HasFlag(SlotFlags.POCKET) && item is { Size: <= ItemSize.Small }; if (clothing == null && !fittingInPocket || clothing != null && !clothing.Slots.HasFlag(slotDefinition.SlotFlags) && !fittingInPocket) { diff --git a/Content.Shared/Item/ItemComponent.cs b/Content.Shared/Item/ItemComponent.cs index 7516f4faca..6d91f7cb4e 100644 --- a/Content.Shared/Item/ItemComponent.cs +++ b/Content.Shared/Item/ItemComponent.cs @@ -13,18 +13,17 @@ namespace Content.Shared.Item; [Access(typeof(SharedItemSystem))] public sealed partial class ItemComponent : Component { - [ViewVariables(VVAccess.ReadWrite)] - [DataField("size")] - [Access(typeof(SharedItemSystem), Other = AccessPermissions.ReadExecute)] - public int Size = 5; + [DataField, ViewVariables(VVAccess.ReadWrite)] + [Access(typeof(SharedItemSystem))] + public ItemSize Size = ItemSize.Small; [Access(typeof(SharedItemSystem))] - [DataField("inhandVisuals")] + [DataField] public Dictionary> InhandVisuals = new(); [Access(typeof(SharedItemSystem))] [ViewVariables(VVAccess.ReadWrite)] - [DataField("heldPrefix")] + [DataField] public string? HeldPrefix; /// @@ -39,10 +38,10 @@ public sealed partial class ItemComponent : Component [Serializable, NetSerializable] public sealed class ItemComponentState : ComponentState { - public int Size { get; } + public ItemSize Size { get; } public string? HeldPrefix { get; } - public ItemComponentState(int size, string? heldPrefix) + public ItemComponentState(ItemSize size, string? heldPrefix) { Size = size; HeldPrefix = heldPrefix; @@ -66,6 +65,43 @@ public sealed class VisualsChangedEvent : EntityEventArgs } } +/// +/// Abstracted sizes for items. +/// Used to determine what can fit into inventories. +/// +public enum ItemSize +{ + /// + /// Items that can be held completely in one's hand. + /// + Tiny = 1, + + /// + /// Items that can fit inside of a standard pocket. + /// + Small = 2, + + /// + /// Items that can fit inside of a standard bag. + /// + Normal = 3, + + /// + /// Items that are too large to fit inside of standard bags, but can worn in exterior slots or placed in custom containers. + /// + Large = 4, + + /// + /// Items that are too large to place inside of any kind of container. + /// + Huge = 5, + + /// + /// Picture furry gf + /// + Ginormous = 6 +} + /// /// Reference sizes for common containers and items. /// diff --git a/Content.Shared/Item/ItemToggleComponent.cs b/Content.Shared/Item/ItemToggleComponent.cs index fda4d0904a..250306f8c7 100644 --- a/Content.Shared/Item/ItemToggleComponent.cs +++ b/Content.Shared/Item/ItemToggleComponent.cs @@ -1,3 +1,4 @@ +using Content.Shared.Item; using Robust.Shared.Audio; using Robust.Shared.GameStates; @@ -20,11 +21,11 @@ public sealed partial class ItemToggleComponent : Component [ViewVariables(VVAccess.ReadWrite)] [DataField("offSize")] - public int OffSize = 1; + public ItemSize OffSize = ItemSize.Small; [ViewVariables(VVAccess.ReadWrite)] [DataField("onSize")] - public int OnSize = 9999; + public ItemSize OnSize = ItemSize.Huge; } [ByRefEvent] diff --git a/Content.Shared/Item/SharedItemSystem.cs b/Content.Shared/Item/SharedItemSystem.cs index 5f890af99f..d7e7b3630f 100644 --- a/Content.Shared/Item/SharedItemSystem.cs +++ b/Content.Shared/Item/SharedItemSystem.cs @@ -1,23 +1,27 @@ -using Content.Shared.CombatMode; using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction; using Content.Shared.Stacks; using Content.Shared.Verbs; using Content.Shared.Examine; +using JetBrains.Annotations; using Robust.Shared.Containers; using Robust.Shared.GameStates; -using Robust.Shared.Prototypes; using Robust.Shared.Utility; namespace Content.Shared.Item; public abstract class SharedItemSystem : EntitySystem { - [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly SharedHandsSystem _handsSystem = default!; - [Dependency] private readonly SharedCombatModeSystem _combatMode = default!; [Dependency] protected readonly SharedContainerSystem Container = default!; + public const int ItemSizeWeightTiny = 1; + public const int ItemSizeWeightSmall = 2; + public const int ItemSizeWeightNormal = 4; + public const int ItemSizeWeightLarge = 8; + public const int ItemSizeWeightHuge = 16; + public const int ItemSizeWeightGinormous = 32; + public override void Initialize() { base.Initialize(); @@ -33,13 +37,13 @@ public abstract class SharedItemSystem : EntitySystem #region Public API - public void SetSize(EntityUid uid, int size, ItemComponent? component = null) + public void SetSize(EntityUid uid, ItemSize size, ItemComponent? component = null) { if (!Resolve(uid, ref component, false)) return; component.Size = size; - Dirty(component); + Dirty(uid, component); } public void SetHeldPrefix(EntityUid uid, string? heldPrefix, ItemComponent? component = null) @@ -51,7 +55,7 @@ public abstract class SharedItemSystem : EntitySystem return; component.HeldPrefix = heldPrefix; - Dirty(component); + Dirty(uid, component); VisualsChanged(uid); } @@ -67,7 +71,7 @@ public abstract class SharedItemSystem : EntitySystem item.InhandVisuals = otherItem.InhandVisuals; item.HeldPrefix = otherItem.HeldPrefix; - Dirty(item); + Dirty(uid, item); VisualsChanged(uid); } @@ -83,14 +87,7 @@ public abstract class SharedItemSystem : EntitySystem protected virtual void OnStackCountChanged(EntityUid uid, ItemComponent component, StackCountChangedEvent args) { - if (!TryComp(uid, out var stack)) - return; - if (!_prototype.TryIndex(stack.StackTypeId, out var stackProto) || - stackProto.ItemSize is not { } size) - return; - - SetSize(uid, args.NewCount * size, component); } private void OnHandleState(EntityUid uid, ItemComponent component, ref ComponentHandleState args) @@ -135,7 +132,7 @@ public abstract class SharedItemSystem : EntitySystem private void OnExamine(EntityUid uid, ItemComponent component, ExaminedEvent args) { args.PushMarkup(Loc.GetString("item-component-on-examine-size", - ("size", component.Size))); + ("size", GetItemSizeLocale(component.Size)))); } /// @@ -148,4 +145,32 @@ public abstract class SharedItemSystem : EntitySystem public virtual void VisualsChanged(EntityUid owner) { } + + [PublicAPI] + public static string GetItemSizeLocale(ItemSize size) + { + return Robust.Shared.Localization.Loc.GetString($"item-component-size-{size.ToString()}"); + } + + [PublicAPI] + public static int GetItemSizeWeight(ItemSize size) + { + switch (size) + { + case ItemSize.Tiny: + return ItemSizeWeightTiny; + case ItemSize.Small: + return ItemSizeWeightSmall; + case ItemSize.Normal: + return ItemSizeWeightNormal; + case ItemSize.Large: + return ItemSizeWeightLarge; + case ItemSize.Huge: + return ItemSizeWeightHuge; + case ItemSize.Ginormous: + return ItemSizeWeightGinormous; + default: + throw new ArgumentOutOfRangeException(nameof(size), size, null); + } + } } diff --git a/Content.Shared/Storage/EntitySystems/MagnetPickupSystem.cs b/Content.Shared/Storage/EntitySystems/MagnetPickupSystem.cs index 16657bdae4..c7505ab3c0 100644 --- a/Content.Shared/Storage/EntitySystems/MagnetPickupSystem.cs +++ b/Content.Shared/Storage/EntitySystems/MagnetPickupSystem.cs @@ -1,10 +1,7 @@ using Content.Server.Storage.Components; -using Content.Shared.Hands; using Content.Shared.Inventory; -using Content.Shared.Stacks; using Robust.Shared.Map; using Robust.Shared.Physics.Components; -using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Shared.Storage.EntitySystems; @@ -56,7 +53,7 @@ public sealed class MagnetPickupSystem : EntitySystem comp.NextScan += ScanDelay; // No space - if (storage.StorageUsed >= storage.StorageCapacityMax) + if (!_storage.HasSpace((uid, storage))) continue; if (!_inventory.TryGetContainingSlot(uid, out var slotDef)) diff --git a/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs b/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs index 5faec99fd5..798d768191 100644 --- a/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs +++ b/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs @@ -4,7 +4,6 @@ using Content.Shared.CombatMode; using Content.Shared.Containers.ItemSlots; using Content.Shared.Destructible; using Content.Shared.DoAfter; -using Content.Shared.Hands; using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.Implants.Components; @@ -46,6 +45,8 @@ public abstract class SharedStorageSystem : EntitySystem private EntityQuery _stackQuery; private EntityQuery _xformQuery; + public const ItemSize DefaultStorageMaxItemSize = ItemSize.Normal; + /// public override void Initialize() { @@ -89,6 +90,7 @@ public abstract class SharedStorageSystem : EntitySystem { // TODO: I had this. // We can get states being applied before the container is ready. + // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract if (component.Container == default) return; @@ -229,7 +231,7 @@ public abstract class SharedStorageSystem : EntitySystem return; } - if (TryComp(uid, out var transformOwner) && TryComp(target, out var transformEnt)) + if (_xformQuery.TryGetComponent(uid, out var transformOwner) && TryComp(target, out var transformEnt)) { var parent = transformOwner.ParentUid; @@ -239,7 +241,7 @@ public abstract class SharedStorageSystem : EntitySystem _transform ); - if (PlayerInsertEntityInWorld(uid, args.User, target, storageComp)) + if (PlayerInsertEntityInWorld((uid, storageComp), args.User, target)) { RaiseNetworkEvent(new AnimateInsertingEntitiesEvent(GetNetEntity(uid), new List { GetNetEntity(target) }, @@ -285,7 +287,7 @@ public abstract class SharedStorageSystem : EntitySystem var angle = targetXform.LocalRotation; - if (PlayerInsertEntityInWorld(uid, args.Args.User, entity, component)) + if (PlayerInsertEntityInWorld((uid, component), args.Args.User, entity)) { successfullyInserted.Add(entity); successfullyInsertedPositions.Add(position); @@ -322,7 +324,7 @@ public abstract class SharedStorageSystem : EntitySystem /// private void OnInteractWithItem(EntityUid uid, StorageComponent storageComp, StorageInteractWithItemEvent args) { - if (args.Session.AttachedEntity is not EntityUid player) + if (args.Session.AttachedEntity is not { } player) return; var entity = GetEntity(args.InteractedItemUID); @@ -396,27 +398,10 @@ public abstract class SharedStorageSystem : EntitySystem public void RecalculateStorageUsed(EntityUid uid, StorageComponent storageComp) { - storageComp.StorageUsed = 0; - - foreach (var entity in storageComp.Container.ContainedEntities) - { - if (!_itemQuery.TryGetComponent(entity, out var itemComp)) - continue; - - var size = itemComp.Size; - storageComp.StorageUsed += size; - } - - _appearance.SetData(uid, StorageVisuals.StorageUsed, storageComp.StorageUsed); - _appearance.SetData(uid, StorageVisuals.Capacity, storageComp.StorageCapacityMax); - } - - public int GetAvailableSpace(EntityUid uid, StorageComponent? component = null) - { - if (!Resolve(uid, ref component)) - return 0; - - return component.StorageCapacityMax - component.StorageUsed; + // it might make more sense to use the weights instead of the slots. + // I'm not sure. + _appearance.SetData(uid, StorageVisuals.StorageUsed, storageComp.Container.ContainedEntities.Count); + _appearance.SetData(uid, StorageVisuals.Capacity, storageComp.MaxSlots); } /// @@ -449,17 +434,20 @@ public abstract class SharedStorageSystem : EntitySystem /// Verifies if an entity can be stored and if it fits /// /// The entity to check + /// /// If returning false, the reason displayed to the player + /// + /// /// true if it can be inserted, false otherwise - public bool CanInsert(EntityUid uid, EntityUid insertEnt, out string? reason, StorageComponent? storageComp = null) + public bool CanInsert(EntityUid uid, EntityUid insertEnt, out string? reason, StorageComponent? storageComp = null, ItemComponent? item = null) { - if (!Resolve(uid, ref storageComp)) + if (!Resolve(uid, ref storageComp) || !Resolve(insertEnt, ref item)) { reason = null; return false; } - if (TryComp(insertEnt, out TransformComponent? transformComp) && transformComp.Anchored) + if (Transform(insertEnt).Anchored) { reason = "comp-storage-anchored-failure"; return false; @@ -477,15 +465,19 @@ public abstract class SharedStorageSystem : EntitySystem return false; } - if (TryComp(insertEnt, out StorageComponent? storage) && - storage.StorageCapacityMax >= storageComp.StorageCapacityMax) + if (item.Size > GetMaxItemSize((uid, storageComp))) + { + reason = "comp-storage-too-big"; + return false; + } + + if (storageComp.Container.ContainedEntities.Count >= storageComp.MaxSlots) { reason = "comp-storage-insufficient-capacity"; return false; } - if (TryComp(insertEnt, out ItemComponent? itemComp) && - itemComp.Size > storageComp.StorageCapacityMax - storageComp.StorageUsed) + if (SharedItemSystem.GetItemSizeWeight(item.Size) + GetCumulativeItemSizes(uid, storageComp) > GetMaxTotalWeight((uid, storageComp))) { reason = "comp-storage-insufficient-capacity"; return false; @@ -542,8 +534,7 @@ public abstract class SharedStorageSystem : EntitySystem if (insertStack.Count > 0) { // Try to insert it as a new stack. - if (TryComp(insertEnt, out ItemComponent? itemComp) && - itemComp.Size > storageComp.StorageCapacityMax - storageComp.StorageUsed || + if (!CanInsert(uid, insertEnt, out _, storageComp) || !storageComp.Container.Insert(insertEnt)) { // If we also didn't do any stack fills above then just end @@ -568,7 +559,9 @@ public abstract class SharedStorageSystem : EntitySystem /// /// Inserts an entity into storage from the player's active hand /// + /// /// The player to insert an entity from + /// /// true if inserted, false otherwise public bool PlayerInsertHeldEntity(EntityUid uid, EntityUid player, StorageComponent? storageComp = null) { @@ -589,21 +582,23 @@ public abstract class SharedStorageSystem : EntitySystem return false; } - return PlayerInsertEntityInWorld(uid, player, toInsert.Value, storageComp); + return PlayerInsertEntityInWorld((uid, storageComp), player, toInsert.Value); } /// /// Inserts an Entity () in the world into storage, informing if it fails. - /// is *NOT* held, see . + /// is *NOT* held, see . /// + /// /// The player to insert an entity with + /// /// true if inserted, false otherwise - public bool PlayerInsertEntityInWorld(EntityUid uid, EntityUid player, EntityUid toInsert, StorageComponent? storageComp = null) + public bool PlayerInsertEntityInWorld(Entity uid, EntityUid player, EntityUid toInsert) { - if (!Resolve(uid, ref storageComp) || !_sharedInteractionSystem.InRangeUnobstructed(player, uid)) + if (!Resolve(uid, ref uid.Comp) || !_sharedInteractionSystem.InRangeUnobstructed(player, uid)) return false; - if (!Insert(uid, toInsert, out _, user: player, storageComp)) + if (!Insert(uid, toInsert, out _, user: player, uid.Comp)) { _popupSystem.PopupClient(Loc.GetString("comp-storage-cant-insert"), uid, player); return false; @@ -611,6 +606,65 @@ public abstract class SharedStorageSystem : EntitySystem return true; } + /// + /// Returns true if there is enough space to theoretically fit another item. + /// + public bool HasSpace(Entity uid) + { + if (!Resolve(uid, ref uid.Comp)) + return false; + + return uid.Comp.Container.ContainedEntities.Count < uid.Comp.MaxSlots && + GetCumulativeItemSizes(uid, uid.Comp) < GetMaxTotalWeight(uid); + } + + /// + /// Returns the sum of all the ItemSizes of the items inside of a storage. + /// + public int GetCumulativeItemSizes(EntityUid uid, StorageComponent? component = null) + { + if (!Resolve(uid, ref component)) + return 0; + + var sum = 0; + foreach (var item in component.Container.ContainedEntities) + { + if (!_itemQuery.TryGetComponent(item, out var itemComp)) + continue; + sum += SharedItemSystem.GetItemSizeWeight(itemComp.Size); + } + + return sum; + } + + public ItemSize GetMaxItemSize(Entity uid) + { + if (!Resolve(uid, ref uid.Comp)) + return DefaultStorageMaxItemSize; + + // If we specify a max item size, use that + if (uid.Comp.MaxItemSize != null) + return uid.Comp.MaxItemSize.Value; + + if (!_itemQuery.TryGetComponent(uid, out var item)) + return DefaultStorageMaxItemSize; + + // if there is no max item size specified, the value used + // is one below the item size of the storage entity, clamped at ItemSize.Tiny + return (ItemSize) Math.Max((int) item.Size - 1, 1); + } + + public int GetMaxTotalWeight(Entity uid) + { + if (!Resolve(uid, ref uid.Comp)) + return 0; + + if (uid.Comp.MaxTotalWeight != null) + return uid.Comp.MaxTotalWeight.Value; + + return uid.Comp.MaxSlots * SharedItemSystem.GetItemSizeWeight(GetMaxItemSize(uid)); + } + /// /// Plays a clientside pickup animation for the specified uid. /// diff --git a/Content.Shared/Storage/StorageComponent.cs b/Content.Shared/Storage/StorageComponent.cs index fdcf06bf5d..f05db44081 100644 --- a/Content.Shared/Storage/StorageComponent.cs +++ b/Content.Shared/Storage/StorageComponent.cs @@ -1,3 +1,5 @@ +using Content.Shared.Item; +using Content.Shared.Storage.EntitySystems; using Content.Shared.Whitelist; using Robust.Shared.Audio; using Robust.Shared.Containers; @@ -20,6 +22,25 @@ namespace Content.Shared.Storage [ViewVariables] public Container Container = default!; + /// + /// The max number of entities that can be inserted into this storage. + /// + [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public int MaxSlots = 7; + + /// + /// The maximum size item that can be inserted into this storage, + /// + [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + [Access(typeof(SharedStorageSystem))] + public ItemSize? MaxItemSize; + + /// + /// A limit for the cumulative ItemSizes that can be inserted in this storage. + /// + [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public int? MaxTotalWeight; + // TODO: Make area insert its own component. [DataField("quickInsert")] public bool QuickInsert; // Can insert storables by "attacking" them with the storage entity @@ -45,18 +66,6 @@ namespace Content.Shared.Storage [DataField("blacklist")] public EntityWhitelist? Blacklist; - /// - /// How much storage is currently being used by contained entities. - /// - [ViewVariables, DataField("storageUsed"), AutoNetworkedField] - public int StorageUsed; - - /// - /// Maximum capacity for storage. - /// - [DataField("capacity"), AutoNetworkedField] - public int StorageCapacityMax = 10000; - /// /// Sound played whenever an entity is inserted into storage. /// diff --git a/Resources/Locale/en-US/components/storage-component.ftl b/Resources/Locale/en-US/components/storage-component.ftl index a6d542e4fb..cea37cd961 100644 --- a/Resources/Locale/en-US/components/storage-component.ftl +++ b/Resources/Locale/en-US/components/storage-component.ftl @@ -1,9 +1,10 @@ comp-storage-no-item-size = N/A comp-storage-cant-insert = Can't insert. -comp-storage-insufficient-capacity = Insufficient capacity. +comp-storage-too-big = Too big! +comp-storage-insufficient-capacity = No room! comp-storage-invalid-container = This doesn't go in there! comp-storage-anchored-failure = Can't insert an anchored item. comp-storage-cant-drop = You can't let go of { THE($entity) }! comp-storage-window-title = Storage Item -comp-storage-window-volume = Items: { $itemCount }, Stored: { $usedVolume }/{ $maxVolume } -comp-storage-window-volume-unlimited = Items: { $itemCount } +comp-storage-window-volume = Items: { $itemCount }/{ $maxCount }, Max Size: {$size} +comp-storage-window-volume-full = [color=orange][bold]FULL[/bold][/color], Max Size: {$size} diff --git a/Resources/Locale/en-US/items/components/item-component.ftl b/Resources/Locale/en-US/items/components/item-component.ftl index f9750a55fa..54354ef1ee 100644 --- a/Resources/Locale/en-US/items/components/item-component.ftl +++ b/Resources/Locale/en-US/items/components/item-component.ftl @@ -7,3 +7,10 @@ pick-up-verb-get-data-text = Pick Up pick-up-verb-get-data-text-inventory = Put in hand item-component-on-examine-size = Size: {$size} + +item-component-size-Tiny = tiny +item-component-size-Small = small +item-component-size-Normal = normal +item-component-size-Large = large +item-component-size-Huge = huge +item-component-size-Ginormous = bulky diff --git a/Resources/Maps/Shuttles/striker.yml b/Resources/Maps/Shuttles/striker.yml index 1b71e29725..2601c78160 100644 --- a/Resources/Maps/Shuttles/striker.yml +++ b/Resources/Maps/Shuttles/striker.yml @@ -874,36 +874,6 @@ entities: pos: -0.5,0.5 parent: 325 type: Transform -- proto: ClothingBeltSyndieHolster - entities: - - uid: 317 - components: - - flags: InContainer - type: MetaData - - parent: 177 - type: Transform - - canCollide: False - type: Physics -- proto: ClothingHandsGlovesCombat - entities: - - uid: 316 - components: - - flags: InContainer - type: MetaData - - parent: 177 - type: Transform - - canCollide: False - type: Physics -- proto: ClothingMaskGasSyndicate - entities: - - uid: 318 - components: - - flags: InContainer - type: MetaData - - parent: 177 - type: Transform - - canCollide: False - type: Physics - proto: ComputerIFFSyndicate entities: - uid: 40 @@ -926,16 +896,6 @@ entities: ents: - 245 type: ContainerContainer -- proto: Crowbar - entities: - - uid: 313 - components: - - flags: InContainer - type: MetaData - - parent: 177 - type: Transform - - canCollide: False - type: Physics - proto: CyberPen entities: - uid: 77 @@ -1672,16 +1632,6 @@ entities: pos: -2.5,-3.5 parent: 325 type: Transform -- proto: Multitool - entities: - - uid: 314 - components: - - flags: InContainer - type: MetaData - - parent: 177 - type: Transform - - canCollide: False - type: Physics - proto: NitrogenTankFilled entities: - uid: 105 @@ -1880,20 +1830,6 @@ entities: type: Transform - canCollide: False type: Physics -- proto: Screwdriver - entities: - - uid: 310 - components: - - flags: InContainer - type: MetaData - - parent: 177 - type: Transform - - selected: - enum.DamageStateVisualLayers.Base: - screwdriver: '#1861D5FF' - type: RandomSprite - - canCollide: False - type: Physics - proto: SheetGlass1 entities: - uid: 244 @@ -2382,21 +2318,6 @@ entities: - pos: 1.5699697,-0.44908836 parent: 325 type: Transform - - containers: - storagebase: !type:Container - showEnts: False - occludes: True - ents: - - 310 - - 311 - - 312 - - 313 - - 314 - - 315 - - 316 - - 317 - - 318 - type: ContainerContainer - canCollide: False type: Physics - proto: ToyFigurineNukie @@ -2656,16 +2577,6 @@ entities: - pos: -2.5,2.5 parent: 325 type: Transform -- proto: Welder - entities: - - uid: 312 - components: - - flags: InContainer - type: MetaData - - parent: 177 - type: Transform - - canCollide: False - type: Physics - proto: WindoorSecure entities: - uid: 166 @@ -2687,30 +2598,6 @@ entities: ents: - 346 type: ContainerContainer -- proto: Wirecutter - entities: - - uid: 315 - components: - - flags: InContainer - type: MetaData - - parent: 177 - type: Transform - - selected: - enum.DamageStateVisualLayers.Base: - cutters: '#D58C18FF' - type: RandomSprite - - canCollide: False - type: Physics -- proto: Wrench - entities: - - uid: 311 - components: - - flags: InContainer - type: MetaData - - parent: 177 - type: Transform - - canCollide: False - type: Physics - proto: YellowOxygenTankFilled entities: - uid: 167 diff --git a/Resources/Maps/core.yml b/Resources/Maps/core.yml index 328400cd0b..d31189c43b 100644 --- a/Resources/Maps/core.yml +++ b/Resources/Maps/core.yml @@ -102471,8 +102471,6 @@ entities: type: Transform - count: 15 type: Stack - - size: 15 - type: Item - proto: SheetPlasma entities: - uid: 12944 @@ -102564,8 +102562,6 @@ entities: type: Transform - count: 20 type: Stack - - size: 20 - type: Item - proto: Shovel entities: - uid: 12955 diff --git a/Resources/Maps/europa.yml b/Resources/Maps/europa.yml index ddba1100f2..98a2c5807d 100644 --- a/Resources/Maps/europa.yml +++ b/Resources/Maps/europa.yml @@ -78331,8 +78331,6 @@ entities: type: Transform - count: 15 type: Stack - - size: 30 - type: Item - proto: StoolBar entities: - uid: 921 diff --git a/Resources/Prototypes/Catalog/Fills/Backpacks/StarterGear/backpack.yml b/Resources/Prototypes/Catalog/Fills/Backpacks/StarterGear/backpack.yml index 1e0788cccd..5eeec04af2 100644 --- a/Resources/Prototypes/Catalog/Fills/Backpacks/StarterGear/backpack.yml +++ b/Resources/Prototypes/Catalog/Fills/Backpacks/StarterGear/backpack.yml @@ -28,7 +28,7 @@ - id: BoxSurvivalSecurity - id: Flash - id: MagazinePistol - + - type: entity noSpawn: true parent: ClothingBackpackSecurity @@ -291,8 +291,7 @@ - id: RegenerativeMesh - id: RCD - id: RCDAmmo - - id: RCDAmmo - - id: RCDAmmo + amount: 2 - id: CableMVStack - id: CableHVStack diff --git a/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml b/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml index 12f31bc016..375e831f3c 100644 --- a/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml +++ b/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml @@ -198,6 +198,9 @@ name: syndicate pyjama duffel bag description: Contains 3 pairs of syndicate pyjamas and 3 plushies for the ultimate sleepover. components: + - type: Storage + maxSlots: 16 + maxTotalWeight: 44 - type: StorageFill contents: - id: ClothingUniformJumpsuitPyjamaSyndicateRed @@ -231,6 +234,8 @@ id: ClothingBackpackChameleonFill suffix: Fill, Chameleon components: + - type: Storage + maxSlots: 9 - type: StorageFill contents: - id: ClothingUniformJumpsuitChameleon diff --git a/Resources/Prototypes/Catalog/Fills/Boxes/ammunition.yml b/Resources/Prototypes/Catalog/Fills/Boxes/ammunition.yml index 20e291494f..7fc62984a0 100644 --- a/Resources/Prototypes/Catalog/Fills/Boxes/ammunition.yml +++ b/Resources/Prototypes/Catalog/Fills/Boxes/ammunition.yml @@ -278,7 +278,7 @@ containers: ballistic-ammo: !type:Container - type: Item - size: 30 + size: Normal - type: Sprite sprite: Objects/Storage/boxes.rsi diff --git a/Resources/Prototypes/Catalog/Fills/Boxes/general.yml b/Resources/Prototypes/Catalog/Fills/Boxes/general.yml index d05dfbb4ed..e2ca59a7d2 100644 --- a/Resources/Prototypes/Catalog/Fills/Boxes/general.yml +++ b/Resources/Prototypes/Catalog/Fills/Boxes/general.yml @@ -37,7 +37,8 @@ - state: box - state: light - type: Storage - capacity: 60 + maxSlots: 12 + maxTotalWeight: 24 whitelist: components: - LightBulb @@ -60,7 +61,8 @@ - state: box - state: lighttube - type: Storage - capacity: 60 + maxSlots: 12 + maxTotalWeight: 24 whitelist: components: - LightBulb @@ -85,7 +87,8 @@ - state: box - state: lightmixed - type: Storage - capacity: 60 + maxSlots: 12 + maxTotalWeight: 24 whitelist: components: - LightBulb @@ -108,7 +111,6 @@ - state: box - state: pda - type: Storage - capacity: 60 whitelist: components: - Pda @@ -128,7 +130,6 @@ - state: box - state: pda - type: Storage - capacity: 60 whitelist: components: - IdCard @@ -148,7 +149,6 @@ - state: box - state: headset - type: Storage - capacity: 60 whitelist: components: - Headset @@ -192,7 +192,6 @@ description: A special box for sensitive people. components: - type: Storage - capacity: 30 - type: Sprite layers: - state: box_hug @@ -234,6 +233,12 @@ id: BoxPerformer description: Happy Hatsune Miku Day! components: + - type: Storage + maxItemSize: Normal + whitelist: + components: + - Clothing + - Food - type: StorageFill contents: - id: ClothingShoesBootsPerformer @@ -267,7 +272,7 @@ - id: TrashBag amount: 6 - type: Storage - capacity: 800 + maxItemSize: Normal whitelist: tags: - TrashBag @@ -294,7 +299,6 @@ - state: box - state: encryptokey - type: Storage - capacity: 30 whitelist: components: - EncryptionKey @@ -386,13 +390,12 @@ description: Two syndicate encryption keys for the price of one. Miniaturized for ease of use. components: - type: Item - size: 15 + size: Normal - type: StorageFill contents: - id: EncryptionKeySyndie amount: 2 - type: Storage - capacity: 15 - type: entity name: deathrattle implant box @@ -401,7 +404,7 @@ description: Six deathrattle implants and handheld GPS devices for the whole squad. components: - type: Item - size: 60 + size: Normal - type: StorageFill contents: - id: DeathRattleImplanter @@ -409,7 +412,8 @@ - id: HandheldGPSBasic amount: 6 - type: Storage - capacity: 60 + maxSlots: 12 + maxTotalWeight: 24 - type: Sprite layers: - state: box @@ -434,20 +438,21 @@ description: This box filled with colorful darts. components: - type: Item - size: 40 + size: Normal - type: StorageFill contents: - id: Dart - amount: 5 + amount: 3 - id: DartBlue - amount: 5 + amount: 3 - id: DartPurple - amount: 5 + amount: 3 - id: DartYellow - amount: 5 + amount: 3 - type: Storage - capacity: 40 + maxSlots: 12 + maxTotalWeight: 24 - type: Sprite layers: - state: box - - state: darts \ No newline at end of file + - state: darts diff --git a/Resources/Prototypes/Catalog/Fills/Boxes/medical.yml b/Resources/Prototypes/Catalog/Fills/Boxes/medical.yml index 41ee064ce0..9a7f4b47e0 100644 --- a/Resources/Prototypes/Catalog/Fills/Boxes/medical.yml +++ b/Resources/Prototypes/Catalog/Fills/Boxes/medical.yml @@ -93,10 +93,13 @@ parent: BoxCardboard id: BoxMouthSwab components: + - type: Storage + maxSlots: 10 + maxTotalWeight: 20 - type: StorageFill contents: - id: DiseaseSwab - amount: 30 + amount: 10 - type: Sprite layers: - state: box diff --git a/Resources/Prototypes/Catalog/Fills/Boxes/security.yml b/Resources/Prototypes/Catalog/Fills/Boxes/security.yml index 027aaf19f6..51dc512f91 100644 --- a/Resources/Prototypes/Catalog/Fills/Boxes/security.yml +++ b/Resources/Prototypes/Catalog/Fills/Boxes/security.yml @@ -49,6 +49,12 @@ id: BoxZiptie description: A box full of zipties. components: + - type: Storage + maxSlots: 10 + maxTotalWeight: 20 + whitelist: + components: + - Handcuff - type: StorageFill contents: - id: Zipties @@ -64,6 +70,9 @@ id: BoxForensicPad description: A box of forensic pads. components: + - type: Storage + maxSlots: 10 + maxTotalWeight: 20 - type: StorageFill contents: - id: ForensicPad diff --git a/Resources/Prototypes/Catalog/Fills/Crates/fun.yml b/Resources/Prototypes/Catalog/Fills/Crates/fun.yml index 48877fd889..1526cf0f63 100644 --- a/Resources/Prototypes/Catalog/Fills/Crates/fun.yml +++ b/Resources/Prototypes/Catalog/Fills/Crates/fun.yml @@ -302,8 +302,8 @@ - id: TargetDarts amount: 1 - id: BoxDarts - amount: 1 + amount: 2 - id: BoxDarts amount: 1 prob: 0.05 - + diff --git a/Resources/Prototypes/Catalog/Fills/Items/belt.yml b/Resources/Prototypes/Catalog/Fills/Items/belt.yml index 1886b961c8..baad216f47 100644 --- a/Resources/Prototypes/Catalog/Fills/Items/belt.yml +++ b/Resources/Prototypes/Catalog/Fills/Items/belt.yml @@ -89,14 +89,11 @@ - type: StorageFill contents: - id: Brutepack - amount: 1 - id: Ointment - amount: 1 - id: Bloodpack - amount: 1 - id: Gauze - id: EmergencyMedipen #You never know what people are going to latejoin into - amount: 6 + amount: 3 - type: entity id: ClothingBeltPlantFilled @@ -124,6 +121,10 @@ name: grenadier chest rig suffix: Filled components: + - type: Item + size: Large + - type: Storage + maxSlots: 8 - type: StorageFill contents: - id: ExGrenade @@ -169,4 +170,4 @@ contents: - id: WeaponRevolverInspector - id: SpeedLoaderMagnum - - id: SpeedLoaderMagnumRubber \ No newline at end of file + - id: SpeedLoaderMagnumRubber diff --git a/Resources/Prototypes/Catalog/Fills/Items/briefcases.yml b/Resources/Prototypes/Catalog/Fills/Items/briefcases.yml index c487909a4b..714148a64d 100644 --- a/Resources/Prototypes/Catalog/Fills/Items/briefcases.yml +++ b/Resources/Prototypes/Catalog/Fills/Items/briefcases.yml @@ -15,6 +15,10 @@ parent: BriefcaseSyndie suffix: SniperBundle components: + - type: Item + size: Huge + - type: Storage + maxItemSize: Large - type: StorageFill contents: - id: WeaponSniperHristov diff --git a/Resources/Prototypes/Catalog/Fills/Items/firstaidkits.yml b/Resources/Prototypes/Catalog/Fills/Items/firstaidkits.yml index 8cc7d6b6d4..832d357d83 100644 --- a/Resources/Prototypes/Catalog/Fills/Items/firstaidkits.yml +++ b/Resources/Prototypes/Catalog/Fills/Items/firstaidkits.yml @@ -12,8 +12,7 @@ - id: Ointment amount: 2 - id: Gauze - - id: PillTricordrazine - amount: 5 + - id: PillCanisterTricordrazine # see https://github.com/tgstation/blob/master/code/game/objects/items/storage/firstaid.dm for example contents - type: entity @@ -28,10 +27,8 @@ - id: Ointment amount: 2 - id: SyringeSigynate - - id: PillKelotane - amount: 5 - - id: PillDermaline - amount: 5 + - id: PillCanisterKelotane + - id: PillCanisterDermaline - type: entity id: MedkitBruteFilled @@ -45,10 +42,8 @@ - id: Gauze - id: Bloodpack - id: SyringeTranexamicAcid - - id: PillIron - amount: 5 - - id: PillBicaridine - amount: 5 + - id: PillCanisterIron + - id: PillCanisterBicaridine - type: entity id: MedkitToxinFilled @@ -60,10 +55,8 @@ - id: SyringeIpecac - id: SyringeEthylredoxrazine - id: AntiPoisonMedipen - - id: PillDylovene - amount: 5 - - id: PillCharcoal - amount: 3 + - id: PillCanisterDylovene + - id: PillCanisterCharcoal - type: entity id: MedkitOxygenFilled @@ -76,8 +69,7 @@ - id: EmergencyOxygenTankFilled - id: EmergencyMedipen - id: SyringeInaprovaline - - id: PillDexalin - amount: 7 + - id: PillCanisterDexalin - type: entity id: MedkitRadiationFilled @@ -92,8 +84,7 @@ amount: 1 - id: EmergencyMedipen amount: 1 - - id: PillHyronalin - amount: 5 + - id: PillCanisterHyronalin - type: entity id: MedkitAdvancedFilled @@ -120,11 +111,9 @@ - id: MedicatedSuture - id: RegenerativeMesh - id: SyringeEphedrine - - id: SyringeSaline - id: BruteAutoInjector - id: BurnAutoInjector - id: EmergencyMedipen - - id: Bloodpack - type: entity id: StimkitFilled diff --git a/Resources/Prototypes/Entities/Clothing/Back/backpacks.yml b/Resources/Prototypes/Entities/Clothing/Back/backpacks.yml index 7277ebb10a..5edce6be02 100644 --- a/Resources/Prototypes/Entities/Clothing/Back/backpacks.yml +++ b/Resources/Prototypes/Entities/Clothing/Back/backpacks.yml @@ -8,13 +8,14 @@ sprite: Clothing/Back/Backpacks/backpack.rsi state: icon - type: Item - size: 9999 + size: Huge - type: Clothing quickEquip: false slots: - back - type: Storage - capacity: 100 + maxSlots: 7 + maxTotalWeight: 28 - type: ContainerContainer containers: storagebase: !type:Container @@ -196,7 +197,8 @@ - type: Sprite sprite: Clothing/Back/Backpacks/ertleader.rsi - type: Storage - capacity: 250 + maxSlots: 10 + maxTotalWeight: 40 - type: entity parent: ClothingBackpackERTLeader @@ -259,8 +261,12 @@ shader: unshaded - type: Clothing equippedPrefix: holding + - type: Item + size: Ginormous - type: Storage - capacity: 9999 + maxSlots: 14 + maxItemSize: Large + maxTotalWeight: 56 #14 normal-sized items. - type: entity parent: ClothingBackpackClown diff --git a/Resources/Prototypes/Entities/Clothing/Back/duffel.yml b/Resources/Prototypes/Entities/Clothing/Back/duffel.yml index b9cc9ca266..1fb4b67824 100644 --- a/Resources/Prototypes/Entities/Clothing/Back/duffel.yml +++ b/Resources/Prototypes/Entities/Clothing/Back/duffel.yml @@ -7,7 +7,8 @@ - type: Sprite sprite: Clothing/Back/Duffels/duffel.rsi - type: Storage - capacity: 120 + maxSlots: 10 + maxTotalWeight: 40 - type: ClothingSpeedModifier walkModifier: 1 sprintModifier: 0.9 @@ -162,8 +163,6 @@ components: - type: Sprite sprite: Clothing/Back/Duffels/syndicate.rsi - - type: Storage - capacity: 131 - type: entity parent: ClothingBackpackDuffelSyndicate @@ -228,7 +227,11 @@ - state: icon - state: icon-unlit shader: unshaded + - type: Item + size: Ginormous - type: Storage - capacity: 9999 + maxSlots: 14 + maxItemSize: Large + maxTotalWeight: 56 #14 normal-sized items. - type: ClothingSpeedModifier sprintModifier: 1 # makes its stats identical to other variants of bag of holding diff --git a/Resources/Prototypes/Entities/Clothing/Back/satchel.yml b/Resources/Prototypes/Entities/Clothing/Back/satchel.yml index e80b0d6f8b..b3b36b70fb 100644 --- a/Resources/Prototypes/Entities/Clothing/Back/satchel.yml +++ b/Resources/Prototypes/Entities/Clothing/Back/satchel.yml @@ -167,5 +167,9 @@ - state: icon - state: icon-unlit shader: unshaded + - type: Item + size: Ginormous - type: Storage - capacity: 9999 + maxSlots: 14 + maxItemSize: Large + maxTotalWeight: 56 #14 normal-sized items. diff --git a/Resources/Prototypes/Entities/Clothing/Back/specific.yml b/Resources/Prototypes/Entities/Clothing/Back/specific.yml index 5964007356..c36ddde03b 100644 --- a/Resources/Prototypes/Entities/Clothing/Back/specific.yml +++ b/Resources/Prototypes/Entities/Clothing/Back/specific.yml @@ -33,7 +33,7 @@ sprite: Clothing/Back/Backpacks/waterbackpack.rsi state: icon - type: Item - size: 200 + size: Huge - type: Clothing slots: BACK sprite: Clothing/Back/Backpacks/waterbackpack.rsi diff --git a/Resources/Prototypes/Entities/Clothing/Belt/base_clothingbelt.yml b/Resources/Prototypes/Entities/Clothing/Belt/base_clothingbelt.yml index b37d3fd974..1f9f266eb4 100644 --- a/Resources/Prototypes/Entities/Clothing/Belt/base_clothingbelt.yml +++ b/Resources/Prototypes/Entities/Clothing/Belt/base_clothingbelt.yml @@ -6,7 +6,7 @@ - type: Sprite state: icon - type: Item - size: 50 + size: Normal - type: Clothing slots: [belt] quickEquip: false @@ -22,7 +22,10 @@ id: ClothingBeltStorageBase components: - type: Storage - capacity: 40 + maxSlots: 7 + maxItemSize: Normal + - type: Item + size: Large - type: ContainerContainer containers: storagebase: !type:Container diff --git a/Resources/Prototypes/Entities/Clothing/Belt/belts.yml b/Resources/Prototypes/Entities/Clothing/Belt/belts.yml index fa1a5e951f..28f8ed0dca 100644 --- a/Resources/Prototypes/Entities/Clothing/Belt/belts.yml +++ b/Resources/Prototypes/Entities/Clothing/Belt/belts.yml @@ -11,7 +11,7 @@ - type: Clothing sprite: Clothing/Belt/utility.rsi - type: Storage - capacity: 45 + maxItemSize: Normal # TODO: Fill this out more. whitelist: tags: @@ -83,7 +83,6 @@ - type: Clothing sprite: Clothing/Belt/ce.rsi - type: Storage - capacity: 105 # TODO: Fill this out more. whitelist: tags: @@ -238,7 +237,6 @@ - type: Clothing sprite: Clothing/Belt/medical.rsi - type: Storage - capacity: 60 whitelist: tags: - Wrench @@ -393,7 +391,7 @@ - type: Clothing sprite: Clothing/Belt/sheath.rsi - type: Storage - capacity: 15 + maxSlots: 1 whitelist: tags: - CaptainSabre @@ -418,9 +416,8 @@ - type: Clothing sprite: Clothing/Belt/bandolier.rsi - type: Item - size: 60 + size: Large - type: Storage - capacity: 60 whitelist: tags: - ShellShotgun @@ -451,7 +448,7 @@ - type: Clothing sprite: Clothing/Belt/holster.rsi - type: Storage - capacity: 20 + maxSlots: 3 - type: entity parent: ClothingBeltStorageBase @@ -464,9 +461,8 @@ - type: Clothing sprite: Clothing/Belt/syndieholster.rsi - type: Item - size: 60 + size: Large - type: Storage - capacity: 60 whitelist: components: - Gun @@ -528,9 +524,7 @@ - type: Clothing sprite: Clothing/Belt/militarywebbingmed.rsi - type: Item - size: 70 - - type: Storage - capacity: 70 + size: Large - type: entity parent: ClothingBeltBase @@ -559,7 +553,7 @@ - type: Clothing sprite: Clothing/Belt/wand.rsi - type: Storage - capacity: 120 + maxSlots: 8 whitelist: tags: - WizardWand diff --git a/Resources/Prototypes/Entities/Clothing/Belt/quiver.yml b/Resources/Prototypes/Entities/Clothing/Belt/quiver.yml index 10332e46aa..e6685eb47a 100644 --- a/Resources/Prototypes/Entities/Clothing/Belt/quiver.yml +++ b/Resources/Prototypes/Entities/Clothing/Belt/quiver.yml @@ -12,7 +12,8 @@ visible: false - type: Clothing - type: Storage - capacity: 150 + maxSlots: 15 + maxItemSize: Small whitelist: tags: - Arrow diff --git a/Resources/Prototypes/Entities/Clothing/Belt/waist_bags.yml b/Resources/Prototypes/Entities/Clothing/Belt/waist_bags.yml index 6d47010efc..e142376d07 100644 --- a/Resources/Prototypes/Entities/Clothing/Belt/waist_bags.yml +++ b/Resources/Prototypes/Entities/Clothing/Belt/waist_bags.yml @@ -9,8 +9,9 @@ - type: Clothing sprite: Clothing/Belt/waistbag_leather.rsi - type: Storage - capacity: 20 - + maxSlots: 5 + maxItemSize: Small + #Colorization on worn items doesn't work. If this ever gets fixed, you can duplicate this entry and change the color on the sprite to add color variants. #- type: entity # parent: ClothingBeltStorageWaistbag @@ -29,4 +30,4 @@ # layers: # - state: "equipped-BELT" # color: "#bf1313" -# - state: "equipped-trinkets" \ No newline at end of file +# - state: "equipped-trinkets" diff --git a/Resources/Prototypes/Entities/Clothing/Ears/headsets.yml b/Resources/Prototypes/Entities/Clothing/Ears/headsets.yml index cae6a0ea17..858ec6f0db 100644 --- a/Resources/Prototypes/Entities/Clothing/Ears/headsets.yml +++ b/Resources/Prototypes/Entities/Clothing/Ears/headsets.yml @@ -17,6 +17,8 @@ keySlots: 4 - type: Sprite state: icon + - type: Item + size: Small - type: Clothing slots: - ears diff --git a/Resources/Prototypes/Entities/Clothing/Eyes/base_clothingeyes.yml b/Resources/Prototypes/Entities/Clothing/Eyes/base_clothingeyes.yml index dc37811fb8..a0c41120b8 100644 --- a/Resources/Prototypes/Entities/Clothing/Eyes/base_clothingeyes.yml +++ b/Resources/Prototypes/Entities/Clothing/Eyes/base_clothingeyes.yml @@ -7,3 +7,5 @@ state: icon - type: Clothing slots: [eyes] + - type: Item + size: Small diff --git a/Resources/Prototypes/Entities/Clothing/Hands/base_clothinghands.yml b/Resources/Prototypes/Entities/Clothing/Hands/base_clothinghands.yml index e7d8bec69f..5cf7fd645b 100644 --- a/Resources/Prototypes/Entities/Clothing/Hands/base_clothinghands.yml +++ b/Resources/Prototypes/Entities/Clothing/Hands/base_clothinghands.yml @@ -9,6 +9,8 @@ slots: [gloves] - type: Food requiresSpecialDigestion: true + - type: Item + size: Small - type: SolutionContainerManager solutions: food: diff --git a/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml b/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml index 19fc25b233..dd67096b08 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml @@ -8,6 +8,8 @@ - HEAD - type: Sprite state: icon + - type: Item + size: Small - type: Food requiresSpecialDigestion: true - type: SolutionContainerManager @@ -117,7 +119,7 @@ name: base space helmet components: - type: Item - size: 10 + size: Small - type: PressureProtection highPressureMultiplier: 0.6 lowPressureMultiplier: 1000 @@ -241,4 +243,4 @@ - type: GroupExamine - type: Tag tags: - - HidesHair \ No newline at end of file + - HidesHair diff --git a/Resources/Prototypes/Entities/Clothing/Head/hats.yml b/Resources/Prototypes/Entities/Clothing/Head/hats.yml index d5d13fbdd0..731513d31e 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/hats.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/hats.yml @@ -197,7 +197,7 @@ - type: Clothing sprite: Clothing/Head/Hats/chefhat.rsi - type: Storage - capacity: 5 + maxSlots: 1 - type: UserInterface interfaces: - key: enum.StorageUiKey.Key @@ -751,10 +751,10 @@ offset: "0, 0.12" sprite: Clothing/Head/Hats/magician.rsi - type: Item - size: 10 + size: Small sprite: Clothing/Head/Hats/magician.rsi - type: Storage - capacity: 10 + maxSlots: 1 - type: UserInterface interfaces: - key: enum.StorageUiKey.Key diff --git a/Resources/Prototypes/Entities/Clothing/Masks/base_clothingmask.yml b/Resources/Prototypes/Entities/Clothing/Masks/base_clothingmask.yml index b79d76aa17..d57065ba79 100644 --- a/Resources/Prototypes/Entities/Clothing/Masks/base_clothingmask.yml +++ b/Resources/Prototypes/Entities/Clothing/Masks/base_clothingmask.yml @@ -5,6 +5,8 @@ components: - type: Sprite state: icon + - type: Item + size: Small - type: Clothing slots: [mask] diff --git a/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml b/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml index 06ec393c78..1bccb4c92a 100644 --- a/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml +++ b/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml @@ -4,7 +4,7 @@ id: ClothingNeckBase components: - type: Item - size: 10 + size: Small - type: Clothing quickEquip: true slots: diff --git a/Resources/Prototypes/Entities/Clothing/Neck/pins.yml b/Resources/Prototypes/Entities/Clothing/Neck/pins.yml index fe72fd12e9..0d22a653db 100644 --- a/Resources/Prototypes/Entities/Clothing/Neck/pins.yml +++ b/Resources/Prototypes/Entities/Clothing/Neck/pins.yml @@ -6,7 +6,7 @@ description: be nothing do crime components: - type: Item - size: 1 + size: Tiny - type: entity parent: ClothingNeckPinBase diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml index f92592f65e..5ec74294db 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml @@ -15,7 +15,7 @@ id: ClothingOuterBaseLarge components: - type: Item - size: 80 + size: Normal - type: Clothing slots: - outerClothing @@ -29,9 +29,9 @@ id: ClothingOuterStorageBase components: - type: Item - size: 10 + size: Normal - type: Storage - capacity: 10 + maxSlots: 3 - type: ContainerContainer containers: storagebase: !type:Container @@ -72,7 +72,7 @@ walkModifier: 0.4 sprintModifier: 0.6 - type: Item - size: 121 + size: Large - type: Armor modifiers: coefficients: @@ -107,7 +107,7 @@ walkModifier: 0.8 sprintModifier: 0.8 - type: Item - size: 80 + size: Normal - type: entity parent: ClothingOuterBase @@ -130,7 +130,7 @@ id: ClothingOuterBaseMedium components: - type: Item - size: 30 + size: Normal - type: Clothing slots: - outerClothing diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml index 5389eb8bfc..166657d65e 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml @@ -350,7 +350,7 @@ walkModifier: 0.75 sprintModifier: 0.75 - type: Item - size: 50 + size: Normal - type: Tag tags: - WhitelistChameleon diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml index 16bef8c7b2..f0aa96f613 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml @@ -176,7 +176,7 @@ - type: Sprite sprite: Clothing/OuterClothing/Suits/iansuit.rsi - type: Item - size: 30 + size: Normal - type: Clothing sprite: Clothing/OuterClothing/Suits/iansuit.rsi - type: ToggleableClothing @@ -197,7 +197,7 @@ - type: Sprite sprite: Clothing/OuterClothing/Suits/carpsuit.rsi - type: Item - size: 30 + size: Normal - type: Clothing sprite: Clothing/OuterClothing/Suits/carpsuit.rsi - type: ToggleableClothing diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml index 9bc3d25fc4..d15e114857 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml @@ -11,7 +11,7 @@ - type: TemperatureProtection coefficient: 0.1 - type: Item - size: 10 + size: Small - type: Armor modifiers: coefficients: diff --git a/Resources/Prototypes/Entities/Clothing/Shoes/base_clothingshoes.yml b/Resources/Prototypes/Entities/Clothing/Shoes/base_clothingshoes.yml index c829dc5d44..9bd7e00546 100644 --- a/Resources/Prototypes/Entities/Clothing/Shoes/base_clothingshoes.yml +++ b/Resources/Prototypes/Entities/Clothing/Shoes/base_clothingshoes.yml @@ -8,6 +8,8 @@ - FEET - type: Sprite state: icon + - type: Item + size: Normal - type: Food requiresSpecialDigestion: true - type: SolutionContainerManager @@ -39,7 +41,7 @@ id: ClothingShoesStorageBase components: - type: Storage - capacity: 10 + maxSlots: 1 - type: ContainerContainer containers: storagebase: !type:Container diff --git a/Resources/Prototypes/Entities/Clothing/Shoes/specific.yml b/Resources/Prototypes/Entities/Clothing/Shoes/specific.yml index 7b864e806e..eae044f8dd 100644 --- a/Resources/Prototypes/Entities/Clothing/Shoes/specific.yml +++ b/Resources/Prototypes/Entities/Clothing/Shoes/specific.yml @@ -181,7 +181,7 @@ - state: equipped-FEET offset: "0, -0.02" - type: Item - size: 10 + size: Small sprite: Clothing/Shoes/Specific/large_clown.rsi - type: ClothingSpeedModifier walkModifier: 0.85 diff --git a/Resources/Prototypes/Entities/Clothing/base_clothing.yml b/Resources/Prototypes/Entities/Clothing/base_clothing.yml index 60a94fe291..7e9d6e9568 100644 --- a/Resources/Prototypes/Entities/Clothing/base_clothing.yml +++ b/Resources/Prototypes/Entities/Clothing/base_clothing.yml @@ -3,6 +3,8 @@ parent: BaseItem id: Clothing components: + - type: Item + size: Normal - type: Sprite - type: Tag tags: diff --git a/Resources/Prototypes/Entities/Debugging/debug_sweps.yml b/Resources/Prototypes/Entities/Debugging/debug_sweps.yml index 2d374b8e12..e3289569a2 100644 --- a/Resources/Prototypes/Entities/Debugging/debug_sweps.yml +++ b/Resources/Prototypes/Entities/Debugging/debug_sweps.yml @@ -101,7 +101,7 @@ types: Blunt: 20000 - type: Item - size: 1 + size: Tiny sprite: Objects/Weapons/Melee/debug.rsi - type: entity diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index adba78141c..c94d5983e1 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -959,7 +959,7 @@ - map: ["enum.DamageStateVisualLayers.Base"] state: mouse-0 - type: Item - size: 5 + size: Tiny - type: Clothing quickEquip: false sprite: Mobs/Animals/mouse.rsi @@ -1424,7 +1424,7 @@ groups: Brute: 5 - type: Item - size: 80 + size: Normal - type: OnUseTimerTrigger delay: 10 beepSound: @@ -2329,7 +2329,7 @@ - map: ["enum.DamageStateVisualLayers.Base"] state: hamster-0 - type: Item - size: 5 + size: Tiny - type: Physics - type: Fixtures fixtures: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml index aaeeaf0bf6..13719f111a 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml @@ -172,7 +172,9 @@ graph: SupplyBot node: bot - type: Storage - capacity: 250 + maxSlots: 15 + maxItemSize: Large + maxTotalWeight: 60 - type: UserInterface interfaces: - key: enum.StorageUiKey.Key diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml index 118b242136..11228d0ed6 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml @@ -370,9 +370,9 @@ map: ["6pack6"] visible: false - type: Item - size: 6 + size: Normal - type: Storage - capacity: 30 + maxSlots: 6 whitelist: tags: - Cola diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/bread.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/bread.yml index a4cb797129..e4ebcc4c00 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/bread.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/bread.yml @@ -28,7 +28,7 @@ abstract: true components: - type: Item - size: 1 + size: Tiny - type: FlavorProfile flavors: - bread diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml index 09f5ce27ff..7db9015295 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml @@ -21,7 +21,7 @@ - ReagentId: Vitamin Quantity: 5 - type: Item - size: 25 + size: Normal - type: entity parent: FoodCakeBase @@ -43,7 +43,7 @@ - ReagentId: Vitamin Quantity: 1 - type: Item - size: 5 + size: Tiny # Custom Cake Example @@ -574,7 +574,7 @@ - type: Food transferAmount: 12 - type: Item - size: 40 + size: Normal - type: PointLight color: "#FFFF00" radius: 2 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donkpocket.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donkpocket.yml index 061852f561..b0be8011aa 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donkpocket.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donkpocket.yml @@ -16,7 +16,7 @@ - ReagentId: Nutriment Quantity: 3 - type: Item - size: 1 + size: Tiny - type: Tag tags: - DonkPocket diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donut.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donut.yml index bd007d87cb..9cf32f30b4 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donut.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donut.yml @@ -21,7 +21,7 @@ Quantity: 3 - type: Item sprite: Objects/Consumable/Food/Baked/donut.rsi - size: 1 + size: Tiny # Tastes like donut. # The sprinkles are now an overlay, so you can put them on any donut! If we really diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/misc.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/misc.yml index 54fc4d6553..1296bc4752 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/misc.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/misc.yml @@ -16,7 +16,7 @@ - ReagentId: Nutriment Quantity: 5 - type: Item - size: 1 + size: Tiny # Muffins/Buns diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/pizza.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/pizza.yml index 1f6a307f4e..01f93ccced 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/pizza.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/pizza.yml @@ -24,7 +24,7 @@ - type: SliceableFood count: 8 - type: Item - size: 8 + size: Normal - type: Tag tags: - Pizza @@ -53,7 +53,7 @@ - ReagentId: Vitamin Quantity: 0.8 - type: Item - size: 1 + size: Tiny - type: Tag tags: - Pizza diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/box.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/box.yml index 5130b9d7e2..5cf48d3c9b 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/box.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/box.yml @@ -38,13 +38,14 @@ map: ["pink-box6"] visible: false - type: Storage - capacity: 6 + maxSlots: 6 + maxTotalWeight: 12 whitelist: tags: - Donut - type: Item sprite: Objects/Consumable/Food/Baked/donut.rsi - size: 6 + size: Small heldPrefix: box - type: StorageFill contents: @@ -118,13 +119,13 @@ map: ["box12"] visible: false - type: Storage - capacity: 12 + maxSlots: 12 whitelist: tags: - Egg - type: Item sprite: Objects/Consumable/Food/egg.rsi - size: 12 + size: Small - type: StorageFill contents: - id: FoodEgg @@ -175,6 +176,9 @@ id: EggBoxBroken suffix: Broken components: + - type: Storage + maxSlots: 12 + maxItemSize: Small - type: StorageFill contents: - id: Eggshells @@ -206,7 +210,8 @@ map: ["enum.StorageVisualLayers.Door"] # TODO make these entitystorage again + placeablesurface after entity storage ECS gets merged. - type: Storage - capacity: 8 + maxSlots: 1 + maxItemSize: Normal whitelist: tags: - Pizza @@ -296,10 +301,10 @@ map: ["box6"] visible: false - type: Storage - capacity: 6 + maxSlots: 6 - type: Item sprite: Objects/Consumable/Food/Baked/nuggets.rsi - size: 6 + size: Small heldPrefix: box - type: StorageFill contents: @@ -333,10 +338,10 @@ whitelist: tags: - DonkPocket - capacity: 6 + maxSlots: 6 - type: Item sprite: Objects/Consumable/Food/Baked/donkpocket.rsi - size: 6 + size: Small - type: StorageFill contents: - id: FoodDonkpocket @@ -458,8 +463,6 @@ - type: Item sprite: Objects/Storage/Happyhonk/clown.rsi heldPrefix: box - - type: Storage - capacity: 30 - type: Tag tags: - Trash @@ -583,10 +586,8 @@ suffix: Toy Unsafe, Snacks name: syndicate snack box components: - - type: Item - size: 64 - type: Storage - capacity: 64 # need more room for goodies + maxSlots: 9 - type: StorageFill contents: # toy diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/tin.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/tin.yml index 4e63ca5012..89ec5a8c27 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/tin.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/tin.yml @@ -37,7 +37,7 @@ - type: Item sprite: Objects/Consumable/Food/snacks.rsi heldPrefix: packet - size: 3 + size: Tiny - type: DamageOnLand damage: types: @@ -63,7 +63,7 @@ - type: Item sprite: Objects/Consumable/Food/snacks.rsi heldPrefix: packet - size: 3 + size: Tiny - type: PhysicalComposition materialComposition: Steel: 100 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml index 4f6d10d98f..3eb2b96684 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml @@ -16,7 +16,7 @@ sprite: Objects/Consumable/Food/egg.rsi - type: Item sprite: Objects/Consumable/Food/egg.rsi - size: 1 + size: Tiny - type: SolutionContainerManager solutions: food: @@ -69,7 +69,7 @@ sprite: Objects/Consumable/Food/egg.rsi state: eggshells - type: Item - size: 1 + size: Tiny - type: SolutionContainerManager solutions: food: diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml index 35057aeacd..2b7c9d6e16 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml @@ -24,7 +24,7 @@ - ReagentId: Fat Quantity: 5 - type: Item - size: 5 + size: Tiny - type: Fixtures fixtures: fix1: @@ -209,7 +209,7 @@ graph: BearSteak node: start defaultTarget: filet migrawr - + - type: entity name: raw penguin meat diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml index 6439b2eb6c..0fb8afc6d7 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml @@ -136,7 +136,7 @@ - type: Sprite sprite: Objects/Specific/Hydroponics/nettle.rsi - type: Item - size: 10 + size: Small sprite: Objects/Specific/Hydroponics/nettle.rsi - type: MeleeWeapon damage: @@ -166,7 +166,7 @@ - type: Sprite sprite: Objects/Specific/Hydroponics/death_nettle.rsi - type: Item - size: 10 + size: Small sprite: Objects/Specific/Hydroponics/death_nettle.rsi - type: MeleeWeapon damage: @@ -184,7 +184,7 @@ - type: Produce seedId: deathNettle - type: MeleeChemicalInjector - transferAmount: 6 + transferAmount: 6 solution: food pierceArmor: true # We do a little trolling - type: Extractable @@ -222,7 +222,7 @@ - type: Tag tags: - Fruit - + - type: entity name: mimana parent: FoodProduceBase @@ -314,7 +314,7 @@ state: peel - type: Item sprite: Objects/Specific/Hydroponics/mimana.rsi - heldPrefix: peel + heldPrefix: peel - type: Slippery slipSound: path: /Audio/Effects/slip.ogg @@ -836,7 +836,7 @@ sprite: Objects/Specific/Hydroponics/corn.rsi state: cob - type: Item - size: 1 + size: Tiny - type: Tag tags: - Trash @@ -1237,7 +1237,7 @@ - type: Tag tags: - Galaxythistle - - Fruit # Probably? + - Fruit # Probably? - type: entity name: fly amanita @@ -1365,7 +1365,7 @@ description: Round green object that you can slice and eat. components: - type: Item - size: 10 + size: Small - type: FlavorProfile flavors: - watermelon @@ -1427,7 +1427,7 @@ description: Juicy green and red slice. components: - type: Item - size: 2 + size: Tiny - type: FlavorProfile flavors: - watermelon diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/skewer.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/skewer.yml index 0b32de1ce5..8c8f55f804 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/skewer.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/skewer.yml @@ -17,7 +17,7 @@ - ReagentId: Nutriment Quantity: 8 - type: Item - size: 5 + size: Small # Kebabs diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/snacks.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/snacks.yml index c2274aef6d..82c31a01c5 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/snacks.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/snacks.yml @@ -21,7 +21,7 @@ - type: Item sprite: Objects/Consumable/Food/snacks.rsi heldPrefix: packet - size: 3 + size: Tiny # Snacks # "Snacks" means food in a packet. Down the line this stuff can have multiple @@ -101,7 +101,7 @@ state: chocolatebar - type: Item heldPrefix: chocolatebar - size: 3 + size: Tiny - type: Tag tags: - FoodSnack @@ -346,7 +346,7 @@ - type: Item sprite: Objects/Consumable/Food/snacks.rsi heldPrefix: packet - size: 1 + size: Tiny - type: Food trash: FoodCookieFortune @@ -357,7 +357,7 @@ description: A carefully synthesized brick designed to contain the highest ratio of nutriment to volume. Tastes like shit. components: - type: Item - size: 10 + size: Small - type: Tag tags: - FoodSnack @@ -381,7 +381,7 @@ flavors: - nutribrick - type: Item - size: 10 + size: Small - type: Sprite state: nutribrick-open - type: Food diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cartons.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cartons.yml index 4d0b442c46..eff790cdd1 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cartons.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cartons.yml @@ -10,11 +10,9 @@ - state: closed - state: open map: ["openLayer"] - - type: Storage - capacity: 36 - type: Item sprite: Objects/Consumable/Smokeables/Cigarettes/Cartons/green.rsi - size: 36 + size: Normal - type: StorageFill contents: - id: CigPackGreen diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cigarette.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cigarette.yml index 09ac79b141..3543db2ed1 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cigarette.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cigarette.yml @@ -17,7 +17,7 @@ slots: [ mask ] equippedPrefix: unlit - type: Item - size: 1 + size: Tiny - type: Construction graph: smokeableCigarette node: cigarette @@ -41,7 +41,7 @@ slots: [ mask ] equippedPrefix: unlit - type: Item - size: 1 + size: Tiny - type: Construction graph: smokeableCigarette node: cigarette diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/joints.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/joints.yml index 402dcd80f5..e3ae06ec9f 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/joints.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/joints.yml @@ -17,7 +17,7 @@ slots: [ mask ] equippedPrefix: unlit - type: Item - size: 1 + size: Tiny - type: Construction graph: smokeableJoint node: joint @@ -48,7 +48,7 @@ slots: [ mask ] equippedPrefix: unlit - type: Item - size: 1 + size: Tiny - type: Construction graph: smokeableBlunt node: blunt diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/packs.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/packs.yml index 1d161b160a..6bc14cfb77 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/packs.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/packs.yml @@ -43,9 +43,9 @@ Steel: 50 - type: SpaceGarbage - type: Storage - capacity: 5 + maxSlots: 5 - type: Item - size: 5 + size: Small - type: StorageFill contents: - id: Cigarette @@ -108,9 +108,10 @@ Steel: 50 - type: SpaceGarbage - type: Storage - capacity: 10 + maxSlots: 10 + maxTotalWeight: 20 - type: Item - size: 10 + size: Small - type: StorageFill contents: - id: CigaretteRandom diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/rolling_paper.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/rolling_paper.yml index e1005bf113..324a28caca 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/rolling_paper.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/rolling_paper.yml @@ -9,7 +9,7 @@ tags: - RollingPaper - CigFilter - capacity: 20 + maxSlots: 20 - type: StorageFill contents: - id: PaperRolling @@ -31,7 +31,6 @@ tags: - RollingPaper - CigFilter - capacity: 32 - type: StorageFill contents: - id: PaperRolling @@ -54,7 +53,7 @@ state: cigpaper - type: Item sprite: Objects/Consumable/Smokeables/Cigarettes/paper.rsi - size: 5 + size: Tiny - type: Tag tags: - RollingPaper @@ -68,8 +67,6 @@ components: - type: Stack count: 1 - - type: Item - size: 1 - type: entity id: CigaretteFilter @@ -86,7 +83,7 @@ state: cigfilter - type: Item sprite: Objects/Consumable/Smokeables/Cigarettes/paper.rsi - size: 10 + size: Tiny - type: Tag tags: - CigFilter @@ -99,5 +96,3 @@ components: - type: Stack count: 1 - - type: Item - size: 2 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/case.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/case.yml index 6034df179a..eede84cd4b 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/case.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/case.yml @@ -35,10 +35,10 @@ map: ["cigar8"] visible: false - type: Storage - capacity: 8 + maxSlots: 8 - type: Item sprite: Objects/Consumable/Smokeables/Cigars/case.rsi - size: 8 + size: Small - type: StorageFill contents: - id: Cigar diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/cigar.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/cigar.yml index 4ed5912fc5..3495ae26f9 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/cigar.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/cigar.yml @@ -19,7 +19,7 @@ slots: [ mask ] equippedPrefix: unlit - type: Item - size: 1 + size: Tiny - type: entity id: CigarSpent @@ -49,7 +49,7 @@ slots: [ mask ] equippedPrefix: unlit - type: Item - size: 1 + size: Tiny - type: entity id: CigarGoldSpent diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Pipes/pipe.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Pipes/pipe.yml index 21017465bc..7d2b234a58 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Pipes/pipe.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Pipes/pipe.yml @@ -12,7 +12,7 @@ slots: [ mask ] equippedPrefix: unlit - type: Item - size: 3 + size: Tiny sprite: Objects/Consumable/Smokeables/Pipes/pipe.rsi - type: Appearance - type: BurnStateVisuals diff --git a/Resources/Prototypes/Entities/Objects/Decoration/lidsalami.yml b/Resources/Prototypes/Entities/Objects/Decoration/lidsalami.yml index dfff087e22..65141af36f 100644 --- a/Resources/Prototypes/Entities/Objects/Decoration/lidsalami.yml +++ b/Resources/Prototypes/Entities/Objects/Decoration/lidsalami.yml @@ -9,6 +9,6 @@ layers: - state: icon - type: Item - size: 1001 + size: Huge - type: StaticPrice price: 0 diff --git a/Resources/Prototypes/Entities/Objects/Decoration/present.yml b/Resources/Prototypes/Entities/Objects/Decoration/present.yml index 14a1dfbb5e..a7fd1cd1de 100644 --- a/Resources/Prototypes/Entities/Objects/Decoration/present.yml +++ b/Resources/Prototypes/Entities/Objects/Decoration/present.yml @@ -15,9 +15,7 @@ suffix: Empty components: - type: Item - size: 30 - - type: Storage - capacity: 30 + size: Normal - type: entity id: PresentRandomUnsafe diff --git a/Resources/Prototypes/Entities/Objects/Devices/Electronics/triggers.yml b/Resources/Prototypes/Entities/Objects/Devices/Electronics/triggers.yml index 4bb13bdd93..c462a3cb03 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Electronics/triggers.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Electronics/triggers.yml @@ -17,7 +17,7 @@ sprite: Objects/Devices/timer.rsi state: timer - type: Item - size: 5 + size: Small - type: PayloadTrigger components: - type: OnUseTimerTrigger diff --git a/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/chimp_upgrade_kit.yml b/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/chimp_upgrade_kit.yml index aed09fe70b..fc6c2ac787 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/chimp_upgrade_kit.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/chimp_upgrade_kit.yml @@ -6,9 +6,9 @@ components: - type: Sprite sprite: Objects/Misc/module.rsi - state: abductor_mod + state: abductor_mod - type: Item - size: 10 + size: Small - type: Tag tags: - - WeaponPistolCHIMPUpgradeKit \ No newline at end of file + - WeaponPistolCHIMPUpgradeKit diff --git a/Resources/Prototypes/Entities/Objects/Devices/forensic_scanner.yml b/Resources/Prototypes/Entities/Objects/Devices/forensic_scanner.yml index ad05777cfa..21943bfaff 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/forensic_scanner.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/forensic_scanner.yml @@ -8,7 +8,7 @@ sprite: Objects/Devices/forensic_scanner.rsi state: forensicnew - type: Item - size: 5 + size: Small - type: Clothing sprite: Objects/Devices/forensic_scanner.rsi quickEquip: false diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml index f44f1aa998..91becb5251 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml @@ -37,7 +37,7 @@ components: - IdCard - type: Item - size: 10 + size: Tiny - type: ContainerContainer containers: PDA-id: !type:ContainerSlot {} diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/base_instruments.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/base_instruments.yml index 06b2301262..07d918b576 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/base_instruments.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/base_instruments.yml @@ -16,7 +16,7 @@ - key: enum.InstrumentUiKey.Key type: InstrumentBoundUserInterface - type: Item - size: 24 + size: Normal - type: StaticPrice price: 200 diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_brass.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_brass.yml index e8ac6f7ce5..260490ccad 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_brass.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_brass.yml @@ -14,7 +14,7 @@ sprite: Objects/Fun/Instruments/trumpet.rsi state: icon - type: Item - size: 24 + size: Normal sprite: Objects/Fun/Instruments/trumpet.rsi - type: Tag tags: @@ -32,7 +32,7 @@ sprite: Objects/Fun/Instruments/trombone.rsi state: icon - type: Item - size: 48 + size: Normal sprite: Objects/Fun/Instruments/trombone.rsi - type: Tag tags: @@ -50,7 +50,7 @@ sprite: Objects/Fun/Instruments/frenchhorn.rsi state: icon - type: Item - size: 48 + size: Normal sprite: Objects/Fun/Instruments/frenchhorn.rsi - type: Tag tags: @@ -69,7 +69,7 @@ sprite: Objects/Fun/Instruments/euphonium.rsi state: icon - type: Item - size: 48 + size: Normal sprite: Objects/Fun/Instruments/euphonium.rsi - type: Tag tags: diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_misc.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_misc.yml index 15581cbd8d..47ea5ab2f6 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_misc.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_misc.yml @@ -10,7 +10,7 @@ - type: Instrument program: 121 - type: Item - size: 10 + size: Small - type: entity parent: BaseHandheldInstrument @@ -24,7 +24,7 @@ - type: Instrument program: 122 - type: Item - size: 10 + size: Small - type: entity parent: BaseHandheldInstrument @@ -38,7 +38,7 @@ - type: Instrument program: 123 - type: Item - size: 5 + size: Tiny - type: entity parent: BaseHandheldInstrument @@ -55,7 +55,7 @@ - type: Instrument program: 124 - type: Item - size: 10 + size: Small - type: Prayable sentMessage: prayer-popup-notify-centcom-sent notifiactionPrefix: prayer-chat-notify-centcom @@ -74,7 +74,7 @@ - type: Instrument program: 125 - type: Item - size: 10 + size: Small - type: entity parent: BaseHandheldInstrument @@ -88,7 +88,7 @@ - type: Instrument program: 126 - type: Item - size: 5 + size: Tiny - type: entity parent: BaseHandheldInstrument @@ -102,7 +102,7 @@ sprite: Objects/Fun/Instruments/gunpet.rsi state: icon - type: Item - size: 15 + size: Normal sprite: Objects/Fun/Instruments/gunpet.rsi - type: Tag tags: @@ -125,7 +125,7 @@ - BrassInstrument #Go figure. - type: Item sprite: Objects/Fun/Instruments/bike_horn.rsi - size: 10 + size: Small - type: Clothing sprite: Objects/Fun/Instruments/bike_horn.rsi slots: [Belt] diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_percussion.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_percussion.yml index 1ab803c5e2..d79b354df4 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_percussion.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_percussion.yml @@ -9,7 +9,7 @@ sprite: Objects/Fun/Instruments/glockenspiel.rsi state: icon - type: Item - size: 24 + size: Normal sprite: Objects/Fun/Instruments/glockenspiel.rsi - type: Tag tags: @@ -58,7 +58,7 @@ sprite: Objects/Fun/Instruments/microphone.rsi state: icon - type: Item - size: 10 + size: Small sprite: Objects/Fun/Instruments/microphone.rsi - type: entity @@ -76,7 +76,7 @@ sprite: Objects/Fun/Instruments/h_synthesizer.rsi state: icon - type: Item - size: 24 + size: Normal sprite: Objects/Fun/Instruments/h_synthesizer.rsi - type: Tag tags: @@ -135,5 +135,5 @@ sprite: Objects/Fun/Instruments/h_synthesizer.rsi state: icon - type: Item - size: 24 - sprite: Objects/Fun/Instruments/h_synthesizer.rsi \ No newline at end of file + size: Normal + sprite: Objects/Fun/Instruments/h_synthesizer.rsi diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_string.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_string.yml index c71fecd91b..70d1444bc4 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_string.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_string.yml @@ -15,7 +15,7 @@ sprite: Objects/Fun/Instruments/eguitar.rsi state: icon - type: Item - size: 24 + size: Normal sprite: Objects/Fun/Instruments/eguitar.rsi - type: Clothing quickEquip: false @@ -44,7 +44,7 @@ sprite: Objects/Fun/Instruments/bassguitar.rsi state: icon - type: Item - size: 24 + size: Normal sprite: Objects/Fun/Instruments/bassguitar.rsi - type: Clothing quickEquip: false @@ -72,7 +72,7 @@ sprite: Objects/Fun/Instruments/rockguitar.rsi state: icon - type: Item - size: 24 + size: Normal sprite: Objects/Fun/Instruments/rockguitar.rsi - type: Clothing quickEquip: false @@ -115,7 +115,7 @@ - StringInstrument - type: Item sprite: Objects/Fun/Instruments/guitar.rsi - size: 24 + size: Normal - type: Clothing quickEquip: false slots: @@ -178,7 +178,7 @@ sprite: Objects/Fun/Instruments/banjo.rsi state: icon - type: Item - size: 24 + size: Normal sprite: Objects/Fun/Instruments/banjo.rsi - type: Tag tags: @@ -200,7 +200,7 @@ sprite: Objects/Fun/Instruments/violin.rsi state: icon - type: Item - size: 24 + size: Normal sprite: Objects/Fun/Instruments/violin.rsi - type: Tag tags: @@ -218,7 +218,7 @@ sprite: Objects/Fun/Instruments/viola.rsi state: icon - type: Item - size: 24 + size: Normal sprite: Objects/Fun/Instruments/viola.rsi - type: Tag tags: @@ -236,7 +236,7 @@ sprite: Objects/Fun/Instruments/cello.rsi state: icon - type: Item - size: 48 + size: Normal sprite: Objects/Fun/Instruments/cello.rsi - type: Tag tags: diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_wind.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_wind.yml index 09db613313..afba6c2774 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_wind.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_wind.yml @@ -16,7 +16,7 @@ sprite: Objects/Fun/Instruments/saxophone.rsi state: icon - type: Item - size: 24 + size: Normal sprite: Objects/Fun/Instruments/saxophone.rsi - type: Tag tags: @@ -45,7 +45,7 @@ sprite: Objects/Fun/Instruments/accordion.rsi state: icon - type: Item - size: 24 + size: Normal sprite: Objects/Fun/Instruments/accordion.rsi - type: Tag tags: @@ -62,7 +62,7 @@ sprite: Objects/Fun/Instruments/harmonica.rsi state: icon - type: Item - size: 10 + size: Small sprite: Objects/Fun/Instruments/harmonica.rsi - type: Tag tags: @@ -80,7 +80,7 @@ sprite: Objects/Fun/Instruments/clarinet.rsi state: icon - type: Item - size: 20 + size: Normal sprite: Objects/Fun/Instruments/clarinet.rsi - type: Tag tags: @@ -98,7 +98,7 @@ sprite: Objects/Fun/Instruments/flute.rsi state: icon - type: Item - size: 20 + size: Normal sprite: Objects/Fun/Instruments/flute.rsi - type: Tag tags: @@ -116,7 +116,7 @@ sprite: Objects/Fun/Instruments/recorder.rsi state: icon - type: Item - size: 24 + size: Normal sprite: Objects/Fun/Instruments/recorder.rsi - type: Tag tags: @@ -134,7 +134,7 @@ sprite: Objects/Fun/Instruments/panflute.rsi state: icon - type: Item - size: 15 + size: Normal sprite: Objects/Fun/Instruments/panflute.rsi - type: Tag tags: @@ -153,7 +153,7 @@ sprite: Objects/Fun/Instruments/ocarina.rsi state: icon - type: Item - size: 15 + size: Normal sprite: Objects/Fun/Instruments/ocarina.rsi - type: Tag tags: @@ -171,8 +171,8 @@ sprite: Objects/Fun/Instruments/bagpipes.rsi state: icon - type: Item - size: 48 + size: Normal sprite: Objects/Fun/Instruments/bagpipes.rsi - type: Tag tags: - - WoodwindInstrument \ No newline at end of file + - WoodwindInstrument diff --git a/Resources/Prototypes/Entities/Objects/Fun/bike_horn.yml b/Resources/Prototypes/Entities/Objects/Fun/bike_horn.yml index fc20f1a58d..58b168e882 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/bike_horn.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/bike_horn.yml @@ -9,7 +9,7 @@ state: icon - type: Item sprite: Objects/Fun/bikehorn.rsi - size: 5 + size: Tiny - type: Clothing sprite: Objects/Fun/bikehorn.rsi slots: [Belt] @@ -58,7 +58,7 @@ state: icon - type: Item sprite: Objects/Fun/cluwnehorn.rsi - size: 5 + size: Tiny - type: Clothing sprite: Objects/Fun/cluwnehorn.rsi slots: [Belt] @@ -100,7 +100,7 @@ state: icon - type: Item sprite: Objects/Fun/goldbikehorn.rsi - size: 5 + size: Tiny - type: Clothing sprite: Objects/Fun/goldbikehorn.rsi slots: [Belt] @@ -119,7 +119,7 @@ state: icon - type: Item sprite: Objects/Fun/bananiumhorn.rsi - size: 5 + size: Tiny - type: Clothing sprite: Objects/Fun/bananiumhorn.rsi slots: [Belt] diff --git a/Resources/Prototypes/Entities/Objects/Fun/crayons.yml b/Resources/Prototypes/Entities/Objects/Fun/crayons.yml index 3ed188bd8e..2ec93b9c9b 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/crayons.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/crayons.yml @@ -9,7 +9,7 @@ sprite: Objects/Fun/crayons.rsi - type: Item sprite: Objects/Fun/crayons.rsi - size: 1 + size: Tiny - type: Tag tags: - Write @@ -235,10 +235,11 @@ sprite: Objects/Fun/crayons.rsi state: box - type: Storage - capacity: 7 + maxSlots: 7 + maxTotalWeight: 7 - type: Item sprite: Objects/Fun/crayons.rsi - size: 7 + size: Small heldPrefix: box - type: StorageFill contents: diff --git a/Resources/Prototypes/Entities/Objects/Fun/darts.yml b/Resources/Prototypes/Entities/Objects/Fun/darts.yml index bd4163d974..34486ac93e 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/darts.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/darts.yml @@ -40,7 +40,7 @@ types: Piercing: 4 - type: Item - size: 2 + size: Tiny sprite: Objects/Fun/Darts/dart_red.rsi - type: ItemCooldown - type: SolutionContainerManager @@ -86,7 +86,7 @@ - type: SolutionContainerVisuals maxFillLevels: 1 fillBaseName: dart - + - type: entity parent: Dart id: DartBlue @@ -95,7 +95,7 @@ sprite: Objects/Fun/Darts/dart_blue.rsi - type: Item sprite: Objects/Fun/Darts/dart_blue.rsi - + - type: entity parent: Dart id: DartPurple @@ -104,7 +104,7 @@ sprite: Objects/Fun/Darts/dart_purple.rsi - type: Item sprite: Objects/Fun/Darts/dart_purple.rsi - + - type: entity parent: Dart id: DartYellow diff --git a/Resources/Prototypes/Entities/Objects/Fun/dice.yml b/Resources/Prototypes/Entities/Objects/Fun/dice.yml index 6903a0bcac..d2c33b90f0 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/dice.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/dice.yml @@ -13,7 +13,7 @@ tags: - Dice - type: Item - size: 2 + size: Tiny - type: entity parent: BaseDice diff --git a/Resources/Prototypes/Entities/Objects/Fun/dice_bag.yml b/Resources/Prototypes/Entities/Objects/Fun/dice_bag.yml index 8c3b5aea8b..20c3c12736 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/dice_bag.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/dice_bag.yml @@ -17,11 +17,11 @@ sprite: Objects/Fun/dice.rsi state: dicebag - type: Item + size: Small - type: Storage - capacity: 18 whitelist: tags: - - Dice + - Dice - type: entity parent: DiceBag @@ -32,4 +32,5 @@ sprite: Objects/Fun/dice.rsi state: magicdicebag - type: Storage - capacity: 30 + maxSlots: 14 + maxTotalWeight: 28 diff --git a/Resources/Prototypes/Entities/Objects/Fun/puppet.yml b/Resources/Prototypes/Entities/Objects/Fun/puppet.yml index c0649d0acf..01a15d2e5b 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/puppet.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/puppet.yml @@ -14,7 +14,7 @@ - type: DoAfter - type: VentriloquistPuppet - type: Item - size: 30 + size: Normal - type: Muted - type: TypingIndicator proto: robot diff --git a/Resources/Prototypes/Entities/Objects/Fun/toys.yml b/Resources/Prototypes/Entities/Objects/Fun/toys.yml index 491ae0037a..c326fc9707 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/toys.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/toys.yml @@ -554,7 +554,7 @@ components: - type: Sprite - type: Item - size: 24 + size: Normal - type: entity parent: FoamWeaponBase @@ -566,7 +566,7 @@ sprite: Objects/Fun/toys.rsi state: foamcrossbow - type: Item - size: 24 + size: Normal sprite: Objects/Fun/toys.rsi heldPrefix: foamcrossbow - type: Gun @@ -672,7 +672,7 @@ types: Blunt: 0 - type: Item - size: 20 + size: Small sprite: Objects/Fun/toys.rsi heldPrefix: foamblade - type: ItemCooldown @@ -692,7 +692,7 @@ sound: path: /Audio/Effects/Footsteps/bounce.ogg - type: Item - size: 24 + size: Normal sprite: Objects/Fun/toys.rsi heldPrefix: bask - type: TileFrictionModifier @@ -708,7 +708,7 @@ sprite: Objects/Fun/toys.rsi state: football - type: Item - size: 12 + size: Small sprite: Objects/Fun/toys.rsi heldPrefix: footb @@ -725,7 +725,7 @@ sound: path: /Audio/Effects/Footsteps/bounce.ogg - type: Item - size: 24 + size: Normal sprite: Objects/Fun/toys.rsi heldPrefix: beachb - type: TileFrictionModifier @@ -741,7 +741,7 @@ sprite: Objects/Fun/toys.rsi state: synb - type: Item - size: 24 + size: Small sprite: Objects/Fun/toys.rsi heldPrefix: synb - type: Damageable @@ -760,7 +760,7 @@ sprite: Objects/Fun/toys.rsi state: corgib - type: Item - size: 24 + size: Normal sprite: Objects/Fun/toys.rsi heldPrefix: corgib - type: Damageable @@ -785,7 +785,7 @@ intensity: 2000 falloffPower: 2.6 - type: Item - size: 12 + size: Small sprite: Objects/Fun/toys.rsi heldPrefix: singularitytoy @@ -803,7 +803,7 @@ radius: 2 color: "#00CCFF" - type: Item - size: 24 + size: Normal sprite: Objects/Fun/toys.rsi heldPrefix: orb - type: TileFrictionModifier @@ -828,7 +828,7 @@ shader: unshaded map: [ "blade" ] - type: Item - size: 5 + size: Small sprite: Objects/Weapons/Melee/e_sword.rsi - type: UseDelay delay: 1.0 @@ -892,7 +892,7 @@ types: Blunt: 0 - type: Item - size: 15 + size: Normal sprite: Objects/Weapons/Melee/cutlass.rsi - type: entity @@ -934,7 +934,7 @@ - type: StaminaDamageOnHit damage: 8 - type: Item - size: 5 + size: Small sprite: Objects/Fun/rubber_hammer.rsi - type: Appearance - type: DisarmMalus diff --git a/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml b/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml index 2c1a8e628d..898d2c37c1 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml @@ -9,7 +9,7 @@ sprite: Objects/Materials/Sheets/glass.rsi - type: Item sprite: Objects/Materials/Sheets/glass.rsi - size: 30 + size: Normal - type: StaticPrice price: 0 - type: Tag @@ -83,8 +83,6 @@ - type: Stack stackType: Glass count: 10 - - type: Item - size: 10 - type: entity parent: SheetGlass @@ -96,16 +94,12 @@ - type: Stack stackType: Glass count: 1 - - type: Item - size: 1 - type: entity parent: SheetGlass id: SheetGlassLingering0 suffix: Lingering, 0 components: - - type: Item - size: 0 - type: Stack lingering: true count: 0 @@ -174,8 +168,6 @@ - type: Stack stackType: ReinforcedGlass count: 1 - - type: Item - size: 1 - type: entity parent: SheetGlassBase @@ -201,7 +193,6 @@ map: ["base"] - type: Item heldPrefix: pglass - size: 30 - type: Construction graph: Glass node: SheetPGlass @@ -239,8 +230,6 @@ - type: Stack stackType: PlasmaGlass count: 1 - - type: Item - size: 1 - type: entity parent: SheetPGlass @@ -281,8 +270,6 @@ - type: Stack stackType: ReinforcedPlasmaGlass count: 1 - - type: Item - size: 1 - type: entity parent: SheetGlassBase @@ -345,8 +332,6 @@ - type: Stack stackType: UraniumGlass count: 1 - - type: Item - size: 1 - type: entity parent: SheetUGlass @@ -386,5 +371,3 @@ - type: Stack stackType: ReinforcedUraniumGlass count: 1 - - type: Item - size: 1 diff --git a/Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml b/Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml index 69b7f83ddb..99c7ae0e11 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml @@ -8,7 +8,7 @@ sprite: Objects/Materials/Sheets/metal.rsi - type: Item sprite: Objects/Materials/Sheets/metal.rsi - size: 30 + size: Normal - type: StaticPrice price: 0 - type: Tag @@ -75,8 +75,6 @@ name: steel suffix: 10 components: - - type: Item - size: 10 - type: Sprite state: steel - type: Stack @@ -89,8 +87,6 @@ name: steel suffix: Single components: - - type: Item - size: 1 - type: Sprite state: steel - type: Stack @@ -102,8 +98,6 @@ id: SheetSteelLingering0 suffix: Lingering, 0 components: - - type: Item - size: 0 - type: Stack lingering: true count: 0 @@ -145,8 +139,6 @@ - type: Stack stackType: Plasteel count: 10 - - type: Item - size: 10 - type: entity parent: SheetPlasteel @@ -159,5 +151,3 @@ - type: Stack stackType: Plasteel count: 1 - - type: Item - size: 1 diff --git a/Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml b/Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml index 3cb6f027a9..ed1a1e3da0 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml @@ -8,7 +8,7 @@ sprite: Objects/Materials/Sheets/other.rsi - type: Item sprite: Objects/Materials/Sheets/other.rsi - size: 30 + size: Normal - type: Tag tags: - Sheet @@ -56,8 +56,6 @@ state: paper - type: Stack count: 1 - - type: Item - size: 1 - type: entity parent: SheetOtherBase @@ -106,8 +104,6 @@ state: plasma - type: Stack count: 1 - - type: Item - size: 1 - type: entity parent: SheetOtherBase @@ -138,7 +134,6 @@ map: ["base"] - type: Item heldPrefix: plastic - size: 30 - type: Appearance - type: entity @@ -149,8 +144,6 @@ components: - type: Sprite state: plastic - - type: Item - size: 10 - type: Stack count: 10 @@ -162,8 +155,6 @@ components: - type: Sprite state: plastic - - type: Item - size: 1 - type: Stack count: 1 @@ -212,8 +203,6 @@ components: - type: Stack count: 1 - - type: Item - size: 1 - type: entity parent: SheetOtherBase @@ -255,5 +244,3 @@ state: meat - type: Stack count: 1 - - type: Item - size: 1 diff --git a/Resources/Prototypes/Entities/Objects/Materials/ingots.yml b/Resources/Prototypes/Entities/Objects/Materials/ingots.yml index 61aefee332..d383a7266d 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/ingots.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/ingots.yml @@ -8,7 +8,7 @@ sprite: Objects/Materials/ingots.rsi - type: Item sprite: Objects/Materials/ingots.rsi - size: 30 + size: Normal - type: StaticPrice price: 0 - type: Tag @@ -62,8 +62,6 @@ state: gold - type: Stack count: 1 - - type: Item - size: 1 - type: entity parent: IngotBase @@ -99,7 +97,3 @@ components: - type: Sprite state: silver - - type: Stack - count: 1 - - type: Item - size: 1 diff --git a/Resources/Prototypes/Entities/Objects/Materials/materials.yml b/Resources/Prototypes/Entities/Objects/Materials/materials.yml index 7386eaee4d..4af2886c24 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/materials.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/materials.yml @@ -8,7 +8,7 @@ sprite: Objects/Materials/materials.rsi - type: Item sprite: Objects/Materials/materials.rsi - size: 30 + size: Normal - type: Tag tags: - DroneUsable @@ -47,8 +47,6 @@ - state: cardboard_3 map: ["base"] - type: Appearance - - type: Item - size: 30 - type: entity parent: MaterialCardboard @@ -59,8 +57,6 @@ state: cardboard - type: Stack count: 10 - - type: Item - size: 10 - type: entity parent: MaterialCardboard @@ -71,8 +67,6 @@ state: cardboard - type: Stack count: 1 - - type: Item - size: 1 - type: entity parent: MaterialBase @@ -114,8 +108,6 @@ - state: cloth_3 map: ["base"] - type: Appearance - - type: Item - size: 30 - type: Food requiresSpecialDigestion: true - type: SolutionContainerManager @@ -144,8 +136,6 @@ state: cloth - type: Stack count: 10 - - type: Item - size: 10 - type: entity parent: MaterialCloth @@ -156,8 +146,6 @@ state: cloth - type: Stack count: 1 - - type: Item - size: 1 - type: entity parent: MaterialBase @@ -209,8 +197,6 @@ state: durathread - type: Stack count: 1 - - type: Item - size: 1 - type: entity parent: MaterialBase @@ -245,8 +231,6 @@ components: - type: Stack count: 10 - - type: Item - size: 10 - type: entity parent: MaterialWoodPlank @@ -255,8 +239,6 @@ components: - type: Stack count: 1 - - type: Item - size: 1 - type: entity parent: MaterialBase @@ -278,8 +260,6 @@ - type: GuideHelp guides: - Cloning - - type: Item - size: 100 - type: entity parent: MaterialBiomass @@ -288,8 +268,6 @@ components: - type: Stack count: 1 - - type: Item - size: 1 # Following not used currently - type: entity @@ -352,7 +330,6 @@ state: diamond - type: Item heldPrefix: diamond - size: 60 - type: entity parent: MaterialDiamond @@ -361,8 +338,6 @@ components: - type: Stack count: 1 - - type: Item - size: 2 - type: entity parent: MaterialBase @@ -383,8 +358,6 @@ - state: cotton_3 map: ["base"] - type: Appearance - - type: Item - size: 30 - type: Food requiresSpecialDigestion: true - type: SolutionContainerManager @@ -410,8 +383,6 @@ state: cotton - type: Stack count: 1 - - type: Item - size: 1 - type: entity parent: MaterialBase @@ -462,8 +433,6 @@ - ReagentId: Honk Quantity: 5 - type: Appearance - - type: Item - size: 20 - type: entity parent: MaterialBananium @@ -474,8 +443,6 @@ state: bananium - type: Stack count: 1 - - type: Item - size: 2 - type: entity parent: MaterialBase @@ -493,8 +460,6 @@ - type: Stack count: 50 stackType: WebSilk - - type: Item - size: 50 - type: Food requiresSpecialDigestion: true - type: FlavorProfile @@ -522,8 +487,6 @@ components: - type: Stack count: 25 - - type: Item - size: 25 - type: entity parent: MaterialWebSilk @@ -532,8 +495,6 @@ components: - type: Stack count: 1 - - type: Item - size: 1 - type: entity parent: MaterialBase @@ -554,8 +515,6 @@ - state: cotton_3 map: ["base"] - type: Appearance - - type: Item - size: 30 - type: Food - type: BadFood - type: SolutionContainerManager @@ -573,5 +532,3 @@ components: - type: Stack count: 1 - - type: Item - size: 1 diff --git a/Resources/Prototypes/Entities/Objects/Materials/ore.yml b/Resources/Prototypes/Entities/Objects/Materials/ore.yml index f27d1b770e..2b6fec873b 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/ore.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/ore.yml @@ -8,7 +8,7 @@ sprite: Objects/Materials/ore.rsi - type: Item sprite: Objects/Materials/ore.rsi - size: 60 + size: Normal - type: Tag tags: - Ore @@ -57,8 +57,6 @@ components: - type: Stack count: 1 - - type: Item - size: 2 - type: entity parent: OreBase @@ -82,8 +80,6 @@ components: - type: Stack count: 1 - - type: Item - size: 2 - type: entity parent: OreBase @@ -107,8 +103,6 @@ components: - type: Stack count: 1 - - type: Item - size: 2 - type: entity parent: OreBase @@ -132,8 +126,6 @@ components: - type: Stack count: 1 - - type: Item - size: 2 - type: entity parent: OreBase @@ -157,8 +149,6 @@ components: - type: Stack count: 1 - - type: Item - size: 2 - type: entity parent: OreBase @@ -182,9 +172,6 @@ components: - type: Stack count: 1 - - type: Item - size: 2 - - type: entity parent: OreBase @@ -208,5 +195,3 @@ components: - type: Stack count: 1 - - type: Item - size: 2 diff --git a/Resources/Prototypes/Entities/Objects/Materials/parts.yml b/Resources/Prototypes/Entities/Objects/Materials/parts.yml index e75704c2a4..7529bdee04 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/parts.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/parts.yml @@ -44,7 +44,7 @@ - state: rods_5 map: ["base"] - type: Item - size: 30 + size: Normal # heldPrefix: rods - type: Construction graph: MetalRod @@ -73,8 +73,6 @@ state: rods - type: Stack count: 10 - - type: Item - size: 10 - type: entity parent: PartRodMetal @@ -90,16 +88,12 @@ state: rods - type: Stack count: 1 - - type: Item - size: 1 - type: entity parent: PartRodMetal id: PartRodMetalLingering0 suffix: Lingering, 0 components: - - type: Item - size: 0 - type: Stack lingering: true count: 0 diff --git a/Resources/Prototypes/Entities/Objects/Materials/shards.yml b/Resources/Prototypes/Entities/Objects/Materials/shards.yml index affd08edb1..8129ab2116 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/shards.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/shards.yml @@ -26,7 +26,7 @@ Slash: 3.5 - type: Item sprite: Objects/Materials/Shards/shard.rsi - size: 4 + size: Tiny - type: CollisionWake enabled: false - type: Fixtures diff --git a/Resources/Prototypes/Entities/Objects/Misc/bedsheets.yml b/Resources/Prototypes/Entities/Objects/Misc/bedsheets.yml index 6c6f2d484e..2945c4f68e 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/bedsheets.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/bedsheets.yml @@ -13,7 +13,7 @@ sprite: Objects/Misc/bedsheets.rsi noRot: true - type: Item - size: 10 + size: Small - type: Clothing quickEquip: true slots: diff --git a/Resources/Prototypes/Entities/Objects/Misc/box.yml b/Resources/Prototypes/Entities/Objects/Misc/box.yml index 59a2abd566..fa54570d27 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/box.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/box.yml @@ -7,9 +7,9 @@ sprite: Objects/Storage/boxes.rsi - type: Item sprite: Objects/Storage/boxes.rsi - size: 30 + size: Normal - type: Storage - capacity: 30 + maxSlots: 7 - type: ContainerContainer containers: storagebase: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Misc/briefcases.yml b/Resources/Prototypes/Entities/Objects/Misc/briefcases.yml index 1866d3513e..ebf776a7b1 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/briefcases.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/briefcases.yml @@ -5,9 +5,10 @@ description: Useful for carrying items in your hands. components: - type: Item - size: 60 + size: Large - type: Storage - capacity: 60 + maxSlots: 4 + maxTotalWeight: 16 - type: Tag tags: - Briefcase @@ -25,16 +26,17 @@ sprite: Objects/Storage/Briefcases/briefcase_brown.rsi - type: entity - parent: BaseStorageItem + parent: BriefcaseBase abstract: true id: BriefcaseSyndieBase suffix: Syndicate, Empty description: Useful for carrying items in your hands. components: - type: Item - size: 80 + size: Large - type: Storage - capacity: 80 + maxSlots: 6 + maxTotalWeight: 24 - type: Tag tags: - Briefcase diff --git a/Resources/Prototypes/Entities/Objects/Misc/eggspider.yml b/Resources/Prototypes/Entities/Objects/Misc/eggspider.yml index f53e39e364..c2357ed3c8 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/eggspider.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/eggspider.yml @@ -14,7 +14,7 @@ Structural: 2 animation: WeaponArcPunch - type: Item - size: 5 + size: Small - type: PointLight radius: 1.5 energy: 3 diff --git a/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml b/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml index a90f598a5d..0697281a0f 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml @@ -11,7 +11,7 @@ map: [ "enabled" ] - type: Item sprite: Objects/Misc/fire_extinguisher.rsi - size: 10 + size: Small - type: SolutionContainerManager solutions: spray: diff --git a/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml b/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml index 77b321f951..1b925b5cb0 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml @@ -38,7 +38,7 @@ sprite: Objects/Misc/Lights/lights.rsi - type: Item sprite: Objects/Misc/Lights/lights.rsi - size: 20 + size: Normal heldPrefix: off - type: PointLight enabled: false @@ -158,7 +158,7 @@ description: A pole with powerful mounted lights on it. components: - type: Item - size: 50 + size: Normal - type: Sprite layers: - state: floodlight diff --git a/Resources/Prototypes/Entities/Objects/Misc/handcuffs.yml b/Resources/Prototypes/Entities/Objects/Misc/handcuffs.yml index befd24f36e..4f2199bfa8 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/handcuffs.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/handcuffs.yml @@ -5,7 +5,7 @@ parent: BaseItem components: - type: Item - size: 3 + size: Small - type: Handcuff cuffedRSI: Objects/Misc/handcuffs.rsi bodyIconState: body-overlay @@ -31,8 +31,6 @@ id: Cablecuffs parent: Handcuffs components: - - type: Item - size: 5 - type: Handcuff breakoutTime: 15 cuffedRSI: Objects/Misc/cablecuffs.rsi @@ -65,7 +63,7 @@ parent: Handcuffs components: - type: Item - size: 2 + size: Tiny - type: Handcuff breakoutTime: 20 # halfway between improvised cablecuffs and metal ones cuffedRSI: Objects/Misc/cablecuffs.rsi # cablecuffs will look fine @@ -92,7 +90,7 @@ abstract: true components: - type: Item - size: 2 + size: Tiny - type: Tag tags: - Trash @@ -128,7 +126,7 @@ description: Used to restrain those who may cause harm to themselves or others. components: - type: Item - size: 20 + size: Normal - type: Handcuff cuffedRSI: Clothing/OuterClothing/Misc/straight_jacket.rsi breakoutTime: 100 diff --git a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml index 24462d5113..df8a007576 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml @@ -12,6 +12,7 @@ - idcard sprite: Objects/Misc/id_cards.rsi - type: Item + size: Small heldPrefix: default - type: Access - type: IdCard diff --git a/Resources/Prototypes/Entities/Objects/Misc/implanters.yml b/Resources/Prototypes/Entities/Objects/Misc/implanters.yml index 41966ab93f..dd609dee6c 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/implanters.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/implanters.yml @@ -81,7 +81,7 @@ components: - type: Item sprite: Objects/Specific/Medical/syndi_implanter.rsi - size: 3 + size: Tiny - type: Sprite sprite: Objects/Specific/Medical/syndi_implanter.rsi state: implanter1 diff --git a/Resources/Prototypes/Entities/Objects/Misc/improvised_gun_parts.yml b/Resources/Prototypes/Entities/Objects/Misc/improvised_gun_parts.yml index d94193e49a..abf4e0974a 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/improvised_gun_parts.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/improvised_gun_parts.yml @@ -2,12 +2,12 @@ #TODO: Assimilate these into the same RSI. - type: entity parent: BaseItem - id: ModularReceiver - name: modular receiver + id: ModularReceiver + name: modular receiver description: A vital part used in the creation of firearms. #Could use a better description, but I'm not a gun nut so I can't really do that. components: # - type: Item -# size: 15 +# size: Normal - type: Sprite sprite: Objects/Misc/modular_receiver.rsi state: icon @@ -23,7 +23,7 @@ description: A robust wooden stock, used in the creation of firearms. #Same as above components: # - type: Item -# size: 25 +# size: Normal - type: Sprite sprite: Objects/Misc/rifle_stock.rsi state: icon diff --git a/Resources/Prototypes/Entities/Objects/Misc/machine_parts.yml b/Resources/Prototypes/Entities/Objects/Misc/machine_parts.yml index be1f4f65ee..c38239a08d 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/machine_parts.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/machine_parts.yml @@ -8,7 +8,7 @@ - type: Sprite sprite: Objects/Misc/stock_parts.rsi - type: Item - size: 1 + size: Tiny - type: GuideHelp guides: - MachineUpgrading diff --git a/Resources/Prototypes/Entities/Objects/Misc/medalcase.yml b/Resources/Prototypes/Entities/Objects/Misc/medalcase.yml index 64c11d5a2f..d1ceae2c60 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/medalcase.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/medalcase.yml @@ -9,9 +9,10 @@ state: icon - type: Item sprite: Objects/Storage/medalcase.rsi - size: 80 + size: Normal - type: Storage - capacity: 80 + maxSlots: 8 + maxTotalWeight: 16 - type: StorageFill contents: - id: ClothingNeckGoldmedal diff --git a/Resources/Prototypes/Entities/Objects/Misc/monkeycube.yml b/Resources/Prototypes/Entities/Objects/Misc/monkeycube.yml index 32ad0552c0..fcf47d713d 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/monkeycube.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/monkeycube.yml @@ -8,7 +8,6 @@ whitelist: tags: - MonkeyCube - capacity: 30 - type: StorageFill contents: - id: MonkeyCubeWrapped @@ -47,7 +46,6 @@ whitelist: tags: - MonkeyCube - capacity: 30 - type: StorageFill contents: - id: SyndicateSpongeWrapped diff --git a/Resources/Prototypes/Entities/Objects/Misc/paper.yml b/Resources/Prototypes/Entities/Objects/Misc/paper.yml index 132d6b7aff..99dc9c07c6 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/paper.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/paper.yml @@ -23,7 +23,7 @@ - key: enum.PaperUiKey.Key type: PaperBoundUserInterface - type: Item - size: 1 + size: Tiny - type: Tag tags: - Document @@ -245,7 +245,7 @@ - type: Item sprite: Objects/Misc/bureaucracy.rsi heldPrefix: pen - size: 2 + size: Tiny - type: PhysicalComposition materialComposition: Steel: 25 @@ -277,7 +277,7 @@ - type: Item sprite: Objects/Misc/bureaucracy.rsi heldPrefix: overpriced_pen - size: 2 + size: Tiny - type: entity name: captain's fountain pen @@ -336,9 +336,11 @@ # black: "#3f3f3f" - type: Item sprite: Objects/Misc/bureaucracy.rsi - size: 5 + size: Small - type: Storage - capacity: 10 + maxSlots: 10 + maxItemSize: Small + maxTotalWeight: 20 whitelist: tags: - Document @@ -468,13 +470,14 @@ insertOnInteract: false - type: Item sprite: Objects/Misc/clipboard.rsi - size: 10 + size: Small - type: Clothing slots: [belt] quickEquip: false sprite: Objects/Misc/clipboard.rsi - type: Storage - capacity: 20 + maxSlots: 15 + maxTotalWeight: 30 whitelist: tags: - Document @@ -526,13 +529,13 @@ insertOnInteract: true - type: Item sprite: Objects/Misc/qm_clipboard.rsi - size: 30 + size: Normal - type: Clothing slots: [belt] quickEquip: false sprite: Objects/Misc/qm_clipboard.rsi - type: Storage - capacity: 90 + maxSlots: 20 quickInsert: true whitelist: tags: @@ -585,7 +588,7 @@ sprite: Objects/Misc/bureaucracy.rsi state: stamp-mime - type: Item - size: 3 + size: Tiny - type: entity name: alternate rubber stamp diff --git a/Resources/Prototypes/Entities/Objects/Misc/potatoai_chip.yml b/Resources/Prototypes/Entities/Objects/Misc/potatoai_chip.yml index 528aa30a14..0f871831e2 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/potatoai_chip.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/potatoai_chip.yml @@ -8,10 +8,10 @@ sprite: Objects/Misc/potatoai_chip.rsi state: icon - type: Item - size: 3 + size: Tiny - type: Tag tags: - SmallAIChip - type: Construction graph: PotatoAIChip - node: potatoaichip \ No newline at end of file + node: potatoaichip diff --git a/Resources/Prototypes/Entities/Objects/Misc/subdermal_implants.yml b/Resources/Prototypes/Entities/Objects/Misc/subdermal_implants.yml index 6632010a79..4335461660 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/subdermal_implants.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/subdermal_implants.yml @@ -110,9 +110,10 @@ - type: SubdermalImplant implantAction: ActionOpenStorageImplant - type: Item - size: 9999 + size: Huge - type: Storage - capacity: 20 #10-20 should be more than enough for this + maxSlots: 4 + maxItemSize: Small - type: ContainerContainer containers: storagebase: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Power/antimatter_jar.yml b/Resources/Prototypes/Entities/Objects/Power/antimatter_jar.yml index 8267903dbb..22e5b9bb3c 100644 --- a/Resources/Prototypes/Entities/Objects/Power/antimatter_jar.yml +++ b/Resources/Prototypes/Entities/Objects/Power/antimatter_jar.yml @@ -5,7 +5,7 @@ description: A hermetically sealed jar containing antimatter for use in an antimatter reactor. components: - type: Item - size: 5 + size: Normal sprite: Objects/Power/AME/ame_jar.rsi - type: Sprite sprite: Objects/Power/AME/ame_jar.rsi diff --git a/Resources/Prototypes/Entities/Objects/Power/antimatter_part.yml b/Resources/Prototypes/Entities/Objects/Power/antimatter_part.yml index a393cad617..7d428bcc5a 100644 --- a/Resources/Prototypes/Entities/Objects/Power/antimatter_part.yml +++ b/Resources/Prototypes/Entities/Objects/Power/antimatter_part.yml @@ -5,7 +5,7 @@ description: A flatpack used for constructing an antimatter engine reactor. Use a multitool to unpack it. components: - type: Item - size: 5 + size: Small sprite: Objects/Power/AME/ame_part.rsi - type: Sprite sprite: Objects/Power/AME/ame_part.rsi diff --git a/Resources/Prototypes/Entities/Objects/Power/powersink.yml b/Resources/Prototypes/Entities/Objects/Power/powersink.yml index 9317dd741f..c8684323a9 100644 --- a/Resources/Prototypes/Entities/Objects/Power/powersink.yml +++ b/Resources/Prototypes/Entities/Objects/Power/powersink.yml @@ -5,7 +5,7 @@ description: Drains immense amounts of electricity from the grid. components: - type: Item - size: 150 + size: Large - type: NodeContainer examinable: true nodes: diff --git a/Resources/Prototypes/Entities/Objects/Power/solar_parts.yml b/Resources/Prototypes/Entities/Objects/Power/solar_parts.yml index ff333b93c2..5b3f5e90ce 100644 --- a/Resources/Prototypes/Entities/Objects/Power/solar_parts.yml +++ b/Resources/Prototypes/Entities/Objects/Power/solar_parts.yml @@ -4,7 +4,7 @@ name: solar assembly part components: - type: Item - size: 10 + size: Small - type: Sprite sprite: Objects/Power/solar_parts.rsi state: solar_assembly_parts diff --git a/Resources/Prototypes/Entities/Objects/Shields/shields.yml b/Resources/Prototypes/Entities/Objects/Shields/shields.yml index 8afe40bfe7..76a8e576a5 100644 --- a/Resources/Prototypes/Entities/Objects/Shields/shields.yml +++ b/Resources/Prototypes/Entities/Objects/Shields/shields.yml @@ -10,7 +10,7 @@ state: riot-icon - type: Item sprite: Objects/Weapons/Melee/shields.rsi - size: 100 + size: Huge heldPrefix: riot - type: Blocking passiveBlockModifier: @@ -308,7 +308,7 @@ path: /Audio/Weapons/ebladeon.ogg deActivateSound: path: /Audio/Weapons/ebladeoff.ogg - offSize: 5 + offSize: Small - type: Sprite sprite: Objects/Weapons/Melee/e_shield.rsi layers: @@ -319,7 +319,7 @@ shader: unshaded map: [ "shield" ] - type: Item - size: 5 + size: Small sprite: Objects/Weapons/Melee/e_shield.rsi heldPrefix: eshield - type: UseDelay @@ -398,7 +398,7 @@ state: eshield-icon - type: Item sprite: Objects/Weapons/Melee/e_shield.rsi - size: 5 + size: Small heldPrefix: eshield - type: entity @@ -417,7 +417,7 @@ path: /Audio/Weapons/telescopicoff.ogg params: volume: -5 - offSize: 10 + offSize: Small - type: Sprite sprite: Objects/Weapons/Melee/teleriot_shield.rsi layers: @@ -426,7 +426,7 @@ visible: false map: [ "shield" ] - type: Item - size: 10 + size: Small sprite: Objects/Weapons/Melee/teleriot_shield.rsi heldPrefix: teleriot - type: UseDelay diff --git a/Resources/Prototypes/Entities/Objects/Specific/Chapel/bibles.yml b/Resources/Prototypes/Entities/Objects/Specific/Chapel/bibles.yml index 19414d0997..3e72257d5c 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Chapel/bibles.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Chapel/bibles.yml @@ -31,13 +31,13 @@ sprite: Objects/Specific/Chapel/bible.rsi state: icon - type: Item - size: 15 + size: Normal sprite: Objects/Specific/Chapel/bible.rsi - type: Clothing slots: - Belt - type: Storage - capacity: 10 + maxSlots: 1 - type: UserInterface interfaces: - key: enum.StorageUiKey.Key @@ -74,7 +74,7 @@ sprite: Objects/Specific/Chapel/necronomicon.rsi state: icon - type: Item - size: 15 + size: Normal sprite: Objects/Specific/Chapel/necronomicon.rsi - type: Clothing slots: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chem_bag.yml b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chem_bag.yml index 8be5fecb4f..597f48744c 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chem_bag.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chem_bag.yml @@ -13,9 +13,9 @@ slots: - belt - type: Item - size: 46 + size: Normal - type: Storage - capacity: 45 + maxSlots: 40 quickInsert: true areaInsert: true whitelist: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Forensics/forensics.yml b/Resources/Prototypes/Entities/Objects/Specific/Forensics/forensics.yml index a3abd4f1e3..b7627e1016 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Forensics/forensics.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Forensics/forensics.yml @@ -5,7 +5,7 @@ description: A forensic pad for collecting fingerprints or fibers. components: - type: Item - size: 3 + size: Tiny - type: ForensicPad - type: Sprite sprite: Objects/Misc/bureaucracy.rsi diff --git a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/leaves.yml b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/leaves.yml index 6da11b53fb..8e26898daa 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/leaves.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/leaves.yml @@ -63,7 +63,7 @@ tags: - Smokable - type: Item - size: 1 + size: Tiny - type: entity name: tobacco leaves @@ -121,4 +121,4 @@ tags: - Smokable - type: Item - size: 1 + size: Tiny diff --git a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml index 16d9fd1a64..af66e528c9 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml @@ -8,7 +8,7 @@ sprite: Objects/Specific/Hydroponics/seeds.rsi state: seed - type: Item - size: 2 + size: Tiny - type: StaticPrice price: 20 @@ -457,7 +457,7 @@ seedId: watermelon - type: Sprite sprite: Objects/Specific/Hydroponics/watermelon.rsi - + - type: entity parent: SeedBase name: packet of grape seeds @@ -497,4 +497,4 @@ - type: Seed seedId: bungo - type: Sprite - sprite: Objects/Specific/Hydroponics/bungo.rsi \ No newline at end of file + sprite: Objects/Specific/Hydroponics/bungo.rsi diff --git a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/tools.yml b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/tools.yml index c939cc9ca1..026c47f176 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/tools.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/tools.yml @@ -59,7 +59,7 @@ types: Slash: 10 - type: Item - size: 20 + size: Normal - type: Clothing sprite: Objects/Tools/Hydroponics/scythe.rsi slots: @@ -123,13 +123,13 @@ - type: Sprite sprite: Objects/Specific/Hydroponics/Equipment/plant_bag.rsi state: icon - - type: Item - type: Clothing quickEquip: false slots: - belt - type: Storage - capacity: 200 + maxSlots: 40 + maxItemSize: Small quickInsert: true areaInsert: true whitelist: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml index 333c17b217..d865dd172f 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml @@ -20,7 +20,7 @@ types: Blunt: 5 - type: Item - size: 15 + size: Normal sprite: Objects/Specific/Janitorial/mop.rsi - type: Absorbent - type: SolutionContainerManager @@ -59,7 +59,7 @@ types: Blunt: 5 - type: Item - size: 15 + size: Normal sprite: Objects/Specific/Janitorial/advmop.rsi - type: Absorbent pickupAmount: 100 @@ -203,7 +203,7 @@ sprite: Objects/Specific/Janitorial/wet_floor_sign.rsi - type: Item sprite: Objects/Specific/Janitorial/wet_floor_sign.rsi - size: 15 + size: Normal - type: Armor modifiers: coefficients: @@ -544,7 +544,7 @@ types: Blunt: 0 - type: Item - size: 10 + size: Small sprite: Objects/Specific/Janitorial/rag.rsi - type: Absorbent pickupAmount: 15 diff --git a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/trashbag.yml b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/trashbag.yml index 80aace05e7..da12222595 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/trashbag.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/trashbag.yml @@ -9,7 +9,8 @@ - state: icon-0 map: ["enum.StorageFillLayers.Fill"] - type: Storage - capacity: 125 + maxSlots: 20 + maxItemSize: Small quickInsert: true areaInsert: true storageOpenSound: @@ -33,7 +34,7 @@ slots: [belt] sprite: Objects/Specific/Janitorial/trashbag.rsi - type: Item - size: 125 + size: Normal - type: entity name: trash bag @@ -55,7 +56,9 @@ parent: TrashBagBlue components: - type: Storage - capacity: 125000 + maxSlots: 100 + maxItemSize: Huge + maxTotalWeight: 200 quickInsert: true areaInsert: true areaInsertRadius: 1000 diff --git a/Resources/Prototypes/Entities/Objects/Specific/Kitchen/foodcarts.yml b/Resources/Prototypes/Entities/Objects/Specific/Kitchen/foodcarts.yml index 22faf499f1..20ec7354fb 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Kitchen/foodcarts.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Kitchen/foodcarts.yml @@ -47,10 +47,9 @@ - key: enum.StorageUiKey.Key type: StorageBoundUserInterface - type: Storage - capacity: 30 - type: TileFrictionModifier - modifier: 0.4 # makes it slide - + modifier: 0.4 # makes it slide + # Add this if freezing/heating container/objects thermodynamics becomes a thing #- type: PowerCellSlot @@ -63,7 +62,7 @@ # cell_slot: # name: power-cell-slot-component-slot-name-default # startingItem: PowerCellMedium - + - type: entity name: Hot Food Cart id: FoodCartHot @@ -73,11 +72,11 @@ - type: Sprite netSync: false noRot: true - sprite: Objects/Specific/Kitchen/food_carts.rsi + sprite: Objects/Specific/Kitchen/food_carts.rsi layers: - state: stand-food - type: Storage - blacklist: + blacklist: tags: - Coldsauce - Hotsauce @@ -100,7 +99,7 @@ whitelist: tags: - Hotsauce - priority: 5 + priority: 5 bbqsauce_slot: name: BBQ Sauce insertSound: /Audio/Items/bottle_clunk.ogg @@ -108,7 +107,7 @@ whitelist: tags: - BBQsauce - priority: 4 + priority: 4 ketchup_slot: name: Ketchup insertSound: /Audio/Items/bottle_clunk.ogg @@ -116,7 +115,7 @@ whitelist: tags: - Ketchup - priority: 3 + priority: 3 - type: ItemMapper mapLayers: cart_hotsauce: @@ -154,7 +153,7 @@ - type: Sprite netSync: false noRot: true - sprite: Objects/Specific/Kitchen/food_carts.rsi + sprite: Objects/Specific/Kitchen/food_carts.rsi layers: - state: stand-ice - type: ContainerContainer diff --git a/Resources/Prototypes/Entities/Objects/Specific/Librarian/books_bag.yml b/Resources/Prototypes/Entities/Objects/Specific/Librarian/books_bag.yml index 2ad28399a6..a2675ffaaf 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Librarian/books_bag.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Librarian/books_bag.yml @@ -13,9 +13,9 @@ slots: - belt - type: Item - size: 151 + size: Huge - type: Storage - capacity: 150 + maxSlots: 15 quickInsert: true areaInsert: true whitelist: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Mech/mech_construction.yml b/Resources/Prototypes/Entities/Objects/Specific/Mech/mech_construction.yml index 678cd5ea12..a79e6e9037 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Mech/mech_construction.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Mech/mech_construction.yml @@ -44,7 +44,7 @@ abstract: true components: - type: Item - size: 50 + size: Huge - type: entity parent: BaseRipleyPart @@ -172,7 +172,7 @@ abstract: true components: - type: Item - size: 50 + size: Huge - type: entity parent: BaseHonkerPart @@ -300,7 +300,7 @@ abstract: true components: - type: Item - size: 50 + size: Large - type: entity parent: BaseHamtrPart @@ -428,7 +428,7 @@ abstract: true components: - type: Item - size: 10 + size: Small - type: entity parent: BaseVimPartItem diff --git a/Resources/Prototypes/Entities/Objects/Specific/Mech/mecha_equipment.yml b/Resources/Prototypes/Entities/Objects/Specific/Mech/mecha_equipment.yml index 8539c473b9..ac550b8e61 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Mech/mecha_equipment.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Mech/mecha_equipment.yml @@ -7,7 +7,7 @@ sprite: Objects/Specific/Mech/mecha_equipment.rsi - type: Item sprite: Objects/Specific/Mech/mecha_equipment.rsi - size: 50 + size: Huge - type: MechEquipment - type: GuideHelp guides: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/defib.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/defib.yml index a69147b610..74b0cbb0d9 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/defib.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/defib.yml @@ -28,7 +28,7 @@ True: { visible: true } False: { visible: false } - type: Item - size: 50 + size: Normal - type: ItemCooldown - type: Speech speechVerb: Robotic diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/disease.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/disease.yml index 9c67cbb28c..b85f708777 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/disease.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/disease.yml @@ -5,7 +5,7 @@ description: Used for taking and transfering samples. Sterile until open. Single use only. components: - type: Item - size: 1 + size: Tiny - type: Sprite sprite: Objects/Specific/Medical/mouth_swab.rsi state: icon @@ -26,7 +26,7 @@ description: Prevents people who DON'T already have a disease from catching it. components: - type: Item - size: 3 + size: Tiny - type: Sprite sprite: Objects/Specific/Medical/medipen.rsi state: salpen diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml index 5083ae4a44..88b7401f74 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml @@ -6,7 +6,7 @@ - type: Sprite sprite: Objects/Specific/Medical/medical.rsi - type: Item - size: 10 + size: Small sprite: Objects/Specific/Medical/medical.rsi heldPrefix: ointment # Inherited @@ -54,8 +54,6 @@ - type: Stack stackType: Ointment count: 1 - - type: Item - size: 1 - type: entity id: Ointment10Lingering @@ -105,8 +103,6 @@ - type: Stack stackType: RegenerativeMesh count: 1 - - type: Item - size: 1 - type: entity name: bruise pack @@ -144,8 +140,6 @@ - type: Stack stackType: Brutepack count: 1 - - type: Item - size: 1 - type: entity id: Brutepack10Lingering @@ -193,8 +187,6 @@ - type: Stack stackType: MedicatedSuture count: 1 - - type: Item - size: 1 - type: entity name: blood pack @@ -273,8 +265,6 @@ components: - type: Stack count: 1 - - type: Item - size: 1 - type: entity id: Gauze10Lingering @@ -338,6 +328,16 @@ - ReagentId: Dexalin Quantity: 10 +- type: entity + parent: PillCanister + id: PillCanisterDexalin + suffix: Dexalin, 7 + components: + - type: StorageFill + contents: + - id: PillDexalin + amount: 7 + - type: entity name: dylovene pill (10u) parent: Pill @@ -351,6 +351,16 @@ - ReagentId: Dylovene Quantity: 10 +- type: entity + parent: PillCanister + id: PillCanisterDylovene + suffix: Dylovene, 5 + components: + - type: StorageFill + contents: + - id: PillDylovene + amount: 5 + - type: entity name: hyronalin pill (10u) parent: Pill @@ -364,6 +374,16 @@ - ReagentId: Hyronalin Quantity: 10 +- type: entity + parent: PillCanister + id: PillCanisterHyronalin + suffix: Hyronalin, 5 + components: + - type: StorageFill + contents: + - id: PillHyronalin + amount: 5 + - type: entity name: iron pill (10u) parent: Pill @@ -377,6 +397,16 @@ - ReagentId: Iron Quantity: 10 +- type: entity + parent: PillCanister + id: PillCanisterIron + suffix: Iron, 5 + components: + - type: StorageFill + contents: + - id: PillIron + amount: 5 + - type: entity name: kelotane pill (10u) parent: Pill @@ -390,6 +420,16 @@ - ReagentId: Kelotane Quantity: 10 +- type: entity + parent: PillCanister + id: PillCanisterKelotane + suffix: Kelotane, 5 + components: + - type: StorageFill + contents: + - id: PillKelotane + amount: 5 + - type: entity name: dermaline pill (10u) parent: Pill @@ -403,6 +443,16 @@ - ReagentId: Dermaline Quantity: 10 +- type: entity + parent: PillCanister + id: PillCanisterDermaline + suffix: Dermaline, 5 + components: + - type: StorageFill + contents: + - id: PillDermaline + amount: 5 + - type: entity name: space drugs parent: Pill @@ -429,6 +479,16 @@ - ReagentId: Tricordrazine Quantity: 10 +- type: entity + parent: PillCanister + id: PillCanisterTricordrazine + suffix: Tricordrazine, 5 + components: + - type: StorageFill + contents: + - id: PillTricordrazine + amount: 5 + - type: entity name: bicaridine pill (10u) parent: Pill @@ -442,6 +502,16 @@ - ReagentId: Bicaridine Quantity: 10 +- type: entity + parent: PillCanister + id: PillCanisterBicaridine + suffix: Bicaridine, 5 + components: + - type: StorageFill + contents: + - id: PillBicaridine + amount: 5 + - type: entity name: charcoal pill (10u) parent: Pill @@ -458,6 +528,16 @@ - ReagentId: Charcoal Quantity: 10 +- type: entity + parent: PillCanister + id: PillCanisterCharcoal + suffix: Charcoal, 3 + components: + - type: StorageFill + contents: + - id: PillCharcoal + amount: 3 + - type: entity name: romerol pill parent: Pill diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml index dccbbc7328..709bc751a4 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml @@ -101,7 +101,7 @@ map: ["enum.SolutionContainerLayers.Fill"] - type: Item sprite: Objects/Specific/Medical/medipen.rsi - size: 3 + size: Tiny - type: SolutionContainerManager solutions: pen: @@ -291,7 +291,7 @@ map: ["enum.SolutionContainerLayers.Fill"] - type: Item sprite: Objects/Specific/Medical/medipen.rsi - size: 10 + size: Small - type: SolutionContainerManager solutions: pen: @@ -320,7 +320,7 @@ map: ["enum.SolutionContainerLayers.Fill"] - type: Item sprite: Objects/Specific/Medical/medipen.rsi - size: 5 + size: Tiny - type: SolutionContainerManager solutions: pen: @@ -346,7 +346,7 @@ map: ["enum.SolutionContainerLayers.Fill"] - type: Item sprite: Objects/Specific/Medical/medipen.rsi - size: 5 + size: Tiny - type: SolutionContainerManager solutions: pen: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/medkits.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/medkits.yml index 400f6670ab..3328316112 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/medkits.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/medkits.yml @@ -8,9 +8,8 @@ sprite: Objects/Specific/Medical/firstaidkits.rsi state: firstaid - type: Storage - capacity: 60 - type: Item - size: 60 + size: Normal sprite: Objects/Specific/Medical/firstaidkits.rsi heldPrefix: firstaid - type: Tag @@ -93,7 +92,5 @@ state: blackkit - type: Item heldPrefix: blackkit - size: 50 - - type: Storage - capacity: 50 + size: Normal diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml index 18e502ccdf..1ef73f2396 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml @@ -5,7 +5,7 @@ description: A plastic bag designed for the storage and transportation of cadavers. components: - type: Item - size: 6 + size: Small - type: Sprite drawdepth: SmallObjects # I guess body bags need appear above a coroner's table? sprite: Objects/Specific/Medical/Morgue/bodybags.rsi diff --git a/Resources/Prototypes/Entities/Objects/Specific/Research/rped.yml b/Resources/Prototypes/Entities/Objects/Specific/Research/rped.yml index 268a91c8de..dd9d771ebe 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Research/rped.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Research/rped.yml @@ -9,13 +9,13 @@ state: icon - type: Item sprite: Objects/Specific/Research/rped.rsi - size: 50 + size: Normal - type: GuideHelp guides: - MachineUpgrading - type: PartExchanger - type: Storage - capacity: 150 + maxSlots: 30 quickInsert: true areaInsert: true whitelist: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Salvage/ore_bag.yml b/Resources/Prototypes/Entities/Objects/Specific/Salvage/ore_bag.yml index 583aef374a..5d81dabd84 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Salvage/ore_bag.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Salvage/ore_bag.yml @@ -14,9 +14,10 @@ slots: - belt - type: Item - size: 176 + size: Huge - type: Storage - capacity: 175 + maxSlots: 12 + maxItemSize: Normal quickInsert: true areaInsert: true whitelist: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml b/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml index 6ada51176c..6abdd790c9 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml @@ -22,7 +22,7 @@ soundSwing: path: /Audio/Weapons/punchmiss.ogg - type: Item - size: 50 + size: Normal - type: Damageable damageContainer: Inorganic damageModifierSet: Metallic diff --git a/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/item_artifacts.yml b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/item_artifacts.yml index 465e1a458c..6c49fd7a5e 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/item_artifacts.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/item_artifacts.yml @@ -55,7 +55,7 @@ type: IntercomBoundUserInterface - type: Appearance - type: Item - size: 40 + size: Normal sprite: Objects/Specific/Xenoarchaeology/item_artifacts.rsi heldPrefix: ano01 - type: Actions diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml b/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml index 0e679c7096..51d705f617 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml @@ -17,7 +17,7 @@ map: [ "enum.SolutionContainerLayers.Fill" ] visible: false - type: Item - size: 20 + size: Normal sprite: Objects/Specific/Chemistry/jug.rsi - type: RefillableSolution solution: beaker diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemistry-bottles.yml b/Resources/Prototypes/Entities/Objects/Specific/chemistry-bottles.yml index da1a15e238..b869a2008f 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/chemistry-bottles.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/chemistry-bottles.yml @@ -46,7 +46,7 @@ - key: enum.TransferAmountUiKey.Key type: TransferAmountBoundUserInterface - type: Item - size: 3 + size: Tiny sprite: Objects/Specific/Chemistry/beaker.rsi - type: Spillable solution: drink diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml b/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml index bf323067ac..6ccb29f1cc 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml @@ -187,7 +187,7 @@ map: ["enum.SolutionContainerLayers.Fill"] visible: false - type: Item - size: 10 + size: Small sprite: Objects/Specific/Chemistry/beaker_large.rsi - type: SolutionContainerManager solutions: @@ -317,7 +317,7 @@ sprite: Objects/Specific/Chemistry/syringe.rsi state: "syringe_base0" - type: Item - size: 3 + size: Tiny sprite: Objects/Specific/Chemistry/syringe.rsi heldPrefix: 0 - type: SolutionContainerManager @@ -393,7 +393,7 @@ sprite: Objects/Specific/Chemistry/pills.rsi state: pill - type: Item - size: 1 + size: Tiny sprite: Objects/Specific/Chemistry/pills.rsi - type: Pill - type: Food @@ -436,18 +436,20 @@ name: pill canister id: PillCanister parent: BaseStorageItem - description: Holds up to 9 pills. + description: Holds up to 10 pills. components: - type: Sprite sprite: Objects/Specific/Chemistry/pills_canister.rsi state: pill_canister - type: Item sprite: Objects/Specific/Chemistry/pills_canister.rsi + size: Small - type: Tag tags: - PillCanister - type: Storage - capacity: 9 + maxSlots: 10 + maxTotalWeight: 10 quickInsert: true areaInsert: true areaInsertRadius: 1 diff --git a/Resources/Prototypes/Entities/Objects/Specific/syndicate.yml b/Resources/Prototypes/Entities/Objects/Specific/syndicate.yml index 81836f9c6c..aa6a64789e 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/syndicate.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/syndicate.yml @@ -10,7 +10,7 @@ state: telecrystal - type: Item sprite: Objects/Specific/Syndicate/telecrystal.rsi - size: 20 + size: Tiny - type: Stack count: 20 stackType: Telecrystal @@ -29,8 +29,6 @@ components: - type: Stack count: 1 - - type: Item - size: 1 - type: entity parent: Telecrystal @@ -39,8 +37,6 @@ components: - type: Stack count: 5 - - type: Item - size: 5 - type: entity parent: Telecrystal @@ -49,8 +45,6 @@ components: - type: Stack count: 10 - - type: Item - size: 10 # Uplinks - type: entity diff --git a/Resources/Prototypes/Entities/Objects/Tools/access_configurator.yml b/Resources/Prototypes/Entities/Objects/Tools/access_configurator.yml index c8b05c6959..7863cf8c09 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/access_configurator.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/access_configurator.yml @@ -11,7 +11,7 @@ sprite: Objects/Tools/access_configurator.rsi state: icon - type: Item - size: 5 + size: Small - type: Clothing sprite: Objects/Tools/access_configurator.rsi quickEquip: false @@ -62,12 +62,12 @@ - type: UserInterface interfaces: - key: enum.AccessOverriderUiKey.Key - type: AccessOverriderBoundUserInterface - - type: ActivatableUI + type: AccessOverriderBoundUserInterface + - type: ActivatableUI key: enum.AccessOverriderUiKey.Key - requireHands: true - closeOnHandDeselect: false - singleUser: true + requireHands: true + closeOnHandDeselect: false + singleUser: true - type: ItemSlots - type: ContainerContainer containers: diff --git a/Resources/Prototypes/Entities/Objects/Tools/bucket.yml b/Resources/Prototypes/Entities/Objects/Tools/bucket.yml index 2a5870908f..c7d62d759b 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/bucket.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/bucket.yml @@ -16,7 +16,7 @@ state: fill-1 visible: false - type: Item - size: 100 + size: Normal - type: Clothing sprite: Objects/Tools/bucket.rsi slots: diff --git a/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml b/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml index e73d80f83b..e8d95ff9cb 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml @@ -19,7 +19,7 @@ sprite: Objects/Tools/cable-coils.rsi - type: Item sprite: Objects/Tools/cable-coils.rsi - size: 30 + size: Small - type: CablePlacer - type: Clickable - type: StaticPrice @@ -62,8 +62,6 @@ state: coilhv-10 - type: Stack count: 10 - - type: Item - size: 10 - type: entity parent: CableHVStack10 @@ -83,8 +81,6 @@ state: coilhv-10 - type: Stack count: 1 - - type: Item - size: 1 - type: entity parent: CableStack @@ -121,8 +117,6 @@ state: coilmv-10 - type: Stack count: 10 - - type: Item - size: 10 - type: entity parent: CableMVStack10 @@ -142,8 +136,6 @@ state: coilmv-10 - type: Stack count: 1 - - type: Item - size: 1 - type: entity parent: CableStack @@ -179,8 +171,6 @@ state: coillv-10 - type: Stack count: 10 - - type: Item - size: 10 - type: entity parent: CableApcStack10 @@ -200,5 +190,3 @@ state: coillv-10 - type: Stack count: 1 - - type: Item - size: 1 diff --git a/Resources/Prototypes/Entities/Objects/Tools/cowtools.yml b/Resources/Prototypes/Entities/Objects/Tools/cowtools.yml index 24eb0b02b2..e6a7a43fa4 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/cowtools.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/cowtools.yml @@ -127,7 +127,7 @@ - type: Sprite sprite: Objects/Tools/Cowtools/cowelder.rsi - type: Item - size: 10 + size: Small sprite: Objects/Tools/Cowtools/cowelder.rsi - type: Tool speed: 0.05 diff --git a/Resources/Prototypes/Entities/Objects/Tools/fulton.yml b/Resources/Prototypes/Entities/Objects/Tools/fulton.yml index 8e54b4277f..612c8b93b9 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/fulton.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/fulton.yml @@ -28,7 +28,7 @@ mask: - Impassable - type: Item - size: 30 + size: Normal - type: Foldable folded: true - type: Clickable @@ -58,7 +58,7 @@ components: - type: Fulton - type: Item - size: 20 + size: Normal - type: Stack stackType: Fulton count: 10 @@ -84,7 +84,7 @@ suffix: One components: - type: Item - size: 2 + size: Small - type: Stack count: 1 diff --git a/Resources/Prototypes/Entities/Objects/Tools/gas_tanks.yml b/Resources/Prototypes/Entities/Objects/Tools/gas_tanks.yml index 09d9945213..9887d8cdc0 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/gas_tanks.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/gas_tanks.yml @@ -7,7 +7,7 @@ sprite: Objects/Tanks/generic.rsi state: icon - type: Item - size: 15 + size: Normal sprite: Objects/Tanks/generic.rsi - type: Clothing sprite: Objects/Tanks/generic.rsi @@ -100,7 +100,7 @@ - type: Sprite sprite: Objects/Tanks/emergency.rsi - type: Item - size: 10 + size: Small sprite: Objects/Tanks/emergency.rsi - type: GasTank outputPressure: 21.3 diff --git a/Resources/Prototypes/Entities/Objects/Tools/inflatable_wall.yml b/Resources/Prototypes/Entities/Objects/Tools/inflatable_wall.yml index b3d117dced..5c30cfdea3 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/inflatable_wall.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/inflatable_wall.yml @@ -13,7 +13,7 @@ state: item_wall - type: Item sprite: Objects/Misc/inflatable_wall.rsi - size: 10 + size: Small - type: SpawnAfterInteract prototype: InflatableWall doAfter: 1 @@ -39,7 +39,7 @@ state: item_door - type: Item sprite: Objects/Misc/inflatable_door.rsi - size: 4 + size: Small - type: SpawnAfterInteract prototype: InflatableDoor doAfter: 1 @@ -57,8 +57,6 @@ components: - type: Sprite state: item_wall - - type: Item - size: 5 - type: Stack count: 5 @@ -69,8 +67,6 @@ components: - type: Sprite state: item_wall - - type: Item - size: 1 - type: Stack count: 1 @@ -81,7 +77,5 @@ components: - type: Sprite state: item_door - - type: Item - size: 1 - type: Stack count: 1 diff --git a/Resources/Prototypes/Entities/Objects/Tools/jaws_of_life.yml b/Resources/Prototypes/Entities/Objects/Tools/jaws_of_life.yml index 36f96f61af..31d852354b 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/jaws_of_life.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/jaws_of_life.yml @@ -11,7 +11,7 @@ sprite: Objects/Tools/jaws_of_life.rsi state: jaws_pry - type: Item - size: 50 + size: Normal - type: Clothing sprite: Objects/Tools/jaws_of_life.rsi quickEquip: false @@ -61,7 +61,7 @@ sprite: Objects/Tools/jaws_of_life.rsi state: syn_jaws_pry - type: Item - size: 35 + size: Normal - type: Tool qualities: - Prying diff --git a/Resources/Prototypes/Entities/Objects/Tools/jetpacks.yml b/Resources/Prototypes/Entities/Objects/Tools/jetpacks.yml index b87bbae0d8..d63225b2bd 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/jetpacks.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/jetpacks.yml @@ -37,7 +37,7 @@ state: icon - type: Item sprite: Objects/Tanks/Jetpacks/blue.rsi - size: 100 + size: Large - type: UserInterface interfaces: - key: enum.SharedGasTankUiKey.Key @@ -153,7 +153,7 @@ - Back - type: Item sprite: Objects/Tanks/Jetpacks/captain.rsi - size: 30 + size: Normal - type: Tag tags: - HighRiskItem diff --git a/Resources/Prototypes/Entities/Objects/Tools/lighters.yml b/Resources/Prototypes/Entities/Objects/Tools/lighters.yml index e3422f2a4a..a3b6b3fd6e 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/lighters.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/lighters.yml @@ -40,7 +40,7 @@ visible: false - state: basic_icon_top - type: Item - size: 1 + size: Tiny sprite: Objects/Tools/lighters.rsi heldPrefix: off - type: ItemCooldown diff --git a/Resources/Prototypes/Entities/Objects/Tools/matches.yml b/Resources/Prototypes/Entities/Objects/Tools/matches.yml index fd7e185cb0..98affd271c 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/matches.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/matches.yml @@ -4,9 +4,10 @@ abstract: true components: - type: Storage - capacity: 10 + maxSlots: 7 + maxTotalWeight: 14 - type: Item - size: 10 + size: Small - type: entity name: match stick @@ -26,7 +27,7 @@ - type: Item sprite: Objects/Tools/matches.rsi heldPrefix: unlit - size: 1 + size: Tiny - type: Matchstick duration: 10 igniteSound: @@ -80,9 +81,10 @@ - type: Item sprite: Objects/Tools/matches.rsi heldPrefix: matchbox - size: 5 + size: Small - type: Storage - capacity: 5 + maxSlots: 5 + maxTotalWeight: 5 - type: StorageFill contents: - id: Matchstick diff --git a/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml b/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml index e9f0526796..8a1c33df76 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml @@ -8,9 +8,11 @@ sound: path: /Audio/Items/toolbox_drop.ogg - type: Storage - capacity: 60 + maxSlots: 7 + maxItemSize: Normal + maxTotalWeight: 14 - type: Item - size: 9999 + size: Huge - type: ItemCooldown - type: MeleeWeapon damage: @@ -114,7 +116,8 @@ - type: Item sprite: Objects/Tools/Toolboxes/toolbox_syn.rsi - type: Storage - capacity: 170 # this seems silly high + maxItemSize: Large + maxTotalWeight: 28 - type: MeleeWeapon damage: types: diff --git a/Resources/Prototypes/Entities/Objects/Tools/tools.yml b/Resources/Prototypes/Entities/Objects/Tools/tools.yml index 12a6ede231..566c72dafd 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/tools.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/tools.yml @@ -140,7 +140,7 @@ state: icon - type: Item sprite: Objects/Tools/crowbar.rsi - size: 10 + size: Small - type: ItemCooldown - type: MeleeWeapon wideAnimationRotation: -135 @@ -191,7 +191,7 @@ - state: green-unlit shader: unshaded - type: Item - size: 5 + size: Small - type: Clothing sprite: Objects/Tools/multitool.rsi quickEquip: false @@ -240,7 +240,7 @@ map: ["enum.NetworkConfiguratorLayers.ModeLight"] shader: unshaded - type: Item - size: 5 + size: Small - type: Clothing sprite: Objects/Tools/network_configurator.rsi quickEquip: false @@ -290,7 +290,7 @@ state: drill_screw - type: Item sprite: Objects/Tools/drill.rsi - size: 10 + size: Small - type: Tool qualities: - Screwing @@ -346,7 +346,7 @@ sprite: Objects/Tools/rcd.rsi state: icon - type: Item - size: 20 + size: Normal - type: Clothing sprite: Objects/Tools/rcd.rsi quickEquip: false @@ -422,7 +422,7 @@ state: omnitool-screwing - type: Item sprite: Objects/Tools/omnitool.rsi - size: 20 + size: Normal - type: Tag tags: - Multitool @@ -497,7 +497,7 @@ types: Blunt: 14 - type: Item - size: 90 + size: Normal sprite: Objects/Tools/shovel.rsi - type: PhysicalComposition materialComposition: @@ -517,7 +517,7 @@ state: icon - type: Item sprite: Objects/Tools/rolling_pin.rsi - size: 10 + size: Small - type: Clothing sprite: Objects/Tools/rolling_pin.rsi quickEquip: false diff --git a/Resources/Prototypes/Entities/Objects/Tools/welders.yml b/Resources/Prototypes/Entities/Objects/Tools/welders.yml index 7c3de82d0a..caa0d4c208 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/welders.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/welders.yml @@ -17,7 +17,7 @@ shader: unshaded visible: false - type: Item - size: 10 + size: Small sprite: Objects/Tools/welder.rsi - type: ToggleableLightVisuals spriteLayer: flame @@ -142,7 +142,7 @@ - type: Sprite sprite: Objects/Tools/welder_mini.rsi - type: Item - size: 5 + size: Tiny sprite: Objects/Tools/welder_mini.rsi - type: RefillableSolution solution: Welder diff --git a/Resources/Prototypes/Entities/Objects/Vehicles/keys.yml b/Resources/Prototypes/Entities/Objects/Vehicles/keys.yml index f361c2b877..468f1aa3a5 100644 --- a/Resources/Prototypes/Entities/Objects/Vehicles/keys.yml +++ b/Resources/Prototypes/Entities/Objects/Vehicles/keys.yml @@ -5,7 +5,7 @@ description: Interesting design. components: - type: Item - size: 2 + size: Tiny - type: Tag tags: - VehicleKey diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/funny.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/funny.yml index c33c1f92c5..84883c975d 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/funny.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/funny.yml @@ -12,7 +12,7 @@ map: ["base"] - type: Item sprite: Objects/Weapons/Bombs/hot_potato.rsi - size: 5 + size: Small - type: AmbientSound enabled: false range: 8 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/plastic.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/plastic.yml index 4d9fed1f91..e3581370f0 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/plastic.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/plastic.yml @@ -12,7 +12,7 @@ map: ["base"] - type: Item sprite: Objects/Weapons/Bombs/c4.rsi - size: 10 + size: Small - type: OnUseTimerTrigger delay: 10 delayOptions: [10, 30, 60, 120, 300] diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/spider.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/spider.yml index 50a7ea8687..8f997b7687 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/spider.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/spider.yml @@ -10,7 +10,7 @@ state: icon - type: Item sprite: Objects/Weapons/Bombs/spidercharge.rsi - size: 10 + size: Small - type: SpiderCharge - type: OnUseTimerTrigger delay: 10 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/antimateriel.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/antimateriel.yml index c7980f845f..28157ef345 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/antimateriel.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/antimateriel.yml @@ -12,7 +12,7 @@ proto: CartridgeAntiMateriel capacity: 10 - type: Item - size: 5 + size: Small - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/caseless_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/caseless_rifle.yml index 4a77bfcfc5..063268d8b5 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/caseless_rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/caseless_rifle.yml @@ -12,7 +12,7 @@ proto: CartridgeCaselessRifle capacity: 60 - type: Item - size: 5 + size: Small - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/light_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/light_rifle.yml index 1c8fbc26e1..0751d3608c 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/light_rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/light_rifle.yml @@ -12,7 +12,7 @@ proto: CartridgeLightRifle capacity: 50 - type: Item - size: 5 + size: Small - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/magnum.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/magnum.yml index 5a9a850e9c..1ff05558e5 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/magnum.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/magnum.yml @@ -11,7 +11,7 @@ proto: CartridgeMagnum capacity: 60 - type: Item - size: 5 + size: Small - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/pistol.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/pistol.yml index a9a78f399a..867aa15a34 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/pistol.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/pistol.yml @@ -12,7 +12,7 @@ proto: CartridgePistol capacity: 60 - type: Item - size: 5 + size: Small - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/rifle.yml index 3725ad91af..5ed2fcc63e 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/rifle.yml @@ -11,7 +11,7 @@ proto: CartridgeRifle capacity: 60 - type: Item - size: 5 + size: Small - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/base_cartridge.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/base_cartridge.yml index de6f9f92a5..1831db28e7 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/base_cartridge.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/base_cartridge.yml @@ -20,7 +20,7 @@ tags: - Cartridge - type: Item - size: 1 + size: Tiny - type: SpaceGarbage - type: EmitSoundOnLand sound: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/caseless_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/caseless_rifle.yml index 773ff01ed8..0d16f1e966 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/caseless_rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/caseless_rifle.yml @@ -15,7 +15,7 @@ proto: CartridgeCaselessRifle capacity: 30 - type: Item - size: 5 + size: Small - type: ContainerContainer containers: ballistic-ammo: !type:Container @@ -42,7 +42,7 @@ proto: CartridgeCaselessRifle capacity: 10 - type: Item - size: 3 + size: Tiny - type: Sprite sprite: Objects/Weapons/Guns/Ammunition/Magazine/CaselessRifle/caseless_rifle_mag_short.rsi layers: @@ -67,7 +67,7 @@ proto: CartridgeCaselessRifle capacity: 10 - type: Item - size: 5 + size: Small - type: Sprite sprite: Objects/Weapons/Guns/Ammunition/Magazine/CaselessRifle/caseless_pistol_mag.rsi layers: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/heavy_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/heavy_rifle.yml index 239533c940..d8af7064a4 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/heavy_rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/heavy_rifle.yml @@ -8,7 +8,7 @@ tags: - MagazineHeavyRifle - type: Item - size: 10 + size: Small - type: BallisticAmmoProvider mayTransfer: true capacity: 100 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/light_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/light_rifle.yml index e586364369..7ae4f32524 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/light_rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/light_rifle.yml @@ -16,7 +16,7 @@ proto: CartridgeLightRifle capacity: 30 - type: Item - size: 5 + size: Small - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/magnum.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/magnum.yml index 6060898d49..b65dac5d15 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/magnum.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/magnum.yml @@ -14,7 +14,7 @@ - CartridgeMagnum capacity: 25 - type: Item - size: 10 + size: Small - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/pistol.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/pistol.yml index 4ed38fdeb3..8793a717e7 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/pistol.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/pistol.yml @@ -14,7 +14,7 @@ - CartridgePistol capacity: 10 - type: Item - size: 5 + size: Small - type: ContainerContainer containers: ballistic-ammo: !type:Container @@ -47,7 +47,7 @@ - CartridgePistol capacity: 16 - type: Item - size: 5 + size: Small - type: ContainerContainer containers: ballistic-ammo: !type:Container @@ -80,7 +80,7 @@ - CartridgePistol capacity: 35 - type: Item - size: 10 + size: Small - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/rifle.yml index ca1f9b8de2..8e65cd992e 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/rifle.yml @@ -9,7 +9,7 @@ tags: - MagazineRifle - type: Item - size: 5 + size: Small - type: BallisticAmmoProvider mayTransfer: true whitelist: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/shotgun.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/shotgun.yml index b78825f3e1..cbe9bbfbe9 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/shotgun.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/shotgun.yml @@ -16,7 +16,7 @@ soundRack: path: /Audio/Weapons/Guns/Cock/smg_cock.ogg - type: Item - size: 5 + size: Small - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/explosives.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/explosives.yml index 56d420cb33..86da8e6662 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/explosives.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/explosives.yml @@ -10,7 +10,7 @@ tags: - CartridgeRocket - type: Item - size: 5 + size: Small - type: CartridgeAmmo proto: BulletRocket deleteOnSpawn: true @@ -30,7 +30,7 @@ tags: - CartridgeRocket - type: Item - size: 5 + size: Small - type: CartridgeAmmo proto: BulletWeakRocket deleteOnSpawn: true @@ -52,7 +52,7 @@ tags: - Grenade - type: Item - size: 5 + size: Small - type: Sprite - type: entity diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_pka.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_pka.yml index 041cf446c1..f85e93b893 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_pka.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_pka.yml @@ -7,7 +7,7 @@ sprite: Objects/Weapons/Guns/Basic/kinetic_accelerator.rsi - type: Item sprite: Objects/Weapons/Guns/Basic/kinetic_accelerator.rsi - size: 30 + size: Normal - type: GunWieldBonus minAngle: -43 maxAngle: -43 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_staff.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_staff.yml index 76bd0b9e75..9cab4cac25 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_staff.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_staff.yml @@ -7,7 +7,7 @@ sprite: Objects/Weapons/Guns/Basic/staves.rsi - type: Item heldPrefix: staff - size: 60 + size: Normal - type: Gun fireRate: 1 selectedMode: SemiAuto diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_wand.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_wand.yml index 3b97eac8ee..c4a937ee2c 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_wand.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_wand.yml @@ -7,7 +7,7 @@ sprite: Objects/Weapons/Guns/Basic/wands.rsi - type: Item heldPrefix: wand - size: 30 + size: Normal - type: Gun fireRate: 0.5 selectedMode: SemiAuto diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/spraynozzle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/spraynozzle.yml index d4d00252f5..f2e93a607e 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/spraynozzle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/spraynozzle.yml @@ -9,7 +9,7 @@ state: icon - type: Item sprite: Objects/Weapons/Guns/Basic/spraynozzle.rsi - size: 30 + size: Normal - type: Gun cameraRecoilScalar: 0 #no recoil fireRate: 4 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/watergun.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/watergun.yml index a815f9c0cd..e925bdab87 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/watergun.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/watergun.yml @@ -10,7 +10,7 @@ slots: BELT - type: Item sprite: Objects/Weapons/Guns/Pistols/water_pistol.rsi - size: 10 + size: Small - type: Gun clumsyProof: true cameraRecoilScalar: 0 #no recoil @@ -95,7 +95,7 @@ map: [ "enum.DamageStateVisualLayers.Base" ] - type: Item sprite: Objects/Weapons/Guns/Pistols/soaker.rsi - size: 35 + size: Normal - type: RandomSprite getAllGroups: true available: @@ -132,7 +132,7 @@ map: [ "enum.DamageStateVisualLayers.Base" ] - type: Item sprite: Objects/Weapons/Guns/Pistols/soaker.rsi - size: 35 + size: Normal - type: RandomSprite getAllGroups: true available: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml index 461a6cc437..d4b9142504 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml @@ -5,7 +5,7 @@ components: - type: Sprite - type: Item - size: 50 + size: Large - type: Clothing sprite: Objects/Weapons/Guns/Battery/laser_retro.rsi quickEquip: false @@ -37,7 +37,7 @@ abstract: true components: - type: Item - size: 10 + size: Small - type: Tag tags: - Sidearm @@ -408,7 +408,7 @@ description: An experimental high-energy laser pistol with a self-charging nuclear battery. components: - type: Item - size: 30 # Intentionally larger than other pistols + size: Normal # Intentionally larger than other pistols - type: Sprite sprite: Objects/Weapons/Guns/Battery/advancedlasergun.rsi layers: @@ -464,7 +464,7 @@ path: /Audio/Weapons/Guns/Gunshots/taser2.ogg - type: ProjectileBatteryAmmoProvider proto: AnomalousParticleDeltaStrong - fireCost: 100 + fireCost: 100 - type: BatteryWeaponFireModes fireModes: - proto: AnomalousParticleDeltaStrong @@ -476,13 +476,13 @@ - type: Construction graph: UpgradeWeaponPistolCHIMP node: start - + - type: entity name: experimental C.H.I.M.P. handcannon parent: WeaponPistolCHIMP id: WeaponPistolCHIMPUpgraded description: This C.H.I.M.P. seems to have a greater punch than is usual... - components: + components: - type: BatteryWeaponFireModes fireModes: - proto: AnomalousParticleDeltaStrong @@ -490,7 +490,7 @@ - proto: AnomalousParticleEpsilonStrong fireCost: 100 - proto: AnomalousParticleOmegaStrong - fireCost: 100 + fireCost: 100 - proto: AnomalousParticleZetaStrong fireCost: 100 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Bow/bow.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Bow/bow.yml index 88640f7812..4b7125f571 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Bow/bow.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Bow/bow.yml @@ -8,7 +8,7 @@ - type: Sprite sprite: Objects/Weapons/Guns/Bow/bow.rsi - type: Item - size: 60 + size: Normal - type: Clothing quickEquip: false slots: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/HMGs/hmgs.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/HMGs/hmgs.yml index 785b36cc62..1b318beac8 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/HMGs/hmgs.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/HMGs/hmgs.yml @@ -7,6 +7,7 @@ components: - type: Sprite - type: Item + size: Huge - type: Gun fireRate: 20 selectedMode: FullAuto @@ -33,7 +34,6 @@ map: ["enum.GunVisualLayers.Base"] - type: Item sprite: Objects/Weapons/Guns/HMGs/minigun.rsi - size: 90 - type: Gun fireRate: 15 soundGunshot: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml index 62142519bf..3d6cd680a0 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml @@ -7,7 +7,7 @@ components: - type: Sprite - type: Item - size: 60 + size: Large - type: Clothing sprite: Objects/Weapons/Guns/LMGs/l6.rsi quickEquip: false diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml index 3796ac92b8..2dbf71840c 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml @@ -12,7 +12,7 @@ slots: - Back - type: Item - size: 60 + size: Large - type: StaticPrice price: 500 - type: ContainerContainer diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml index 7bfd914d94..a6c6f1e677 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml @@ -12,7 +12,7 @@ - state: mag-0 map: ["enum.GunVisualLayers.Mag"] - type: Item - size: 10 + size: Small - type: Tag tags: - Sidearm diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml index 32a2ea4623..8dbcf2b303 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml @@ -4,7 +4,7 @@ abstract: true components: - type: Item - size: 10 + size: Small - type: Sprite sprite: Objects/Weapons/Guns/Projectiles/arrows.rsi - type: Fixtures diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Revolvers/revolvers.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Revolvers/revolvers.yml index 1851dcddf6..c523fd2797 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Revolvers/revolvers.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Revolvers/revolvers.yml @@ -8,7 +8,7 @@ - type: Sprite state: icon - type: Item - size: 10 + size: Small - type: Tag tags: - Sidearm @@ -122,7 +122,7 @@ params: volume: 2.25 -- type: entity +- type: entity name: Python parent: WeaponRevolverPython id: WeaponRevolverPythonAP # For the uplink. @@ -155,4 +155,4 @@ - type: RevolverAmmoProvider capacity: 5 chambers: [ True, True, True, True, True ] - ammoSlots: [ null, null, null, null, null ] \ No newline at end of file + ammoSlots: [ null, null, null, null, null ] diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml index 114573c087..d460c0c8f0 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml @@ -7,7 +7,7 @@ components: - type: Sprite - type: Item - size: 50 + size: Large - type: Clothing sprite: Objects/Weapons/Guns/Rifles/ak.rsi quickEquip: false diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml index e423c09841..6bf6fcf695 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml @@ -7,7 +7,7 @@ components: - type: Sprite - type: Item - size: 30 + size: Normal - type: Clothing sprite: Objects/Weapons/Guns/SMGs/atreides.rsi quickEquip: false diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml index 4bee243d57..5a08eb3636 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml @@ -11,7 +11,7 @@ map: [ "enum.GunVisualLayers.Base" ] - type: Item # If you update this also update the bulldog's size. - size: 30 + size: Large - type: Clothing sprite: Objects/Weapons/Guns/Shotguns/db_shotgun.rsi quickEquip: false @@ -57,8 +57,6 @@ map: ["enum.GunVisualLayers.Base"] - state: mag-0 map: ["enum.GunVisualLayers.Mag"] - - type: Item - size: 30 - type: Clothing sprite: Objects/Weapons/Guns/Shotguns/bulldog.rsi quickEquip: false @@ -137,7 +135,7 @@ - type: Clothing sprite: Objects/Weapons/Guns/Shotguns/enforcer.rsi - type: BallisticAmmoProvider - + - type: entity name: Enforcer parent: BaseWeaponShotgun @@ -151,7 +149,7 @@ sprite: Objects/Weapons/Guns/Shotguns/enforcer.rsi - type: BallisticAmmoProvider proto: ShellShotgunBeanbag - + - type: entity name: Kammerer parent: BaseWeaponShotgun @@ -162,6 +160,8 @@ sprite: Objects/Weapons/Guns/Shotguns/pump.rsi - type: Clothing sprite: Objects/Weapons/Guns/Shotguns/pump.rsi + - type: Item + size: Normal - type: BallisticAmmoProvider capacity: 4 @@ -176,7 +176,7 @@ - type: Clothing sprite: Objects/Weapons/Guns/Shotguns/sawn.rsi - type: Item - size: 10 + size: Small - type: Gun fireRate: 4 - type: BallisticAmmoProvider @@ -210,8 +210,6 @@ sprite: Objects/Weapons/Guns/Shotguns/hm_pistol.rsi - type: Clothing sprite: Objects/Weapons/Guns/Shotguns/hm_pistol.rsi - - type: Item - size: 10 - type: Gun fireRate: 4 - type: BallisticAmmoProvider @@ -245,8 +243,6 @@ sprite: Objects/Weapons/Guns/Shotguns/improvised_shotgun.rsi - type: Clothing sprite: Objects/Weapons/Guns/Shotguns/improvised_shotgun.rsi - - type: Item - size: 75 - type: Gun fireRate: 4 #No reason to stifle the firerate since you have to manually reload every time anyways. - type: BallisticAmmoProvider diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml index 68c494b888..4a16aadb65 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml @@ -10,7 +10,7 @@ - state: base map: ["enum.GunVisualLayers.Base"] - type: Item - size: 50 + size: Large - type: Clothing sprite: Objects/Weapons/Guns/Snipers/bolt_gun_wood.rsi quickEquip: false diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/flare_gun.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/flare_gun.yml index d41346380c..cfcc0a01cd 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/flare_gun.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/flare_gun.yml @@ -10,7 +10,7 @@ - state: icon map: ["enum.GunVisualLayers.Base"] - type: Item - size: 10 + size: Small sprite: Objects/Weapons/Guns/Shotguns/flaregun.rsi - type: Gun fireRate: 8 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/pneumatic_cannon.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/pneumatic_cannon.yml index 9f3aec5c39..fcd028a64e 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/pneumatic_cannon.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/pneumatic_cannon.yml @@ -12,7 +12,7 @@ map: [ "tank" ] visible: false - type: Item - size: 50 + size: Large - type: Clothing quickEquip: false slots: @@ -32,7 +32,9 @@ container: storagebase - type: PneumaticCannon - type: Storage - capacity: 30 + maxSlots: 8 + maxItemSize: Normal + maxTotalWeight: 32 blacklist: tags: - CannonRestrict @@ -75,10 +77,12 @@ layers: - state: piecannon - type: Storage + maxSlots: 8 + maxItemSize: Normal + maxTotalWeight: 32 whitelist: components: - CreamPie - capacity: 40 - type: Gun fireRate: 1 selectedMode: SemiAuto @@ -93,7 +97,7 @@ - type: ContainerAmmoProvider container: storagebase - type: Item - size: 50 + size: Normal - type: Clothing sprite: Objects/Weapons/Guns/Cannons/pie_cannon.rsi quickEquip: false @@ -120,9 +124,13 @@ suffix: Admeme components: - type: Item - size: 9999 + size: Huge - type: Storage - capacity: 9999 + maxSlots: 100 + maxItemSize: Huge + maxTotalWeight: 1600 + whitelist: + tags: [] #dodging a test fail like the IRS - type: PneumaticCannon gasUsage: 0 throwItems: false diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/armblade.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/armblade.yml index 9e9288c8d4..497876f359 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/armblade.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/armblade.yml @@ -16,7 +16,7 @@ Slash: 25 Piercing: 15 - type: Item - size: 15 + size: Normal sprite: Objects/Weapons/Melee/armblade.rsi - type: Tool qualities: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/baseball_bat.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/baseball_bat.yml index c1fc668d59..a1a4f484fa 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/baseball_bat.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/baseball_bat.yml @@ -18,7 +18,7 @@ types: Blunt: 8 - type: Item - size: 80 + size: Normal - type: Tool qualities: - Rolling diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/chainsaw.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/chainsaw.yml index 13f5191c10..bfddd764ca 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/chainsaw.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/chainsaw.yml @@ -31,7 +31,7 @@ Blunt: 5 Structural: 20 - type: Item - size: 50 + size: Normal sprite: Objects/Weapons/Melee/chainsaw.rsi - type: DisarmMalus - type: RefillableSolution diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/cult.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/cult.yml index 661ee379b2..ff80144f9f 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/cult.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/cult.yml @@ -15,7 +15,7 @@ types: Slash: 12 - type: Item - size: 20 + size: Normal - type: Clothing sprite: Objects/Weapons/Melee/cult_dagger.rsi slots: @@ -39,7 +39,7 @@ types: Slash: 33 - type: Item - size: 20 + size: Normal - type: Clothing sprite: Objects/Weapons/Melee/cult_blade.rsi slots: @@ -75,7 +75,7 @@ Slash: 12 Structural: 30 - type: Item - size: 150 + size: Huge - type: Clothing sprite: Objects/Weapons/Melee/cult_halberd.rsi quickEquip: false diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml index 47dfea9d86..c00fd1ab86 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml @@ -30,7 +30,7 @@ types: Blunt: 4.5 - type: Item - size: 5 + size: Small sprite: Objects/Weapons/Melee/e_sword.rsi - type: UseDelay delay: 1.0 @@ -95,7 +95,7 @@ types: Blunt: 1 - type: Item - size: 2 + size: Tiny sprite: Objects/Weapons/Melee/e_dagger.rsi - type: UseDelay delay: 1.0 @@ -161,7 +161,7 @@ shader: unshaded map: [ "blade" ] - type: Item - size: 5 + size: Small sprite: Objects/Weapons/Melee/e_cutlass.rsi - type: entity @@ -198,7 +198,7 @@ shader: unshaded map: [ "blade" ] - type: Item - size: 10 + size: Small sprite: Objects/Weapons/Melee/e_sword_double.rsi - type: Reflect enabled: true diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/fireaxe.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/fireaxe.yml index 6d27e3e7d6..1c786371b3 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/fireaxe.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/fireaxe.yml @@ -29,7 +29,7 @@ Slash: 10.5 Structural: 60 - type: Item - size: 150 + size: Huge - type: Clothing sprite: Objects/Weapons/Melee/fireaxe.rsi quickEquip: false diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/gohei.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/gohei.yml index 9e673da49d..ec9717ea22 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/gohei.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/gohei.yml @@ -13,5 +13,5 @@ types: Blunt: 3 #You'd be better off punching people - type: Item - size: 12 + size: Small sprite: Objects/Weapons/Melee/gohei.rsi diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml index bbd18927e1..98ecaa28a6 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml @@ -37,10 +37,9 @@ - Knife - type: Sprite sprite: Objects/Weapons/Melee/kitchen_knife.rsi - size: 2 state: icon - type: Item - size: 10 + size: Small sprite: Objects/Weapons/Melee/kitchen_knife.rsi - type: GuideHelp guides: @@ -57,7 +56,6 @@ - Knife - type: Sprite sprite: Objects/Weapons/Melee/cleaver.rsi - size: 4 state: butch - type: MeleeWeapon wideAnimationRotation: -135 @@ -66,7 +64,7 @@ types: Slash: 10 - type: Item - size: 10 + size: Small sprite: Objects/Weapons/Melee/cleaver.rsi - type: GuideHelp guides: @@ -84,7 +82,7 @@ - Knife - type: Sprite sprite: Objects/Weapons/Melee/combat_knife.rsi - size: 2 + size: Tiny state: icon - type: MeleeWeapon wideAnimationRotation: -135 @@ -93,7 +91,7 @@ types: Slash: 10 - type: Item - size: 10 + size: Small sprite: Objects/Weapons/Melee/combat_knife.rsi - type: DisarmMalus malus: 0.225 @@ -106,10 +104,10 @@ components: - type: Sprite sprite: Objects/Weapons/Melee/survival_knife.rsi - size: 2 + size: Tiny state: icon - type: Item - size: 10 + size: Small sprite: Objects/Weapons/Melee/survival_knife.rsi - type: entity @@ -120,7 +118,7 @@ components: - type: Sprite sprite: Objects/Weapons/Melee/kukri_knife.rsi - size: 2 + size: Tiny state: icon - type: MeleeWeapon attackRate: 1.0 @@ -128,7 +126,7 @@ types: Slash: 15 - type: Item - size: 10 + size: Small sprite: Objects/Weapons/Melee/kukri_knife.rsi - type: entity @@ -147,7 +145,7 @@ node: icon - type: Sprite sprite: Objects/Weapons/Melee/shiv.rsi - size: 2 + size: Tiny state: icon - type: MeleeWeapon attackRate: 1.5 @@ -155,7 +153,7 @@ types: Slash: 5.5 - type: Item - size: 4 #as much as a regular glass shard + size: Tiny #as much as a regular glass shard sprite: Objects/Weapons/Melee/shiv.rsi - type: DisarmMalus malus: 0.225 @@ -169,7 +167,7 @@ - type: Construction graph: ReinforcedShiv node: icon - size: 2 + size: Tiny state: icon - type: MeleeWeapon attackRate: 1.5 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/mining.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/mining.yml index f3bb0ceec9..e5046d5c1f 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/mining.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/mining.yml @@ -57,7 +57,7 @@ Slash: 2.5 - type: GunRequiresWield - type: Item - size: 150 + size: Huge - type: DisarmMalus - type: Tool qualities: @@ -80,7 +80,7 @@ types: Slash: 6.5 - type: Item - size: 10 + size: Small - type: Tag tags: - Knife @@ -112,4 +112,4 @@ wideAnimationRotation: -135 attackRate: 1.25 - type: Item - size: 150 + size: Huge diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/needle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/needle.yml index 48b2d6ad2b..11efeba5f8 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/needle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/needle.yml @@ -13,5 +13,5 @@ types: Piercing: 1 - type: Item - size: 1 + size: Tiny - type: BalloonPopper diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/pickaxe.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/pickaxe.yml index a0f497bd26..85f1e4a4c7 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/pickaxe.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/pickaxe.yml @@ -26,7 +26,7 @@ types: Structural: 10 - type: Item - size: 80 + size: Normal sprite: Objects/Weapons/Melee/pickaxe.rsi - type: UseDelay delay: 1 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml index d34d29d5eb..037844507f 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml @@ -47,7 +47,7 @@ types: Piercing: 15 - type: Item - size: 95 + size: Huge - type: Clothing quickEquip: false slots: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml index 25c9cf6125..87b7c468c3 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml @@ -26,7 +26,7 @@ - type: ItemCooldown - type: Item heldPrefix: off - size: 100 + size: Large - type: Clothing sprite: Objects/Weapons/Melee/stunprod.rsi quickEquip: false diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml index 23160f13ea..9bd9d6c12f 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml @@ -21,7 +21,7 @@ reflectProb: .5 spread: 90 - type: Item - size: 15 + size: Normal sprite: Objects/Weapons/Melee/captain_sabre.rsi - type: Tag tags: @@ -49,7 +49,7 @@ soundHit: path: /Audio/Weapons/bladeslice.ogg - type: Item - size: 15 + size: Normal sprite: Objects/Weapons/Melee/katana.rsi - type: DisarmMalus @@ -68,7 +68,7 @@ types: Slash: 30 - type: Item - size: 15 + size: Normal sprite: Objects/Weapons/Melee/energykatana.rsi - type: EnergyKatana - type: DashAbility @@ -105,7 +105,7 @@ soundHit: path: /Audio/Weapons/bladeslice.ogg - type: Item - size: 15 + size: Normal sprite: Objects/Weapons/Melee/machete.rsi - type: DisarmMalus @@ -128,7 +128,7 @@ soundHit: path: /Audio/Weapons/bladeslice.ogg - type: Item - size: 20 + size: Normal - type: Clothing sprite: Objects/Weapons/Melee/claymore.rsi slots: @@ -156,6 +156,6 @@ soundHit: path: /Audio/Weapons/bladeslice.ogg - type: Item - size: 15 + size: Normal sprite: Objects/Weapons/Melee/cutlass.rsi - type: DisarmMalus diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/weapon_toolbox.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/weapon_toolbox.yml index b5f8590304..e5a03d5136 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/weapon_toolbox.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/weapon_toolbox.yml @@ -9,7 +9,7 @@ sprite: Objects/Tools/Toolboxes/toolbox_red.rsi state: icon - type: Item - size: 150 + size: Huge sprite: Objects/Tools/Toolboxes/toolbox_red.rsi - type: MeleeWeapon wideAnimationRotation: -135 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/white_cane.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/white_cane.yml index c76ebf4d78..997c3771d5 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/white_cane.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/white_cane.yml @@ -8,7 +8,7 @@ sprite: Objects/Weapons/Melee/white_cane.rsi state: icon - type: Item - size: 15 + size: Normal sprite: Objects/Weapons/Melee/white_cane.rsi - type: MeleeWeapon wideAnimationRotation: 45 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml index 1afb564036..f694762a09 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml @@ -5,7 +5,7 @@ description: Linked together with some spare cuffs and metal. components: - type: Item - size: 20 + size: Normal - type: Sprite sprite: Objects/Weapons/Throwable/bola.rsi state: icon diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml index 9f18b94d2c..ece4ec4ef4 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml @@ -9,7 +9,7 @@ - state: icon map: ["enum.TriggerVisualLayers.Base"] - type: Item - size: 5 + size: Small - type: Clothing quickEquip: false slots: @@ -267,7 +267,7 @@ - state: empty map: [ "enum.ConstructionVisuals.Layer" ] - type: Item - size: 8 + size: Small - type: PayloadCase - type: Construction graph: ModularGrenadeGraph diff --git a/Resources/Prototypes/Entities/Objects/Weapons/security.yml b/Resources/Prototypes/Entities/Objects/Weapons/security.yml index 92e7dbd4c1..bf4a155ee4 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/security.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/security.yml @@ -31,7 +31,7 @@ - type: ItemCooldown - type: Item heldPrefix: off - size: 20 + size: Normal - type: Clothing sprite: Objects/Weapons/Melee/stunbaton.rsi quickEquip: false @@ -81,7 +81,7 @@ Blunt: 20 bluntStaminaDamageFactor: 1.5 - type: Item - size: 20 + size: Normal - type: Clothing sprite: Objects\Weapons\Melee\truncheon.rsi quickEquip: false @@ -122,7 +122,7 @@ Blunt: 0 # melee weapon to allow flashing individual targets angle: 10 - type: Item - size: 5 + size: Small sprite: Objects/Weapons/Melee/flash.rsi - type: ItemCooldown - type: StaticPrice diff --git a/Resources/Prototypes/Entities/Objects/base_item.yml b/Resources/Prototypes/Entities/Objects/base_item.yml index 32325603c1..bcc8e0dce4 100644 --- a/Resources/Prototypes/Entities/Objects/base_item.yml +++ b/Resources/Prototypes/Entities/Objects/base_item.yml @@ -4,7 +4,7 @@ abstract: true components: - type: Item - size: 5 + size: Small - type: Clickable - type: InteractionOutline - type: MovedByPressure diff --git a/Resources/Prototypes/Entities/Structures/Furniture/bookshelf.yml b/Resources/Prototypes/Entities/Structures/Furniture/bookshelf.yml index 9f1de3ff39..6d5e0e3dcd 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/bookshelf.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/bookshelf.yml @@ -47,7 +47,8 @@ - type: Pullable - type: Occluder - type: Storage - capacity: 200 + maxSlots: 32 + maxItemSize: Normal whitelist: tags: - Document diff --git a/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml b/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml index aaff4e1e28..8d669ab6d2 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml @@ -305,7 +305,7 @@ map: ["foldedLayer"] visible: false - type: Item - size: 50 + size: Large - type: Appearance - type: MeleeWeapon damage: @@ -339,4 +339,4 @@ - type: Rotatable - type: Sprite state: steel-bench - + diff --git a/Resources/Prototypes/Entities/Structures/Furniture/dresser.yml b/Resources/Prototypes/Entities/Structures/Furniture/dresser.yml index da2b82270f..29061a06b1 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/dresser.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/dresser.yml @@ -25,7 +25,8 @@ - !type:DoActsBehavior acts: [ "Destruction" ] - type: Storage - capacity: 50 + maxSlots: 6 + maxItemSize: Normal - type: ContainerContainer containers: storagebase: !type:Container @@ -67,7 +68,7 @@ - id: ClothingUniformJumpskirtColorPink prob: 0.05 - id: ClothingUniformJumpsuitLoungewear - prob: 0.05 + prob: 0.05 orGroup: dressermainloot - id: Pen # It`s pen. prob: 0.03 @@ -97,7 +98,7 @@ prob: 0.03 orGroup: dressermainloot - id: ClothingUniformJumpsuitColorRed - prob: 0.03 + prob: 0.03 orGroup: dressermainloot - id: ClothingUniformJumpskirtColorRed prob: 0.03 @@ -184,7 +185,7 @@ prob: 0.03 orGroup: dresserthirdloot - id: ClothingUnderSocksCoder - prob: 0.03 + prob: 0.03 orGroup: dressermainloot - id: ClothingUnderSocksBee prob: 0.03 @@ -224,7 +225,7 @@ orGroup: dresserthirdloot - id: PlushieLizard prob: 0.03 - orGroup: dresserthirdloot + orGroup: dresserthirdloot - id: ClothingOuterSuitShrineMaiden prob: 0.03 orGroup: dressersecondloot @@ -423,7 +424,7 @@ - id: BrokenBottle prob: 0.001 orGroup: dressersecondloot - - id: FoodMeatRotten + - id: FoodMeatRotten prob: 0.001 orGroup: dressersecondloot - id: ClothingOuterSkub diff --git a/Resources/Prototypes/Entities/Structures/Furniture/rollerbeds.yml b/Resources/Prototypes/Entities/Structures/Furniture/rollerbeds.yml index 695a529734..406ff7fa48 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/rollerbeds.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/rollerbeds.yml @@ -7,7 +7,7 @@ - type: Transform noRot: true - type: Item - size: 25 + size: Normal - type: Sprite sprite: Structures/Furniture/rollerbeds.rsi noRot: true diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml index 132da2f1a8..b84499d533 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml @@ -8,7 +8,7 @@ mode: SnapgridCenter components: - type: Item - size: 10 + size: Small - type: Transform anchored: true - type: Damageable diff --git a/Resources/Prototypes/Entities/Structures/Specific/Atmospherics/sensor.yml b/Resources/Prototypes/Entities/Structures/Specific/Atmospherics/sensor.yml index 6fa085646a..4466b21b44 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Atmospherics/sensor.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Atmospherics/sensor.yml @@ -87,7 +87,7 @@ description: Air sensor assembly. An assembly of air sensors? components: - type: Item - size: 10 + size: Small - type: Anchorable - type: Construction graph: AirSensor diff --git a/Resources/Prototypes/Entities/Structures/Storage/filing_cabinets.yml b/Resources/Prototypes/Entities/Structures/Storage/filing_cabinets.yml index b79921815b..f0ce9c46d3 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/filing_cabinets.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/filing_cabinets.yml @@ -6,7 +6,8 @@ description: A cabinet for all your filing needs. components: - type: Storage - capacity: 80 + maxSlots: 12 + maxItemSize: Normal whitelist: tags: - Document @@ -65,7 +66,8 @@ description: A small drawer for all your filing needs, Now with wheels! components: - type: Storage - capacity: 50 + maxSlots: 8 + maxItemSize: Normal whitelist: tags: - Document diff --git a/Resources/Prototypes/Entities/Structures/Storage/ore_box.yml b/Resources/Prototypes/Entities/Structures/Storage/ore_box.yml index 7099e1b45d..6bad8c319f 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/ore_box.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/ore_box.yml @@ -50,7 +50,8 @@ True: { visible: false } False: { visible: true } - type: Storage - capacity: 525 + maxSlots: 60 + maxItemSize: Normal storageOpenSound: /Audio/Effects/closetopen.ogg storageCloseSound: /Audio/Effects/closetclose.ogg whitelist: diff --git a/Resources/Prototypes/XenoArch/Effects/utility_effects.yml b/Resources/Prototypes/XenoArch/Effects/utility_effects.yml index f819946a4d..c9297d901b 100644 --- a/Resources/Prototypes/XenoArch/Effects/utility_effects.yml +++ b/Resources/Prototypes/XenoArch/Effects/utility_effects.yml @@ -52,7 +52,9 @@ storagebase: !type:Container ents: [ ] - type: Storage - capacity: 50 + maxSlots: 5 + maxItemSize: Huge + maxTotalWeight: 40 - type: artifactEffect id: EffectPhasing From 7a08a4ebbb99d8421d61422c090d6d447c8228a0 Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 25 Oct 2023 18:54:44 -0400 Subject: [PATCH 054/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 72 ++++++++++++++----------------- 1 file changed, 33 insertions(+), 39 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 033a23561b..33d53fac25 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,43 +1,4 @@ Entries: -- author: CrigCrag - changes: - - {message: 'Nanotrasen stopped watering down their acid to save money. Drinking - or injecting acids is more dangerous now, and acids burn through your insides - much quicker.', type: Tweak} - - {message: Having corrosive acid in your body now makes you scream!, type: Tweak} - - {message: Polytrinic acid now requires plasma to make., type: Tweak} - id: 4556 - time: '2023-08-13T07:24:50.0000000+00:00' -- author: PixelTK - changes: - - {message: Arachnids have received several changes. Check your local PR station - for more details., type: Tweak} - id: 4557 - time: '2023-08-13T07:38:05.0000000+00:00' -- author: PixelTK - changes: - - {message: 'Nanotrasen have fixed their accidental breakage of time space continuum, - making sure that steel tiles do indeed take steel to create.', type: Fix} - id: 4558 - time: '2023-08-13T12:43:01.0000000+00:00' -- author: FillerVK - changes: - - {message: Added cocoa cultivation, type: Add} - - {message: Added a recipe for creating a chocolate bar, type: Add} - id: 4559 - time: '2023-08-13T14:35:58.0000000+00:00' -- author: Vordenburg - changes: - - {message: Player icons in the end-of-round summary window should now display properly., - type: Fix} - id: 4560 - time: '2023-08-13T16:55:05.0000000+00:00' -- author: EmoGarbage404 - changes: - - {message: The DNA scrambler no longer has the power of magically transforming - various creatures into humanoids., type: Fix} - id: 4561 - time: '2023-08-13T16:56:21.0000000+00:00' - author: Repo changes: - {message: fixed pressure tanks to not show scientific notation., type: Fix} @@ -2899,3 +2860,36 @@ Entries: a free hand., type: Fix} id: 5055 time: '2023-10-25T04:51:32.0000000+00:00' +- author: deltanedas + changes: + - {message: Roundstart borg jobs get funny names., type: Tweak} + id: 5056 + time: '2023-10-25T13:00:09.0000000+00:00' +- author: EmoGarbage404 + changes: + - {message: The search bar in vending machines now works., type: Fix} + id: 5057 + time: '2023-10-25T13:01:16.0000000+00:00' +- author: deltanedas + changes: + - {message: 'The Syndicate''s chefs are now offering snack boxes for only 1 tc. + Usually contains a toy, drinks and food.', type: Add} + id: 5058 + time: '2023-10-25T13:26:27.0000000+00:00' +- author: metalgearsloth + changes: + - {message: Fix docking UI not showing other grids., type: Fix} + id: 5059 + time: '2023-10-25T13:28:34.0000000+00:00' +- author: Doru991 + changes: + - {message: Potato batteries can be built by crew., type: Add} + - {message: New compact AI chips may be powered via potato batteries., type: Add} + id: 5060 + time: '2023-10-25T13:52:50.0000000+00:00' +- author: EmoGarbage404 + changes: + - {message: 'Storage now functions based on slots and sizes, rather than numerical + values.', type: Tweak} + id: 5061 + time: '2023-10-25T22:53:39.0000000+00:00' From 81f5e341c0fe8fe0b216574b98af8ace282006ad Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Wed, 25 Oct 2023 22:47:44 -0400 Subject: [PATCH 055/102] Some mild item size balancing + fixes (#21250) --- .../Chemistry/EntitySystems/ChemMasterSystem.cs | 5 ++--- .../Prototypes/Catalog/Fills/Backpacks/duffelbag.yml | 5 +++++ Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml | 9 ++++++++- .../Entities/Clothing/Belt/base_clothingbelt.yml | 2 +- .../Clothing/OuterClothing/base_clothingouter.yml | 10 ++++------ .../Entities/Objects/Specific/Salvage/ore_bag.yml | 2 +- 6 files changed, 21 insertions(+), 12 deletions(-) diff --git a/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs b/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs index e9cf661347..a35cb7703d 100644 --- a/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs @@ -180,14 +180,13 @@ namespace Content.Server.Chemistry.EntitySystems var user = message.Session.AttachedEntity; var maybeContainer = _itemSlotsSystem.GetItemOrNull(chemMaster, SharedChemMaster.OutputSlotName); if (maybeContainer is not { Valid: true } container - || !TryComp(container, out StorageComponent? storage) - || storage.Container is null) + || !TryComp(container, out StorageComponent? storage)) { return; // output can't fit pills } // Ensure the number is valid. - if (message.Number == 0 || _storageSystem.HasSpace((chemMaster, storage))) + if (message.Number == 0 || !_storageSystem.HasSpace((container, storage))) return; // Ensure the amount is valid. diff --git a/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml b/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml index 375e831f3c..0569c4f58c 100644 --- a/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml +++ b/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml @@ -267,6 +267,11 @@ name: syndicate hardsuit bundle description: "Contains the Syndicate's signature blood red hardsuit." components: + - type: Storage + maxItemSize: Huge + whitelist: #to snub 'dem metagamers + components: + - Clothing - type: StorageFill contents: - id: ClothingOuterHardsuitSyndie diff --git a/Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml b/Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml index 234481af8d..bc9485d7f0 100644 --- a/Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml +++ b/Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml @@ -86,9 +86,16 @@ suffix: Filled parent: ToolboxSyndicate components: + - type: Storage + maxSlots: 8 - type: StorageFill contents: - - id: ClothingBeltUtilityEngineering + - id: Crowbar + - id: Wrench + - id: Screwdriver + - id: Wirecutter + - id: Welder + - id: Multitool - id: ClothingHandsGlovesCombat - id: ClothingMaskGasSyndicate diff --git a/Resources/Prototypes/Entities/Clothing/Belt/base_clothingbelt.yml b/Resources/Prototypes/Entities/Clothing/Belt/base_clothingbelt.yml index 1f9f266eb4..ec6b48bf89 100644 --- a/Resources/Prototypes/Entities/Clothing/Belt/base_clothingbelt.yml +++ b/Resources/Prototypes/Entities/Clothing/Belt/base_clothingbelt.yml @@ -25,7 +25,7 @@ maxSlots: 7 maxItemSize: Normal - type: Item - size: Large + size: Huge - type: ContainerContainer containers: storagebase: !type:Container diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml index 5ec74294db..6af455ab27 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml @@ -15,7 +15,7 @@ id: ClothingOuterBaseLarge components: - type: Item - size: Normal + size: Large - type: Clothing slots: - outerClothing @@ -28,8 +28,6 @@ parent: ClothingOuterBase id: ClothingOuterStorageBase components: - - type: Item - size: Normal - type: Storage maxSlots: 3 - type: ContainerContainer @@ -72,7 +70,7 @@ walkModifier: 0.4 sprintModifier: 0.6 - type: Item - size: Large + size: Huge - type: Armor modifiers: coefficients: @@ -107,7 +105,7 @@ walkModifier: 0.8 sprintModifier: 0.8 - type: Item - size: Normal + size: Large - type: entity parent: ClothingOuterBase @@ -130,7 +128,7 @@ id: ClothingOuterBaseMedium components: - type: Item - size: Normal + size: Large - type: Clothing slots: - outerClothing diff --git a/Resources/Prototypes/Entities/Objects/Specific/Salvage/ore_bag.yml b/Resources/Prototypes/Entities/Objects/Specific/Salvage/ore_bag.yml index 5d81dabd84..814ddb30da 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Salvage/ore_bag.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Salvage/ore_bag.yml @@ -16,7 +16,7 @@ - type: Item size: Huge - type: Storage - maxSlots: 12 + maxSlots: 5 maxItemSize: Normal quickInsert: true areaInsert: true From a850b1f568f274522efa0b1408d5df16f114da7e Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 25 Oct 2023 22:48:48 -0400 Subject: [PATCH 056/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 33d53fac25..7f718932bd 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,9 +1,4 @@ Entries: -- author: Repo - changes: - - {message: fixed pressure tanks to not show scientific notation., type: Fix} - id: 4562 - time: '2023-08-13T16:56:30.0000000+00:00' - author: Cripes changes: - {message: 'Paper stamps have been heavily tweaked with new looks, now each paper @@ -2893,3 +2888,10 @@ Entries: values.', type: Tweak} id: 5061 time: '2023-10-25T22:53:39.0000000+00:00' +- author: EmoGarbage404 + changes: + - {message: Adjusted the sizes of space suits and belts., type: Tweak} + - {message: Reduced the slot count in the ore bag., type: Tweak} + - {message: Fixed not being to create pills at the ChemMaster 5000., type: Fix} + id: 5062 + time: '2023-10-26T02:47:45.0000000+00:00' From c08349a94738bb377a2748d8a4ab93641ca4308c Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Thu, 26 Oct 2023 18:46:22 +1100 Subject: [PATCH 057/102] Revert "Storage TEST MERGE" (#21258) --- Content.Client/Storage/UI/StorageWindow.cs | 44 ++--- .../Tests/HumanInventoryUniformSlotsTest.cs | 8 +- Content.IntegrationTests/Tests/StackTest.cs | 39 +++++ Content.IntegrationTests/Tests/StorageTest.cs | 156 ++++++------------ .../EntitySystems/ChemMasterSystem.cs | 9 +- .../Nutrition/EntitySystems/FoodSystem.cs | 3 +- .../Components/SecretStashComponent.cs | 2 +- .../StorageFillVisualizerSystem.cs | 7 +- .../Melee/EnergySword/EnergySwordSystem.cs | 4 +- .../Inventory/InventorySystem.Equip.cs | 2 +- Content.Shared/Item/ItemComponent.cs | 52 +----- Content.Shared/Item/ItemToggleComponent.cs | 5 +- Content.Shared/Item/SharedItemSystem.cs | 57 ++----- .../EntitySystems/MagnetPickupSystem.cs | 5 +- .../EntitySystems/SharedStorageSystem.cs | 134 +++++---------- Content.Shared/Storage/StorageComponent.cs | 33 ++-- .../en-US/components/storage-component.ftl | 7 +- .../en-US/items/components/item-component.ftl | 7 - Resources/Maps/Shuttles/striker.yml | 113 +++++++++++++ Resources/Maps/core.yml | 4 + Resources/Maps/europa.yml | 2 + .../Fills/Backpacks/StarterGear/backpack.yml | 5 +- .../Catalog/Fills/Backpacks/duffelbag.yml | 10 -- .../Catalog/Fills/Boxes/ammunition.yml | 2 +- .../Catalog/Fills/Boxes/general.yml | 45 +++-- .../Catalog/Fills/Boxes/medical.yml | 5 +- .../Catalog/Fills/Boxes/security.yml | 9 - .../Prototypes/Catalog/Fills/Crates/fun.yml | 4 +- .../Prototypes/Catalog/Fills/Items/belt.yml | 11 +- .../Catalog/Fills/Items/briefcases.yml | 4 - .../Catalog/Fills/Items/firstaidkits.yml | 29 +++- .../Catalog/Fills/Items/toolboxes.yml | 9 +- .../Entities/Clothing/Back/backpacks.yml | 14 +- .../Entities/Clothing/Back/duffel.yml | 11 +- .../Entities/Clothing/Back/satchel.yml | 6 +- .../Entities/Clothing/Back/specific.yml | 2 +- .../Clothing/Belt/base_clothingbelt.yml | 7 +- .../Entities/Clothing/Belt/belts.yml | 20 ++- .../Entities/Clothing/Belt/quiver.yml | 3 +- .../Entities/Clothing/Belt/waist_bags.yml | 7 +- .../Entities/Clothing/Ears/headsets.yml | 2 - .../Clothing/Eyes/base_clothingeyes.yml | 2 - .../Clothing/Hands/base_clothinghands.yml | 2 - .../Clothing/Head/base_clothinghead.yml | 6 +- .../Entities/Clothing/Head/hats.yml | 6 +- .../Clothing/Masks/base_clothingmask.yml | 2 - .../Clothing/Neck/base_clothingneck.yml | 2 +- .../Entities/Clothing/Neck/pins.yml | 2 +- .../OuterClothing/base_clothingouter.yml | 12 +- .../Clothing/OuterClothing/hardsuits.yml | 2 +- .../Entities/Clothing/OuterClothing/suits.yml | 4 +- .../Clothing/OuterClothing/wintercoats.yml | 2 +- .../Clothing/Shoes/base_clothingshoes.yml | 4 +- .../Entities/Clothing/Shoes/specific.yml | 2 +- .../Entities/Clothing/base_clothing.yml | 2 - .../Entities/Debugging/debug_sweps.yml | 2 +- .../Prototypes/Entities/Mobs/NPCs/animals.yml | 6 +- .../Prototypes/Entities/Mobs/NPCs/silicon.yml | 4 +- .../Objects/Consumable/Drinks/drinks_cans.yml | 4 +- .../Objects/Consumable/Food/Baked/bread.yml | 2 +- .../Objects/Consumable/Food/Baked/cake.yml | 6 +- .../Consumable/Food/Baked/donkpocket.yml | 2 +- .../Objects/Consumable/Food/Baked/donut.yml | 2 +- .../Objects/Consumable/Food/Baked/misc.yml | 2 +- .../Objects/Consumable/Food/Baked/pizza.yml | 4 +- .../Consumable/Food/Containers/box.yml | 29 ++-- .../Consumable/Food/Containers/tin.yml | 4 +- .../Entities/Objects/Consumable/Food/egg.yml | 4 +- .../Entities/Objects/Consumable/Food/meat.yml | 4 +- .../Objects/Consumable/Food/produce.yml | 18 +- .../Objects/Consumable/Food/skewer.yml | 2 +- .../Objects/Consumable/Food/snacks.yml | 10 +- .../Smokeables/Cigarettes/cartons.yml | 4 +- .../Smokeables/Cigarettes/cigarette.yml | 4 +- .../Smokeables/Cigarettes/joints.yml | 4 +- .../Smokeables/Cigarettes/packs.yml | 9 +- .../Smokeables/Cigarettes/rolling_paper.yml | 11 +- .../Consumable/Smokeables/Cigars/case.yml | 4 +- .../Consumable/Smokeables/Cigars/cigar.yml | 4 +- .../Consumable/Smokeables/Pipes/pipe.yml | 2 +- .../Entities/Objects/Decoration/lidsalami.yml | 2 +- .../Entities/Objects/Decoration/present.yml | 4 +- .../Objects/Devices/Electronics/triggers.yml | 2 +- .../Syndicate_Gadgets/chimp_upgrade_kit.yml | 6 +- .../Objects/Devices/forensic_scanner.yml | 2 +- .../Entities/Objects/Devices/pda.yml | 2 +- .../Fun/Instruments/base_instruments.yml | 2 +- .../Fun/Instruments/instruments_brass.yml | 8 +- .../Fun/Instruments/instruments_misc.yml | 16 +- .../Instruments/instruments_percussion.yml | 10 +- .../Fun/Instruments/instruments_string.yml | 16 +- .../Fun/Instruments/instruments_wind.yml | 20 +-- .../Entities/Objects/Fun/bike_horn.yml | 8 +- .../Entities/Objects/Fun/crayons.yml | 7 +- .../Prototypes/Entities/Objects/Fun/darts.yml | 8 +- .../Prototypes/Entities/Objects/Fun/dice.yml | 2 +- .../Entities/Objects/Fun/dice_bag.yml | 7 +- .../Entities/Objects/Fun/puppet.yml | 2 +- .../Prototypes/Entities/Objects/Fun/toys.yml | 26 +-- .../Objects/Materials/Sheets/glass.yml | 19 ++- .../Objects/Materials/Sheets/metal.yml | 12 +- .../Objects/Materials/Sheets/other.yml | 15 +- .../Entities/Objects/Materials/ingots.yml | 8 +- .../Entities/Objects/Materials/materials.yml | 45 ++++- .../Entities/Objects/Materials/ore.yml | 17 +- .../Entities/Objects/Materials/parts.yml | 8 +- .../Entities/Objects/Materials/shards.yml | 2 +- .../Entities/Objects/Misc/bedsheets.yml | 2 +- .../Prototypes/Entities/Objects/Misc/box.yml | 4 +- .../Entities/Objects/Misc/briefcases.yml | 12 +- .../Entities/Objects/Misc/eggspider.yml | 2 +- .../Objects/Misc/fire_extinguisher.yml | 2 +- .../Entities/Objects/Misc/fluff_lights.yml | 4 +- .../Entities/Objects/Misc/handcuffs.yml | 10 +- .../Objects/Misc/identification_cards.yml | 1 - .../Entities/Objects/Misc/implanters.yml | 2 +- .../Objects/Misc/improvised_gun_parts.yml | 8 +- .../Entities/Objects/Misc/machine_parts.yml | 2 +- .../Entities/Objects/Misc/medalcase.yml | 5 +- .../Entities/Objects/Misc/monkeycube.yml | 2 + .../Entities/Objects/Misc/paper.yml | 23 ++- .../Entities/Objects/Misc/potatoai_chip.yml | 4 +- .../Objects/Misc/subdermal_implants.yml | 5 +- .../Entities/Objects/Power/antimatter_jar.yml | 2 +- .../Objects/Power/antimatter_part.yml | 2 +- .../Entities/Objects/Power/powersink.yml | 2 +- .../Entities/Objects/Power/solar_parts.yml | 2 +- .../Entities/Objects/Shields/shields.yml | 12 +- .../Objects/Specific/Chapel/bibles.yml | 6 +- .../Objects/Specific/Chemistry/chem_bag.yml | 4 +- .../Objects/Specific/Forensics/forensics.yml | 2 +- .../Objects/Specific/Hydroponics/leaves.yml | 4 +- .../Objects/Specific/Hydroponics/seeds.yml | 6 +- .../Objects/Specific/Hydroponics/tools.yml | 6 +- .../Objects/Specific/Janitorial/janitor.yml | 8 +- .../Objects/Specific/Janitorial/trashbag.yml | 9 +- .../Objects/Specific/Kitchen/foodcarts.yml | 19 ++- .../Objects/Specific/Librarian/books_bag.yml | 4 +- .../Specific/Mech/mech_construction.yml | 8 +- .../Objects/Specific/Mech/mecha_equipment.yml | 2 +- .../Objects/Specific/Medical/defib.yml | 2 +- .../Objects/Specific/Medical/disease.yml | 4 +- .../Objects/Specific/Medical/healing.yml | 102 ++---------- .../Objects/Specific/Medical/hypospray.yml | 8 +- .../Objects/Specific/Medical/medkits.yml | 7 +- .../Objects/Specific/Medical/morgue.yml | 2 +- .../Objects/Specific/Research/rped.yml | 4 +- .../Objects/Specific/Salvage/ore_bag.yml | 5 +- .../Service/vending_machine_restock.yml | 2 +- .../Xenoarchaeology/item_artifacts.yml | 2 +- .../Objects/Specific/chemical-containers.yml | 2 +- .../Objects/Specific/chemistry-bottles.yml | 2 +- .../Entities/Objects/Specific/chemistry.yml | 12 +- .../Entities/Objects/Specific/syndicate.yml | 8 +- .../Objects/Tools/access_configurator.yml | 12 +- .../Entities/Objects/Tools/bucket.yml | 2 +- .../Entities/Objects/Tools/cable_coils.yml | 14 +- .../Entities/Objects/Tools/cowtools.yml | 2 +- .../Entities/Objects/Tools/fulton.yml | 6 +- .../Entities/Objects/Tools/gas_tanks.yml | 4 +- .../Objects/Tools/inflatable_wall.yml | 10 +- .../Entities/Objects/Tools/jaws_of_life.yml | 4 +- .../Entities/Objects/Tools/jetpacks.yml | 4 +- .../Entities/Objects/Tools/lighters.yml | 2 +- .../Entities/Objects/Tools/matches.yml | 12 +- .../Entities/Objects/Tools/toolbox.yml | 9 +- .../Entities/Objects/Tools/tools.yml | 16 +- .../Entities/Objects/Tools/welders.yml | 4 +- .../Entities/Objects/Vehicles/keys.yml | 2 +- .../Entities/Objects/Weapons/Bombs/funny.yml | 2 +- .../Objects/Weapons/Bombs/plastic.yml | 2 +- .../Entities/Objects/Weapons/Bombs/spider.yml | 2 +- .../Guns/Ammunition/Boxes/antimateriel.yml | 2 +- .../Guns/Ammunition/Boxes/caseless_rifle.yml | 2 +- .../Guns/Ammunition/Boxes/light_rifle.yml | 2 +- .../Weapons/Guns/Ammunition/Boxes/magnum.yml | 2 +- .../Weapons/Guns/Ammunition/Boxes/pistol.yml | 2 +- .../Weapons/Guns/Ammunition/Boxes/rifle.yml | 2 +- .../Ammunition/Cartridges/base_cartridge.yml | 2 +- .../Ammunition/Magazines/caseless_rifle.yml | 6 +- .../Guns/Ammunition/Magazines/heavy_rifle.yml | 2 +- .../Guns/Ammunition/Magazines/light_rifle.yml | 2 +- .../Guns/Ammunition/Magazines/magnum.yml | 2 +- .../Guns/Ammunition/Magazines/pistol.yml | 6 +- .../Guns/Ammunition/Magazines/rifle.yml | 2 +- .../Guns/Ammunition/Magazines/shotgun.yml | 2 +- .../Weapons/Guns/Ammunition/explosives.yml | 6 +- .../Objects/Weapons/Guns/Basic/base_pka.yml | 2 +- .../Objects/Weapons/Guns/Basic/base_staff.yml | 2 +- .../Objects/Weapons/Guns/Basic/base_wand.yml | 2 +- .../Weapons/Guns/Basic/spraynozzle.yml | 2 +- .../Objects/Weapons/Guns/Basic/watergun.yml | 6 +- .../Weapons/Guns/Battery/battery_guns.yml | 14 +- .../Entities/Objects/Weapons/Guns/Bow/bow.yml | 2 +- .../Objects/Weapons/Guns/HMGs/hmgs.yml | 2 +- .../Objects/Weapons/Guns/LMGs/lmgs.yml | 2 +- .../Weapons/Guns/Launchers/launchers.yml | 2 +- .../Objects/Weapons/Guns/Pistols/pistols.yml | 2 +- .../Weapons/Guns/Projectiles/arrows.yml | 2 +- .../Weapons/Guns/Revolvers/revolvers.yml | 6 +- .../Objects/Weapons/Guns/Rifles/rifles.yml | 2 +- .../Objects/Weapons/Guns/SMGs/smgs.yml | 2 +- .../Weapons/Guns/Shotguns/shotguns.yml | 16 +- .../Objects/Weapons/Guns/Snipers/snipers.yml | 2 +- .../Objects/Weapons/Guns/flare_gun.yml | 2 +- .../Objects/Weapons/Guns/pneumatic_cannon.yml | 20 +-- .../Objects/Weapons/Melee/armblade.yml | 2 +- .../Objects/Weapons/Melee/baseball_bat.yml | 2 +- .../Objects/Weapons/Melee/chainsaw.yml | 2 +- .../Entities/Objects/Weapons/Melee/cult.yml | 6 +- .../Objects/Weapons/Melee/e_sword.yml | 8 +- .../Objects/Weapons/Melee/fireaxe.yml | 2 +- .../Entities/Objects/Weapons/Melee/gohei.yml | 2 +- .../Entities/Objects/Weapons/Melee/knife.yml | 24 +-- .../Entities/Objects/Weapons/Melee/mining.yml | 6 +- .../Entities/Objects/Weapons/Melee/needle.yml | 2 +- .../Objects/Weapons/Melee/pickaxe.yml | 2 +- .../Entities/Objects/Weapons/Melee/spear.yml | 2 +- .../Objects/Weapons/Melee/stunprod.yml | 2 +- .../Entities/Objects/Weapons/Melee/sword.yml | 12 +- .../Objects/Weapons/Melee/weapon_toolbox.yml | 2 +- .../Objects/Weapons/Melee/white_cane.yml | 2 +- .../Objects/Weapons/Throwable/bola.yml | 2 +- .../Objects/Weapons/Throwable/grenades.yml | 4 +- .../Entities/Objects/Weapons/security.yml | 6 +- .../Prototypes/Entities/Objects/base_item.yml | 2 +- .../Structures/Furniture/bookshelf.yml | 3 +- .../Entities/Structures/Furniture/chairs.yml | 4 +- .../Entities/Structures/Furniture/dresser.yml | 13 +- .../Structures/Furniture/rollerbeds.yml | 2 +- .../Structures/Piping/Atmospherics/pipes.yml | 2 +- .../Specific/Atmospherics/sensor.yml | 2 +- .../Structures/Storage/filing_cabinets.yml | 6 +- .../Entities/Structures/Storage/ore_box.yml | 3 +- .../XenoArch/Effects/utility_effects.yml | 4 +- 235 files changed, 1019 insertions(+), 1072 deletions(-) create mode 100644 Content.IntegrationTests/Tests/StackTest.cs diff --git a/Content.Client/Storage/UI/StorageWindow.cs b/Content.Client/Storage/UI/StorageWindow.cs index 325cbd8a6a..1af50cb147 100644 --- a/Content.Client/Storage/UI/StorageWindow.cs +++ b/Content.Client/Storage/UI/StorageWindow.cs @@ -1,15 +1,16 @@ using System.Numerics; -using Content.Client.Message; +using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.CustomControls; using Content.Client.Stylesheets; using Content.Client.UserInterface.Controls; using Content.Shared.IdentityManagement; using Content.Shared.Item; using Content.Shared.Stacks; using Content.Shared.Storage; -using Content.Shared.Storage.EntitySystems; using Robust.Client.UserInterface; +using Robust.Shared.Containers; using static Robust.Client.UserInterface.Controls.BoxContainer; using Direction = Robust.Shared.Maths.Direction; @@ -22,9 +23,7 @@ namespace Content.Client.Storage.UI { private readonly IEntityManager _entityManager; - private readonly SharedStorageSystem _storage; - - private readonly RichTextLabel _information; + private readonly Label _information; public readonly ContainerButton StorageContainerButton; public readonly ListContainer EntityList; private readonly StyleBoxFlat _hoveredBox = new() { BackgroundColor = Color.Black.WithAlpha(0.35f) }; @@ -33,7 +32,6 @@ namespace Content.Client.Storage.UI public StorageWindow(IEntityManager entityManager) { _entityManager = entityManager; - _storage = _entityManager.System(); SetSize = new Vector2(240, 320); Title = Loc.GetString("comp-storage-window-title"); RectClipContent = true; @@ -62,14 +60,11 @@ namespace Content.Client.Storage.UI StorageContainerButton.AddChild(vBox); - _information = new RichTextLabel + _information = new Label { + Text = Loc.GetString("comp-storage-window-volume", ("itemCount", 0), ("usedVolume", 0), ("maxVolume", 0)), VerticalAlignment = VAlignment.Center }; - _information.SetMessage(Loc.GetString("comp-storage-window-volume", - ("itemCount", 0), - ("maxCount", 0), - ("size", SharedItemSystem.GetItemSizeLocale(ItemSize.Normal)))); vBox.AddChild(_information); @@ -106,23 +101,15 @@ namespace Content.Client.Storage.UI EntityList.PopulateList(list); - SetStorageInformation((entity, component)); - } - - private void SetStorageInformation(Entity uid) - { - if (uid.Comp.MaxSlots != uid.Comp.Container.ContainedEntities.Count - && _storage.GetCumulativeItemSizes(uid, uid.Comp) == _storage.GetMaxTotalWeight((uid, uid.Comp))) + // Sets information about entire storage container current capacity + if (component.StorageCapacityMax != 0) { - _information.SetMarkup(Loc.GetString("comp-storage-window-volume-full", - ("size", SharedItemSystem.GetItemSizeLocale(_storage.GetMaxItemSize((uid, uid.Comp)))))); + _information.Text = Loc.GetString("comp-storage-window-volume", ("itemCount", storedCount), + ("usedVolume", component.StorageUsed), ("maxVolume", component.StorageCapacityMax)); } else { - _information.SetMarkup(Loc.GetString("comp-storage-window-volume", - ("itemCount", uid.Comp.Container.ContainedEntities.Count), - ("maxCount", uid.Comp.MaxSlots), - ("size", SharedItemSystem.GetItemSizeLocale(_storage.GetMaxItemSize((uid, uid.Comp)))))); + _information.Text = Loc.GetString("comp-storage-window-volume-unlimited", ("itemCount", storedCount)); } } @@ -135,9 +122,10 @@ namespace Content.Client.Storage.UI || !_entityManager.EntityExists(entity)) return; - _entityManager.TryGetComponent(entity, out StackComponent? stack); _entityManager.TryGetComponent(entity, out ItemComponent? item); + _entityManager.TryGetComponent(entity, out StackComponent? stack); var count = stack?.Count ?? 1; + var size = item?.Size; var spriteView = new SpriteView { @@ -159,14 +147,12 @@ namespace Content.Client.Storage.UI HorizontalExpand = true, ClipText = true, Text = _entityManager.GetComponent(Identity.Entity(entity, _entityManager)).EntityName + - (count > 1 ? $" x {count}" : string.Empty) + (count > 1 ? $" x {count}" : string.Empty), }, new Label { Align = Label.AlignMode.Right, - Text = item?.Size != null - ? SharedItemSystem.GetItemSizeLocale(item.Size) - : Loc.GetString("comp-storage-no-item-size") + Text = size.ToString() ?? Loc.GetString("comp-storage-no-item-size"), } } }); diff --git a/Content.IntegrationTests/Tests/HumanInventoryUniformSlotsTest.cs b/Content.IntegrationTests/Tests/HumanInventoryUniformSlotsTest.cs index 4bba605f0a..3ea3dd7916 100644 --- a/Content.IntegrationTests/Tests/HumanInventoryUniformSlotsTest.cs +++ b/Content.IntegrationTests/Tests/HumanInventoryUniformSlotsTest.cs @@ -26,7 +26,7 @@ namespace Content.IntegrationTests.Tests - type: Clothing slots: [innerclothing] - type: Item - size: Tiny + size: 5 - type: entity name: IDCardDummy @@ -36,7 +36,7 @@ namespace Content.IntegrationTests.Tests slots: - idcard - type: Item - size: Tiny + size: 5 - type: IdCard - type: entity @@ -44,14 +44,14 @@ namespace Content.IntegrationTests.Tests id: FlashlightDummy components: - type: Item - size: Tiny + size: 5 - type: entity name: ToolboxDummy id: ToolboxDummy components: - type: Item - size: Huge + size: 9999 "; [Test] public async Task Test() diff --git a/Content.IntegrationTests/Tests/StackTest.cs b/Content.IntegrationTests/Tests/StackTest.cs new file mode 100644 index 0000000000..a34dd7e53d --- /dev/null +++ b/Content.IntegrationTests/Tests/StackTest.cs @@ -0,0 +1,39 @@ +using Content.Shared.Item; +using Content.Shared.Stacks; +using Robust.Shared.GameObjects; +using Robust.Shared.Prototypes; + +namespace Content.IntegrationTests.Tests; + +[TestFixture] +public sealed class StackTest +{ + [Test] + public async Task StackCorrectItemSize() + { + await using var pair = await PoolManager.GetServerClient(); + var server = pair.Server; + + var protoManager = server.ResolveDependency(); + var compFact = server.ResolveDependency(); + + Assert.Multiple(() => + { + foreach (var entity in PoolManager.GetPrototypesWithComponent(server)) + { + if (!entity.TryGetComponent(out var stackComponent, compFact) || + !entity.TryGetComponent(out var itemComponent, compFact)) + continue; + + if (!protoManager.TryIndex(stackComponent.StackTypeId, out var stackProto) || + stackProto.ItemSize == null) + continue; + + var expectedSize = stackProto.ItemSize * stackComponent.Count; + Assert.That(itemComponent.Size, Is.EqualTo(expectedSize), $"Prototype id: {entity.ID} has an item size of {itemComponent.Size} but expected size of {expectedSize}."); + } + }); + + await pair.CleanReturnAsync(); + } +} diff --git a/Content.IntegrationTests/Tests/StorageTest.cs b/Content.IntegrationTests/Tests/StorageTest.cs index de3b7f149d..ea7f3f5866 100644 --- a/Content.IntegrationTests/Tests/StorageTest.cs +++ b/Content.IntegrationTests/Tests/StorageTest.cs @@ -3,12 +3,11 @@ using System.Collections.Generic; using System.Linq; using Content.Server.Storage.Components; using Content.Shared.Item; -using Content.Shared.Prototypes; using Content.Shared.Storage; using Content.Shared.Storage.Components; -using Content.Shared.Storage.EntitySystems; using Robust.Shared.GameObjects; using Robust.Shared.Prototypes; +using Robust.UnitTesting; namespace Content.IntegrationTests.Tests { @@ -33,11 +32,9 @@ namespace Content.IntegrationTests.Tests { if (!proto.TryGetComponent("Storage", out var storage) || storage.Whitelist != null || - storage.MaxItemSize == null || - !proto.TryGetComponent("Item", out var item)) - continue; + !proto.TryGetComponent("Item", out var item)) continue; - Assert.That(storage.MaxItemSize.Value, Is.LessThan(item.Size), $"Found storage arbitrage on {proto.ID}"); + Assert.That(storage.StorageCapacityMax, Is.LessThanOrEqualTo(item.Size), $"Found storage arbitrage on {proto.ID}"); } }); await pair.CleanReturnAsync(); @@ -85,120 +82,69 @@ namespace Content.IntegrationTests.Tests { foreach (var proto in PoolManager.GetPrototypesWithComponent(server)) { - if (proto.HasComponent(compFact)) - continue; + int capacity; + var isEntStorage = false; - if (!proto.TryGetComponent("Storage", out var storage)) + if (proto.TryGetComponent("Storage", out var storage)) + { + capacity = storage.StorageCapacityMax; + } + else if (proto.TryGetComponent("EntityStorage", out var entStorage)) + { + capacity = entStorage.Capacity; + isEntStorage = true; + } + else { Assert.Fail($"Entity {proto.ID} has storage-fill without a storage component!"); continue; } - proto.TryGetComponent("Item", out var item); - - var maxSize = storage.MaxItemSize ?? - (item?.Size == null - ? SharedStorageSystem.DefaultStorageMaxItemSize - : (ItemSize) Math.Max(0, (int) item.Size - 1)); - - var capacity = storage.MaxTotalWeight ?? - storage.MaxSlots * SharedItemSystem.GetItemSizeWeight(storage.MaxItemSize ?? maxSize); - var fill = (StorageFillComponent) proto.Components[id].Component; - var size = GetFillSize(fill, false, protoMan); - + var size = GetFillSize(fill, isEntStorage); Assert.That(size, Is.LessThanOrEqualTo(capacity), $"{proto.ID} storage fill is too large."); - Assert.That(GetFillSize(fill, true, protoMan), Is.LessThanOrEqualTo(storage.MaxSlots), $"{proto.ID} storage fill has too many items."); - - foreach (var entry in fill.Contents) - { - if (entry.PrototypeId == null) - continue; - - if (!protoMan.TryIndex(entry.PrototypeId, out var fillItem)) - continue; - - if (!fillItem.TryGetComponent("Item", out var entryItem)) - continue; - - Assert.That(entryItem.Size, Is.LessThanOrEqualTo(maxSize), - $"Entity {proto.ID} has storage-fill item, {entry.PrototypeId}, that is too large"); - } } }); - await pair.CleanReturnAsync(); - - } - - [Test] - public async Task TestSufficientSpaceForEntityStorageFill() - { - await using var pair = await PoolManager.GetServerClient(); - var server = pair.Server; - - var protoMan = server.ResolveDependency(); - var compFact = server.ResolveDependency(); - var id = compFact.GetComponentName(typeof(StorageFillComponent)); - - Assert.Multiple(() => + int GetEntrySize(EntitySpawnEntry entry, bool isEntStorage) { - foreach (var proto in PoolManager.GetPrototypesWithComponent(server)) + if (entry.PrototypeId == null) + return 0; + + if (!protoMan.TryIndex(entry.PrototypeId, out var proto)) { - if (proto.HasComponent(compFact)) - continue; - - if (!proto.TryGetComponent("EntityStorage", out var entStorage)) - { - Assert.Fail($"Entity {proto.ID} has storage-fill without a storage component!"); - continue; - } - - var fill = (StorageFillComponent) proto.Components[id].Component; - var size = GetFillSize(fill, true, protoMan); - Assert.That(size, Is.LessThanOrEqualTo(entStorage.Capacity), - $"{proto.ID} storage fill is too large."); + Assert.Fail($"Unknown prototype: {entry.PrototypeId}"); + return 0; } - }); + + if (isEntStorage) + return entry.Amount; + + if (proto.TryGetComponent("Item", out var item)) + return item.Size * entry.Amount; + + Assert.Fail($"Prototype is missing item comp: {entry.PrototypeId}"); + return 0; + } + + int GetFillSize(StorageFillComponent fill, bool isEntStorage) + { + var totalSize = 0; + var groups = new Dictionary(); + foreach (var entry in fill.Contents) + { + var size = GetEntrySize(entry, isEntStorage); + + if (entry.GroupId == null) + totalSize += size; + else + groups[entry.GroupId] = Math.Max(size, groups.GetValueOrDefault(entry.GroupId)); + } + + return totalSize + groups.Values.Sum(); + } + await pair.CleanReturnAsync(); } - - private int GetEntrySize(EntitySpawnEntry entry, bool getCount, IPrototypeManager protoMan) - { - if (entry.PrototypeId == null) - return 0; - - if (!protoMan.TryIndex(entry.PrototypeId, out var proto)) - { - Assert.Fail($"Unknown prototype: {entry.PrototypeId}"); - return 0; - } - - if (getCount) - return entry.Amount; - - if (proto.TryGetComponent("Item", out var item)) - return SharedItemSystem.GetItemSizeWeight(item.Size) * entry.Amount; - - Assert.Fail($"Prototype is missing item comp: {entry.PrototypeId}"); - return 0; - } - - private int GetFillSize(StorageFillComponent fill, bool getCount, IPrototypeManager protoMan) - { - var totalSize = 0; - var groups = new Dictionary(); - foreach (var entry in fill.Contents) - { - var size = GetEntrySize(entry, getCount, protoMan); - - if (entry.GroupId == null) - totalSize += size; - else - groups[entry.GroupId] = Math.Max(size, groups.GetValueOrDefault(entry.GroupId)); - } - - return totalSize + groups.Values.Sum(); - } } } diff --git a/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs b/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs index a35cb7703d..a831165e68 100644 --- a/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs @@ -180,13 +180,14 @@ namespace Content.Server.Chemistry.EntitySystems var user = message.Session.AttachedEntity; var maybeContainer = _itemSlotsSystem.GetItemOrNull(chemMaster, SharedChemMaster.OutputSlotName); if (maybeContainer is not { Valid: true } container - || !TryComp(container, out StorageComponent? storage)) + || !TryComp(container, out StorageComponent? storage) + || storage.Container is null) { return; // output can't fit pills } // Ensure the number is valid. - if (message.Number == 0 || !_storageSystem.HasSpace((container, storage))) + if (message.Number == 0 || message.Number > storage.StorageCapacityMax - storage.StorageUsed) return; // Ensure the amount is valid. @@ -344,7 +345,7 @@ namespace Content.Server.Chemistry.EntitySystems } } - if (!TryComp(container, out StorageComponent? storage) || storage.Container == null) + if (!TryComp(container, out StorageComponent? storage)) return null; var pills = storage.Container?.ContainedEntities.Select((Func) (pill => @@ -357,7 +358,7 @@ namespace Content.Server.Chemistry.EntitySystems if (pills == null) return null; - return new ContainerInfo(name, storage.Container!.ContainedEntities.Count, storage.MaxSlots) + return new ContainerInfo(name, storage.StorageUsed, storage.StorageCapacityMax) { Entities = pills }; diff --git a/Content.Server/Nutrition/EntitySystems/FoodSystem.cs b/Content.Server/Nutrition/EntitySystems/FoodSystem.cs index 758d42356e..ff4ec41dd9 100644 --- a/Content.Server/Nutrition/EntitySystems/FoodSystem.cs +++ b/Content.Server/Nutrition/EntitySystems/FoodSystem.cs @@ -1,4 +1,3 @@ -using System.Linq; using Content.Server.Body.Components; using Content.Server.Body.Systems; using Content.Server.Inventory; @@ -123,7 +122,7 @@ public sealed class FoodSystem : EntitySystem return (false, false); // Check for used storage on the food item - if (TryComp(food, out var storageState) && storageState.Container.ContainedEntities.Any()) + if (TryComp(food, out var storageState) && storageState.StorageUsed != 0) { _popup.PopupEntity(Loc.GetString("food-has-used-storage", ("food", food)), user, user); return (false, true); diff --git a/Content.Server/Storage/Components/SecretStashComponent.cs b/Content.Server/Storage/Components/SecretStashComponent.cs index 6c7095617c..60d0c829e9 100644 --- a/Content.Server/Storage/Components/SecretStashComponent.cs +++ b/Content.Server/Storage/Components/SecretStashComponent.cs @@ -19,7 +19,7 @@ namespace Content.Server.Storage.Components /// Max item size that can be fitted into secret stash. /// [DataField("maxItemSize")] - public ItemSize MaxItemSize = ItemSize.Small; + public int MaxItemSize = (int) ReferenceSizes.Pocket; /// /// IC secret stash name. For example "the toilet cistern". diff --git a/Content.Server/Storage/EntitySystems/StorageFillVisualizerSystem.cs b/Content.Server/Storage/EntitySystems/StorageFillVisualizerSystem.cs index 5fbd328499..ed48de2e45 100644 --- a/Content.Server/Storage/EntitySystems/StorageFillVisualizerSystem.cs +++ b/Content.Server/Storage/EntitySystems/StorageFillVisualizerSystem.cs @@ -1,6 +1,7 @@ using Content.Shared.Rounding; using Content.Shared.Storage; using Content.Shared.Storage.Components; +using Robust.Server.GameObjects; using Robust.Shared.Containers; namespace Content.Server.Storage.EntitySystems; @@ -12,12 +13,12 @@ public sealed class StorageFillVisualizerSystem : EntitySystem public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnStartup); + SubscribeLocalEvent(OnInit); SubscribeLocalEvent(OnInserted); SubscribeLocalEvent(OnRemoved); } - private void OnStartup(EntityUid uid, StorageFillVisualizerComponent component, ComponentStartup args) + private void OnInit(EntityUid uid, StorageFillVisualizerComponent component, ComponentInit args) { UpdateAppearance(uid, component: component); } @@ -41,7 +42,7 @@ public sealed class StorageFillVisualizerSystem : EntitySystem if (component.MaxFillLevels < 1) return; - var level = ContentHelpers.RoundToEqualLevels(storage.Container.ContainedEntities.Count, storage.MaxSlots, component.MaxFillLevels); + var level = ContentHelpers.RoundToEqualLevels(storage.StorageUsed, storage.StorageCapacityMax, component.MaxFillLevels); _appearance.SetData(uid, StorageFillVisuals.FillLevel, level, appearance); } } diff --git a/Content.Server/Weapons/Melee/EnergySword/EnergySwordSystem.cs b/Content.Server/Weapons/Melee/EnergySword/EnergySwordSystem.cs index 80316d64f9..fcd42f5a28 100644 --- a/Content.Server/Weapons/Melee/EnergySword/EnergySwordSystem.cs +++ b/Content.Server/Weapons/Melee/EnergySword/EnergySwordSystem.cs @@ -98,7 +98,7 @@ public sealed class EnergySwordSystem : EntitySystem { if (TryComp(uid, out ItemComponent? item)) { - _item.SetSize(uid, ItemSize.Small, item); + _item.SetSize(uid, 5, item); } if (TryComp(uid, out var malus)) @@ -125,7 +125,7 @@ public sealed class EnergySwordSystem : EntitySystem { if (TryComp(uid, out ItemComponent? item)) { - _item.SetSize(uid, ItemSize.Huge, item); + _item.SetSize(uid, 9999, item); } if (comp.IsSharp) diff --git a/Content.Shared/Inventory/InventorySystem.Equip.cs b/Content.Shared/Inventory/InventorySystem.Equip.cs index 23c0fbd0a2..90c9f0e1e0 100644 --- a/Content.Shared/Inventory/InventorySystem.Equip.cs +++ b/Content.Shared/Inventory/InventorySystem.Equip.cs @@ -264,7 +264,7 @@ public abstract partial class InventorySystem if (slotDefinition.DependsOn != null && !TryGetSlotEntity(target, slotDefinition.DependsOn, out _, inventory)) return false; - var fittingInPocket = slotDefinition.SlotFlags.HasFlag(SlotFlags.POCKET) && item is { Size: <= ItemSize.Small }; + var fittingInPocket = slotDefinition.SlotFlags.HasFlag(SlotFlags.POCKET) && item is { Size: <= (int) ReferenceSizes.Pocket }; if (clothing == null && !fittingInPocket || clothing != null && !clothing.Slots.HasFlag(slotDefinition.SlotFlags) && !fittingInPocket) { diff --git a/Content.Shared/Item/ItemComponent.cs b/Content.Shared/Item/ItemComponent.cs index 6d91f7cb4e..7516f4faca 100644 --- a/Content.Shared/Item/ItemComponent.cs +++ b/Content.Shared/Item/ItemComponent.cs @@ -13,17 +13,18 @@ namespace Content.Shared.Item; [Access(typeof(SharedItemSystem))] public sealed partial class ItemComponent : Component { - [DataField, ViewVariables(VVAccess.ReadWrite)] - [Access(typeof(SharedItemSystem))] - public ItemSize Size = ItemSize.Small; + [ViewVariables(VVAccess.ReadWrite)] + [DataField("size")] + [Access(typeof(SharedItemSystem), Other = AccessPermissions.ReadExecute)] + public int Size = 5; [Access(typeof(SharedItemSystem))] - [DataField] + [DataField("inhandVisuals")] public Dictionary> InhandVisuals = new(); [Access(typeof(SharedItemSystem))] [ViewVariables(VVAccess.ReadWrite)] - [DataField] + [DataField("heldPrefix")] public string? HeldPrefix; /// @@ -38,10 +39,10 @@ public sealed partial class ItemComponent : Component [Serializable, NetSerializable] public sealed class ItemComponentState : ComponentState { - public ItemSize Size { get; } + public int Size { get; } public string? HeldPrefix { get; } - public ItemComponentState(ItemSize size, string? heldPrefix) + public ItemComponentState(int size, string? heldPrefix) { Size = size; HeldPrefix = heldPrefix; @@ -65,43 +66,6 @@ public sealed class VisualsChangedEvent : EntityEventArgs } } -/// -/// Abstracted sizes for items. -/// Used to determine what can fit into inventories. -/// -public enum ItemSize -{ - /// - /// Items that can be held completely in one's hand. - /// - Tiny = 1, - - /// - /// Items that can fit inside of a standard pocket. - /// - Small = 2, - - /// - /// Items that can fit inside of a standard bag. - /// - Normal = 3, - - /// - /// Items that are too large to fit inside of standard bags, but can worn in exterior slots or placed in custom containers. - /// - Large = 4, - - /// - /// Items that are too large to place inside of any kind of container. - /// - Huge = 5, - - /// - /// Picture furry gf - /// - Ginormous = 6 -} - /// /// Reference sizes for common containers and items. /// diff --git a/Content.Shared/Item/ItemToggleComponent.cs b/Content.Shared/Item/ItemToggleComponent.cs index 250306f8c7..fda4d0904a 100644 --- a/Content.Shared/Item/ItemToggleComponent.cs +++ b/Content.Shared/Item/ItemToggleComponent.cs @@ -1,4 +1,3 @@ -using Content.Shared.Item; using Robust.Shared.Audio; using Robust.Shared.GameStates; @@ -21,11 +20,11 @@ public sealed partial class ItemToggleComponent : Component [ViewVariables(VVAccess.ReadWrite)] [DataField("offSize")] - public ItemSize OffSize = ItemSize.Small; + public int OffSize = 1; [ViewVariables(VVAccess.ReadWrite)] [DataField("onSize")] - public ItemSize OnSize = ItemSize.Huge; + public int OnSize = 9999; } [ByRefEvent] diff --git a/Content.Shared/Item/SharedItemSystem.cs b/Content.Shared/Item/SharedItemSystem.cs index d7e7b3630f..5f890af99f 100644 --- a/Content.Shared/Item/SharedItemSystem.cs +++ b/Content.Shared/Item/SharedItemSystem.cs @@ -1,27 +1,23 @@ +using Content.Shared.CombatMode; using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction; using Content.Shared.Stacks; using Content.Shared.Verbs; using Content.Shared.Examine; -using JetBrains.Annotations; using Robust.Shared.Containers; using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; using Robust.Shared.Utility; namespace Content.Shared.Item; public abstract class SharedItemSystem : EntitySystem { + [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly SharedHandsSystem _handsSystem = default!; + [Dependency] private readonly SharedCombatModeSystem _combatMode = default!; [Dependency] protected readonly SharedContainerSystem Container = default!; - public const int ItemSizeWeightTiny = 1; - public const int ItemSizeWeightSmall = 2; - public const int ItemSizeWeightNormal = 4; - public const int ItemSizeWeightLarge = 8; - public const int ItemSizeWeightHuge = 16; - public const int ItemSizeWeightGinormous = 32; - public override void Initialize() { base.Initialize(); @@ -37,13 +33,13 @@ public abstract class SharedItemSystem : EntitySystem #region Public API - public void SetSize(EntityUid uid, ItemSize size, ItemComponent? component = null) + public void SetSize(EntityUid uid, int size, ItemComponent? component = null) { if (!Resolve(uid, ref component, false)) return; component.Size = size; - Dirty(uid, component); + Dirty(component); } public void SetHeldPrefix(EntityUid uid, string? heldPrefix, ItemComponent? component = null) @@ -55,7 +51,7 @@ public abstract class SharedItemSystem : EntitySystem return; component.HeldPrefix = heldPrefix; - Dirty(uid, component); + Dirty(component); VisualsChanged(uid); } @@ -71,7 +67,7 @@ public abstract class SharedItemSystem : EntitySystem item.InhandVisuals = otherItem.InhandVisuals; item.HeldPrefix = otherItem.HeldPrefix; - Dirty(uid, item); + Dirty(item); VisualsChanged(uid); } @@ -87,7 +83,14 @@ public abstract class SharedItemSystem : EntitySystem protected virtual void OnStackCountChanged(EntityUid uid, ItemComponent component, StackCountChangedEvent args) { + if (!TryComp(uid, out var stack)) + return; + if (!_prototype.TryIndex(stack.StackTypeId, out var stackProto) || + stackProto.ItemSize is not { } size) + return; + + SetSize(uid, args.NewCount * size, component); } private void OnHandleState(EntityUid uid, ItemComponent component, ref ComponentHandleState args) @@ -132,7 +135,7 @@ public abstract class SharedItemSystem : EntitySystem private void OnExamine(EntityUid uid, ItemComponent component, ExaminedEvent args) { args.PushMarkup(Loc.GetString("item-component-on-examine-size", - ("size", GetItemSizeLocale(component.Size)))); + ("size", component.Size))); } /// @@ -145,32 +148,4 @@ public abstract class SharedItemSystem : EntitySystem public virtual void VisualsChanged(EntityUid owner) { } - - [PublicAPI] - public static string GetItemSizeLocale(ItemSize size) - { - return Robust.Shared.Localization.Loc.GetString($"item-component-size-{size.ToString()}"); - } - - [PublicAPI] - public static int GetItemSizeWeight(ItemSize size) - { - switch (size) - { - case ItemSize.Tiny: - return ItemSizeWeightTiny; - case ItemSize.Small: - return ItemSizeWeightSmall; - case ItemSize.Normal: - return ItemSizeWeightNormal; - case ItemSize.Large: - return ItemSizeWeightLarge; - case ItemSize.Huge: - return ItemSizeWeightHuge; - case ItemSize.Ginormous: - return ItemSizeWeightGinormous; - default: - throw new ArgumentOutOfRangeException(nameof(size), size, null); - } - } } diff --git a/Content.Shared/Storage/EntitySystems/MagnetPickupSystem.cs b/Content.Shared/Storage/EntitySystems/MagnetPickupSystem.cs index c7505ab3c0..16657bdae4 100644 --- a/Content.Shared/Storage/EntitySystems/MagnetPickupSystem.cs +++ b/Content.Shared/Storage/EntitySystems/MagnetPickupSystem.cs @@ -1,7 +1,10 @@ using Content.Server.Storage.Components; +using Content.Shared.Hands; using Content.Shared.Inventory; +using Content.Shared.Stacks; using Robust.Shared.Map; using Robust.Shared.Physics.Components; +using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Shared.Storage.EntitySystems; @@ -53,7 +56,7 @@ public sealed class MagnetPickupSystem : EntitySystem comp.NextScan += ScanDelay; // No space - if (!_storage.HasSpace((uid, storage))) + if (storage.StorageUsed >= storage.StorageCapacityMax) continue; if (!_inventory.TryGetContainingSlot(uid, out var slotDef)) diff --git a/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs b/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs index 798d768191..5faec99fd5 100644 --- a/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs +++ b/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs @@ -4,6 +4,7 @@ using Content.Shared.CombatMode; using Content.Shared.Containers.ItemSlots; using Content.Shared.Destructible; using Content.Shared.DoAfter; +using Content.Shared.Hands; using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.Implants.Components; @@ -45,8 +46,6 @@ public abstract class SharedStorageSystem : EntitySystem private EntityQuery _stackQuery; private EntityQuery _xformQuery; - public const ItemSize DefaultStorageMaxItemSize = ItemSize.Normal; - /// public override void Initialize() { @@ -90,7 +89,6 @@ public abstract class SharedStorageSystem : EntitySystem { // TODO: I had this. // We can get states being applied before the container is ready. - // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract if (component.Container == default) return; @@ -231,7 +229,7 @@ public abstract class SharedStorageSystem : EntitySystem return; } - if (_xformQuery.TryGetComponent(uid, out var transformOwner) && TryComp(target, out var transformEnt)) + if (TryComp(uid, out var transformOwner) && TryComp(target, out var transformEnt)) { var parent = transformOwner.ParentUid; @@ -241,7 +239,7 @@ public abstract class SharedStorageSystem : EntitySystem _transform ); - if (PlayerInsertEntityInWorld((uid, storageComp), args.User, target)) + if (PlayerInsertEntityInWorld(uid, args.User, target, storageComp)) { RaiseNetworkEvent(new AnimateInsertingEntitiesEvent(GetNetEntity(uid), new List { GetNetEntity(target) }, @@ -287,7 +285,7 @@ public abstract class SharedStorageSystem : EntitySystem var angle = targetXform.LocalRotation; - if (PlayerInsertEntityInWorld((uid, component), args.Args.User, entity)) + if (PlayerInsertEntityInWorld(uid, args.Args.User, entity, component)) { successfullyInserted.Add(entity); successfullyInsertedPositions.Add(position); @@ -324,7 +322,7 @@ public abstract class SharedStorageSystem : EntitySystem /// private void OnInteractWithItem(EntityUid uid, StorageComponent storageComp, StorageInteractWithItemEvent args) { - if (args.Session.AttachedEntity is not { } player) + if (args.Session.AttachedEntity is not EntityUid player) return; var entity = GetEntity(args.InteractedItemUID); @@ -398,10 +396,27 @@ public abstract class SharedStorageSystem : EntitySystem public void RecalculateStorageUsed(EntityUid uid, StorageComponent storageComp) { - // it might make more sense to use the weights instead of the slots. - // I'm not sure. - _appearance.SetData(uid, StorageVisuals.StorageUsed, storageComp.Container.ContainedEntities.Count); - _appearance.SetData(uid, StorageVisuals.Capacity, storageComp.MaxSlots); + storageComp.StorageUsed = 0; + + foreach (var entity in storageComp.Container.ContainedEntities) + { + if (!_itemQuery.TryGetComponent(entity, out var itemComp)) + continue; + + var size = itemComp.Size; + storageComp.StorageUsed += size; + } + + _appearance.SetData(uid, StorageVisuals.StorageUsed, storageComp.StorageUsed); + _appearance.SetData(uid, StorageVisuals.Capacity, storageComp.StorageCapacityMax); + } + + public int GetAvailableSpace(EntityUid uid, StorageComponent? component = null) + { + if (!Resolve(uid, ref component)) + return 0; + + return component.StorageCapacityMax - component.StorageUsed; } /// @@ -434,20 +449,17 @@ public abstract class SharedStorageSystem : EntitySystem /// Verifies if an entity can be stored and if it fits /// /// The entity to check - /// /// If returning false, the reason displayed to the player - /// - /// /// true if it can be inserted, false otherwise - public bool CanInsert(EntityUid uid, EntityUid insertEnt, out string? reason, StorageComponent? storageComp = null, ItemComponent? item = null) + public bool CanInsert(EntityUid uid, EntityUid insertEnt, out string? reason, StorageComponent? storageComp = null) { - if (!Resolve(uid, ref storageComp) || !Resolve(insertEnt, ref item)) + if (!Resolve(uid, ref storageComp)) { reason = null; return false; } - if (Transform(insertEnt).Anchored) + if (TryComp(insertEnt, out TransformComponent? transformComp) && transformComp.Anchored) { reason = "comp-storage-anchored-failure"; return false; @@ -465,19 +477,15 @@ public abstract class SharedStorageSystem : EntitySystem return false; } - if (item.Size > GetMaxItemSize((uid, storageComp))) - { - reason = "comp-storage-too-big"; - return false; - } - - if (storageComp.Container.ContainedEntities.Count >= storageComp.MaxSlots) + if (TryComp(insertEnt, out StorageComponent? storage) && + storage.StorageCapacityMax >= storageComp.StorageCapacityMax) { reason = "comp-storage-insufficient-capacity"; return false; } - if (SharedItemSystem.GetItemSizeWeight(item.Size) + GetCumulativeItemSizes(uid, storageComp) > GetMaxTotalWeight((uid, storageComp))) + if (TryComp(insertEnt, out ItemComponent? itemComp) && + itemComp.Size > storageComp.StorageCapacityMax - storageComp.StorageUsed) { reason = "comp-storage-insufficient-capacity"; return false; @@ -534,7 +542,8 @@ public abstract class SharedStorageSystem : EntitySystem if (insertStack.Count > 0) { // Try to insert it as a new stack. - if (!CanInsert(uid, insertEnt, out _, storageComp) || + if (TryComp(insertEnt, out ItemComponent? itemComp) && + itemComp.Size > storageComp.StorageCapacityMax - storageComp.StorageUsed || !storageComp.Container.Insert(insertEnt)) { // If we also didn't do any stack fills above then just end @@ -559,9 +568,7 @@ public abstract class SharedStorageSystem : EntitySystem /// /// Inserts an entity into storage from the player's active hand /// - /// /// The player to insert an entity from - /// /// true if inserted, false otherwise public bool PlayerInsertHeldEntity(EntityUid uid, EntityUid player, StorageComponent? storageComp = null) { @@ -582,23 +589,21 @@ public abstract class SharedStorageSystem : EntitySystem return false; } - return PlayerInsertEntityInWorld((uid, storageComp), player, toInsert.Value); + return PlayerInsertEntityInWorld(uid, player, toInsert.Value, storageComp); } /// /// Inserts an Entity () in the world into storage, informing if it fails. - /// is *NOT* held, see . + /// is *NOT* held, see . /// - /// /// The player to insert an entity with - /// /// true if inserted, false otherwise - public bool PlayerInsertEntityInWorld(Entity uid, EntityUid player, EntityUid toInsert) + public bool PlayerInsertEntityInWorld(EntityUid uid, EntityUid player, EntityUid toInsert, StorageComponent? storageComp = null) { - if (!Resolve(uid, ref uid.Comp) || !_sharedInteractionSystem.InRangeUnobstructed(player, uid)) + if (!Resolve(uid, ref storageComp) || !_sharedInteractionSystem.InRangeUnobstructed(player, uid)) return false; - if (!Insert(uid, toInsert, out _, user: player, uid.Comp)) + if (!Insert(uid, toInsert, out _, user: player, storageComp)) { _popupSystem.PopupClient(Loc.GetString("comp-storage-cant-insert"), uid, player); return false; @@ -606,65 +611,6 @@ public abstract class SharedStorageSystem : EntitySystem return true; } - /// - /// Returns true if there is enough space to theoretically fit another item. - /// - public bool HasSpace(Entity uid) - { - if (!Resolve(uid, ref uid.Comp)) - return false; - - return uid.Comp.Container.ContainedEntities.Count < uid.Comp.MaxSlots && - GetCumulativeItemSizes(uid, uid.Comp) < GetMaxTotalWeight(uid); - } - - /// - /// Returns the sum of all the ItemSizes of the items inside of a storage. - /// - public int GetCumulativeItemSizes(EntityUid uid, StorageComponent? component = null) - { - if (!Resolve(uid, ref component)) - return 0; - - var sum = 0; - foreach (var item in component.Container.ContainedEntities) - { - if (!_itemQuery.TryGetComponent(item, out var itemComp)) - continue; - sum += SharedItemSystem.GetItemSizeWeight(itemComp.Size); - } - - return sum; - } - - public ItemSize GetMaxItemSize(Entity uid) - { - if (!Resolve(uid, ref uid.Comp)) - return DefaultStorageMaxItemSize; - - // If we specify a max item size, use that - if (uid.Comp.MaxItemSize != null) - return uid.Comp.MaxItemSize.Value; - - if (!_itemQuery.TryGetComponent(uid, out var item)) - return DefaultStorageMaxItemSize; - - // if there is no max item size specified, the value used - // is one below the item size of the storage entity, clamped at ItemSize.Tiny - return (ItemSize) Math.Max((int) item.Size - 1, 1); - } - - public int GetMaxTotalWeight(Entity uid) - { - if (!Resolve(uid, ref uid.Comp)) - return 0; - - if (uid.Comp.MaxTotalWeight != null) - return uid.Comp.MaxTotalWeight.Value; - - return uid.Comp.MaxSlots * SharedItemSystem.GetItemSizeWeight(GetMaxItemSize(uid)); - } - /// /// Plays a clientside pickup animation for the specified uid. /// diff --git a/Content.Shared/Storage/StorageComponent.cs b/Content.Shared/Storage/StorageComponent.cs index f05db44081..fdcf06bf5d 100644 --- a/Content.Shared/Storage/StorageComponent.cs +++ b/Content.Shared/Storage/StorageComponent.cs @@ -1,5 +1,3 @@ -using Content.Shared.Item; -using Content.Shared.Storage.EntitySystems; using Content.Shared.Whitelist; using Robust.Shared.Audio; using Robust.Shared.Containers; @@ -22,25 +20,6 @@ namespace Content.Shared.Storage [ViewVariables] public Container Container = default!; - /// - /// The max number of entities that can be inserted into this storage. - /// - [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] - public int MaxSlots = 7; - - /// - /// The maximum size item that can be inserted into this storage, - /// - [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] - [Access(typeof(SharedStorageSystem))] - public ItemSize? MaxItemSize; - - /// - /// A limit for the cumulative ItemSizes that can be inserted in this storage. - /// - [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] - public int? MaxTotalWeight; - // TODO: Make area insert its own component. [DataField("quickInsert")] public bool QuickInsert; // Can insert storables by "attacking" them with the storage entity @@ -66,6 +45,18 @@ namespace Content.Shared.Storage [DataField("blacklist")] public EntityWhitelist? Blacklist; + /// + /// How much storage is currently being used by contained entities. + /// + [ViewVariables, DataField("storageUsed"), AutoNetworkedField] + public int StorageUsed; + + /// + /// Maximum capacity for storage. + /// + [DataField("capacity"), AutoNetworkedField] + public int StorageCapacityMax = 10000; + /// /// Sound played whenever an entity is inserted into storage. /// diff --git a/Resources/Locale/en-US/components/storage-component.ftl b/Resources/Locale/en-US/components/storage-component.ftl index cea37cd961..a6d542e4fb 100644 --- a/Resources/Locale/en-US/components/storage-component.ftl +++ b/Resources/Locale/en-US/components/storage-component.ftl @@ -1,10 +1,9 @@ comp-storage-no-item-size = N/A comp-storage-cant-insert = Can't insert. -comp-storage-too-big = Too big! -comp-storage-insufficient-capacity = No room! +comp-storage-insufficient-capacity = Insufficient capacity. comp-storage-invalid-container = This doesn't go in there! comp-storage-anchored-failure = Can't insert an anchored item. comp-storage-cant-drop = You can't let go of { THE($entity) }! comp-storage-window-title = Storage Item -comp-storage-window-volume = Items: { $itemCount }/{ $maxCount }, Max Size: {$size} -comp-storage-window-volume-full = [color=orange][bold]FULL[/bold][/color], Max Size: {$size} +comp-storage-window-volume = Items: { $itemCount }, Stored: { $usedVolume }/{ $maxVolume } +comp-storage-window-volume-unlimited = Items: { $itemCount } diff --git a/Resources/Locale/en-US/items/components/item-component.ftl b/Resources/Locale/en-US/items/components/item-component.ftl index 54354ef1ee..f9750a55fa 100644 --- a/Resources/Locale/en-US/items/components/item-component.ftl +++ b/Resources/Locale/en-US/items/components/item-component.ftl @@ -7,10 +7,3 @@ pick-up-verb-get-data-text = Pick Up pick-up-verb-get-data-text-inventory = Put in hand item-component-on-examine-size = Size: {$size} - -item-component-size-Tiny = tiny -item-component-size-Small = small -item-component-size-Normal = normal -item-component-size-Large = large -item-component-size-Huge = huge -item-component-size-Ginormous = bulky diff --git a/Resources/Maps/Shuttles/striker.yml b/Resources/Maps/Shuttles/striker.yml index 2601c78160..1b71e29725 100644 --- a/Resources/Maps/Shuttles/striker.yml +++ b/Resources/Maps/Shuttles/striker.yml @@ -874,6 +874,36 @@ entities: pos: -0.5,0.5 parent: 325 type: Transform +- proto: ClothingBeltSyndieHolster + entities: + - uid: 317 + components: + - flags: InContainer + type: MetaData + - parent: 177 + type: Transform + - canCollide: False + type: Physics +- proto: ClothingHandsGlovesCombat + entities: + - uid: 316 + components: + - flags: InContainer + type: MetaData + - parent: 177 + type: Transform + - canCollide: False + type: Physics +- proto: ClothingMaskGasSyndicate + entities: + - uid: 318 + components: + - flags: InContainer + type: MetaData + - parent: 177 + type: Transform + - canCollide: False + type: Physics - proto: ComputerIFFSyndicate entities: - uid: 40 @@ -896,6 +926,16 @@ entities: ents: - 245 type: ContainerContainer +- proto: Crowbar + entities: + - uid: 313 + components: + - flags: InContainer + type: MetaData + - parent: 177 + type: Transform + - canCollide: False + type: Physics - proto: CyberPen entities: - uid: 77 @@ -1632,6 +1672,16 @@ entities: pos: -2.5,-3.5 parent: 325 type: Transform +- proto: Multitool + entities: + - uid: 314 + components: + - flags: InContainer + type: MetaData + - parent: 177 + type: Transform + - canCollide: False + type: Physics - proto: NitrogenTankFilled entities: - uid: 105 @@ -1830,6 +1880,20 @@ entities: type: Transform - canCollide: False type: Physics +- proto: Screwdriver + entities: + - uid: 310 + components: + - flags: InContainer + type: MetaData + - parent: 177 + type: Transform + - selected: + enum.DamageStateVisualLayers.Base: + screwdriver: '#1861D5FF' + type: RandomSprite + - canCollide: False + type: Physics - proto: SheetGlass1 entities: - uid: 244 @@ -2318,6 +2382,21 @@ entities: - pos: 1.5699697,-0.44908836 parent: 325 type: Transform + - containers: + storagebase: !type:Container + showEnts: False + occludes: True + ents: + - 310 + - 311 + - 312 + - 313 + - 314 + - 315 + - 316 + - 317 + - 318 + type: ContainerContainer - canCollide: False type: Physics - proto: ToyFigurineNukie @@ -2577,6 +2656,16 @@ entities: - pos: -2.5,2.5 parent: 325 type: Transform +- proto: Welder + entities: + - uid: 312 + components: + - flags: InContainer + type: MetaData + - parent: 177 + type: Transform + - canCollide: False + type: Physics - proto: WindoorSecure entities: - uid: 166 @@ -2598,6 +2687,30 @@ entities: ents: - 346 type: ContainerContainer +- proto: Wirecutter + entities: + - uid: 315 + components: + - flags: InContainer + type: MetaData + - parent: 177 + type: Transform + - selected: + enum.DamageStateVisualLayers.Base: + cutters: '#D58C18FF' + type: RandomSprite + - canCollide: False + type: Physics +- proto: Wrench + entities: + - uid: 311 + components: + - flags: InContainer + type: MetaData + - parent: 177 + type: Transform + - canCollide: False + type: Physics - proto: YellowOxygenTankFilled entities: - uid: 167 diff --git a/Resources/Maps/core.yml b/Resources/Maps/core.yml index d31189c43b..328400cd0b 100644 --- a/Resources/Maps/core.yml +++ b/Resources/Maps/core.yml @@ -102471,6 +102471,8 @@ entities: type: Transform - count: 15 type: Stack + - size: 15 + type: Item - proto: SheetPlasma entities: - uid: 12944 @@ -102562,6 +102564,8 @@ entities: type: Transform - count: 20 type: Stack + - size: 20 + type: Item - proto: Shovel entities: - uid: 12955 diff --git a/Resources/Maps/europa.yml b/Resources/Maps/europa.yml index 98a2c5807d..ddba1100f2 100644 --- a/Resources/Maps/europa.yml +++ b/Resources/Maps/europa.yml @@ -78331,6 +78331,8 @@ entities: type: Transform - count: 15 type: Stack + - size: 30 + type: Item - proto: StoolBar entities: - uid: 921 diff --git a/Resources/Prototypes/Catalog/Fills/Backpacks/StarterGear/backpack.yml b/Resources/Prototypes/Catalog/Fills/Backpacks/StarterGear/backpack.yml index 5eeec04af2..1e0788cccd 100644 --- a/Resources/Prototypes/Catalog/Fills/Backpacks/StarterGear/backpack.yml +++ b/Resources/Prototypes/Catalog/Fills/Backpacks/StarterGear/backpack.yml @@ -28,7 +28,7 @@ - id: BoxSurvivalSecurity - id: Flash - id: MagazinePistol - + - type: entity noSpawn: true parent: ClothingBackpackSecurity @@ -291,7 +291,8 @@ - id: RegenerativeMesh - id: RCD - id: RCDAmmo - amount: 2 + - id: RCDAmmo + - id: RCDAmmo - id: CableMVStack - id: CableHVStack diff --git a/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml b/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml index 0569c4f58c..12f31bc016 100644 --- a/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml +++ b/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml @@ -198,9 +198,6 @@ name: syndicate pyjama duffel bag description: Contains 3 pairs of syndicate pyjamas and 3 plushies for the ultimate sleepover. components: - - type: Storage - maxSlots: 16 - maxTotalWeight: 44 - type: StorageFill contents: - id: ClothingUniformJumpsuitPyjamaSyndicateRed @@ -234,8 +231,6 @@ id: ClothingBackpackChameleonFill suffix: Fill, Chameleon components: - - type: Storage - maxSlots: 9 - type: StorageFill contents: - id: ClothingUniformJumpsuitChameleon @@ -267,11 +262,6 @@ name: syndicate hardsuit bundle description: "Contains the Syndicate's signature blood red hardsuit." components: - - type: Storage - maxItemSize: Huge - whitelist: #to snub 'dem metagamers - components: - - Clothing - type: StorageFill contents: - id: ClothingOuterHardsuitSyndie diff --git a/Resources/Prototypes/Catalog/Fills/Boxes/ammunition.yml b/Resources/Prototypes/Catalog/Fills/Boxes/ammunition.yml index 7fc62984a0..20e291494f 100644 --- a/Resources/Prototypes/Catalog/Fills/Boxes/ammunition.yml +++ b/Resources/Prototypes/Catalog/Fills/Boxes/ammunition.yml @@ -278,7 +278,7 @@ containers: ballistic-ammo: !type:Container - type: Item - size: Normal + size: 30 - type: Sprite sprite: Objects/Storage/boxes.rsi diff --git a/Resources/Prototypes/Catalog/Fills/Boxes/general.yml b/Resources/Prototypes/Catalog/Fills/Boxes/general.yml index e2ca59a7d2..d05dfbb4ed 100644 --- a/Resources/Prototypes/Catalog/Fills/Boxes/general.yml +++ b/Resources/Prototypes/Catalog/Fills/Boxes/general.yml @@ -37,8 +37,7 @@ - state: box - state: light - type: Storage - maxSlots: 12 - maxTotalWeight: 24 + capacity: 60 whitelist: components: - LightBulb @@ -61,8 +60,7 @@ - state: box - state: lighttube - type: Storage - maxSlots: 12 - maxTotalWeight: 24 + capacity: 60 whitelist: components: - LightBulb @@ -87,8 +85,7 @@ - state: box - state: lightmixed - type: Storage - maxSlots: 12 - maxTotalWeight: 24 + capacity: 60 whitelist: components: - LightBulb @@ -111,6 +108,7 @@ - state: box - state: pda - type: Storage + capacity: 60 whitelist: components: - Pda @@ -130,6 +128,7 @@ - state: box - state: pda - type: Storage + capacity: 60 whitelist: components: - IdCard @@ -149,6 +148,7 @@ - state: box - state: headset - type: Storage + capacity: 60 whitelist: components: - Headset @@ -192,6 +192,7 @@ description: A special box for sensitive people. components: - type: Storage + capacity: 30 - type: Sprite layers: - state: box_hug @@ -233,12 +234,6 @@ id: BoxPerformer description: Happy Hatsune Miku Day! components: - - type: Storage - maxItemSize: Normal - whitelist: - components: - - Clothing - - Food - type: StorageFill contents: - id: ClothingShoesBootsPerformer @@ -272,7 +267,7 @@ - id: TrashBag amount: 6 - type: Storage - maxItemSize: Normal + capacity: 800 whitelist: tags: - TrashBag @@ -299,6 +294,7 @@ - state: box - state: encryptokey - type: Storage + capacity: 30 whitelist: components: - EncryptionKey @@ -390,12 +386,13 @@ description: Two syndicate encryption keys for the price of one. Miniaturized for ease of use. components: - type: Item - size: Normal + size: 15 - type: StorageFill contents: - id: EncryptionKeySyndie amount: 2 - type: Storage + capacity: 15 - type: entity name: deathrattle implant box @@ -404,7 +401,7 @@ description: Six deathrattle implants and handheld GPS devices for the whole squad. components: - type: Item - size: Normal + size: 60 - type: StorageFill contents: - id: DeathRattleImplanter @@ -412,8 +409,7 @@ - id: HandheldGPSBasic amount: 6 - type: Storage - maxSlots: 12 - maxTotalWeight: 24 + capacity: 60 - type: Sprite layers: - state: box @@ -438,21 +434,20 @@ description: This box filled with colorful darts. components: - type: Item - size: Normal + size: 40 - type: StorageFill contents: - id: Dart - amount: 3 + amount: 5 - id: DartBlue - amount: 3 + amount: 5 - id: DartPurple - amount: 3 + amount: 5 - id: DartYellow - amount: 3 + amount: 5 - type: Storage - maxSlots: 12 - maxTotalWeight: 24 + capacity: 40 - type: Sprite layers: - state: box - - state: darts + - state: darts \ No newline at end of file diff --git a/Resources/Prototypes/Catalog/Fills/Boxes/medical.yml b/Resources/Prototypes/Catalog/Fills/Boxes/medical.yml index 9a7f4b47e0..41ee064ce0 100644 --- a/Resources/Prototypes/Catalog/Fills/Boxes/medical.yml +++ b/Resources/Prototypes/Catalog/Fills/Boxes/medical.yml @@ -93,13 +93,10 @@ parent: BoxCardboard id: BoxMouthSwab components: - - type: Storage - maxSlots: 10 - maxTotalWeight: 20 - type: StorageFill contents: - id: DiseaseSwab - amount: 10 + amount: 30 - type: Sprite layers: - state: box diff --git a/Resources/Prototypes/Catalog/Fills/Boxes/security.yml b/Resources/Prototypes/Catalog/Fills/Boxes/security.yml index 51dc512f91..027aaf19f6 100644 --- a/Resources/Prototypes/Catalog/Fills/Boxes/security.yml +++ b/Resources/Prototypes/Catalog/Fills/Boxes/security.yml @@ -49,12 +49,6 @@ id: BoxZiptie description: A box full of zipties. components: - - type: Storage - maxSlots: 10 - maxTotalWeight: 20 - whitelist: - components: - - Handcuff - type: StorageFill contents: - id: Zipties @@ -70,9 +64,6 @@ id: BoxForensicPad description: A box of forensic pads. components: - - type: Storage - maxSlots: 10 - maxTotalWeight: 20 - type: StorageFill contents: - id: ForensicPad diff --git a/Resources/Prototypes/Catalog/Fills/Crates/fun.yml b/Resources/Prototypes/Catalog/Fills/Crates/fun.yml index 1526cf0f63..48877fd889 100644 --- a/Resources/Prototypes/Catalog/Fills/Crates/fun.yml +++ b/Resources/Prototypes/Catalog/Fills/Crates/fun.yml @@ -302,8 +302,8 @@ - id: TargetDarts amount: 1 - id: BoxDarts - amount: 2 + amount: 1 - id: BoxDarts amount: 1 prob: 0.05 - + diff --git a/Resources/Prototypes/Catalog/Fills/Items/belt.yml b/Resources/Prototypes/Catalog/Fills/Items/belt.yml index baad216f47..1886b961c8 100644 --- a/Resources/Prototypes/Catalog/Fills/Items/belt.yml +++ b/Resources/Prototypes/Catalog/Fills/Items/belt.yml @@ -89,11 +89,14 @@ - type: StorageFill contents: - id: Brutepack + amount: 1 - id: Ointment + amount: 1 - id: Bloodpack + amount: 1 - id: Gauze - id: EmergencyMedipen #You never know what people are going to latejoin into - amount: 3 + amount: 6 - type: entity id: ClothingBeltPlantFilled @@ -121,10 +124,6 @@ name: grenadier chest rig suffix: Filled components: - - type: Item - size: Large - - type: Storage - maxSlots: 8 - type: StorageFill contents: - id: ExGrenade @@ -170,4 +169,4 @@ contents: - id: WeaponRevolverInspector - id: SpeedLoaderMagnum - - id: SpeedLoaderMagnumRubber + - id: SpeedLoaderMagnumRubber \ No newline at end of file diff --git a/Resources/Prototypes/Catalog/Fills/Items/briefcases.yml b/Resources/Prototypes/Catalog/Fills/Items/briefcases.yml index 714148a64d..c487909a4b 100644 --- a/Resources/Prototypes/Catalog/Fills/Items/briefcases.yml +++ b/Resources/Prototypes/Catalog/Fills/Items/briefcases.yml @@ -15,10 +15,6 @@ parent: BriefcaseSyndie suffix: SniperBundle components: - - type: Item - size: Huge - - type: Storage - maxItemSize: Large - type: StorageFill contents: - id: WeaponSniperHristov diff --git a/Resources/Prototypes/Catalog/Fills/Items/firstaidkits.yml b/Resources/Prototypes/Catalog/Fills/Items/firstaidkits.yml index 832d357d83..8cc7d6b6d4 100644 --- a/Resources/Prototypes/Catalog/Fills/Items/firstaidkits.yml +++ b/Resources/Prototypes/Catalog/Fills/Items/firstaidkits.yml @@ -12,7 +12,8 @@ - id: Ointment amount: 2 - id: Gauze - - id: PillCanisterTricordrazine + - id: PillTricordrazine + amount: 5 # see https://github.com/tgstation/blob/master/code/game/objects/items/storage/firstaid.dm for example contents - type: entity @@ -27,8 +28,10 @@ - id: Ointment amount: 2 - id: SyringeSigynate - - id: PillCanisterKelotane - - id: PillCanisterDermaline + - id: PillKelotane + amount: 5 + - id: PillDermaline + amount: 5 - type: entity id: MedkitBruteFilled @@ -42,8 +45,10 @@ - id: Gauze - id: Bloodpack - id: SyringeTranexamicAcid - - id: PillCanisterIron - - id: PillCanisterBicaridine + - id: PillIron + amount: 5 + - id: PillBicaridine + amount: 5 - type: entity id: MedkitToxinFilled @@ -55,8 +60,10 @@ - id: SyringeIpecac - id: SyringeEthylredoxrazine - id: AntiPoisonMedipen - - id: PillCanisterDylovene - - id: PillCanisterCharcoal + - id: PillDylovene + amount: 5 + - id: PillCharcoal + amount: 3 - type: entity id: MedkitOxygenFilled @@ -69,7 +76,8 @@ - id: EmergencyOxygenTankFilled - id: EmergencyMedipen - id: SyringeInaprovaline - - id: PillCanisterDexalin + - id: PillDexalin + amount: 7 - type: entity id: MedkitRadiationFilled @@ -84,7 +92,8 @@ amount: 1 - id: EmergencyMedipen amount: 1 - - id: PillCanisterHyronalin + - id: PillHyronalin + amount: 5 - type: entity id: MedkitAdvancedFilled @@ -111,9 +120,11 @@ - id: MedicatedSuture - id: RegenerativeMesh - id: SyringeEphedrine + - id: SyringeSaline - id: BruteAutoInjector - id: BurnAutoInjector - id: EmergencyMedipen + - id: Bloodpack - type: entity id: StimkitFilled diff --git a/Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml b/Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml index bc9485d7f0..234481af8d 100644 --- a/Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml +++ b/Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml @@ -86,16 +86,9 @@ suffix: Filled parent: ToolboxSyndicate components: - - type: Storage - maxSlots: 8 - type: StorageFill contents: - - id: Crowbar - - id: Wrench - - id: Screwdriver - - id: Wirecutter - - id: Welder - - id: Multitool + - id: ClothingBeltUtilityEngineering - id: ClothingHandsGlovesCombat - id: ClothingMaskGasSyndicate diff --git a/Resources/Prototypes/Entities/Clothing/Back/backpacks.yml b/Resources/Prototypes/Entities/Clothing/Back/backpacks.yml index 5edce6be02..7277ebb10a 100644 --- a/Resources/Prototypes/Entities/Clothing/Back/backpacks.yml +++ b/Resources/Prototypes/Entities/Clothing/Back/backpacks.yml @@ -8,14 +8,13 @@ sprite: Clothing/Back/Backpacks/backpack.rsi state: icon - type: Item - size: Huge + size: 9999 - type: Clothing quickEquip: false slots: - back - type: Storage - maxSlots: 7 - maxTotalWeight: 28 + capacity: 100 - type: ContainerContainer containers: storagebase: !type:Container @@ -197,8 +196,7 @@ - type: Sprite sprite: Clothing/Back/Backpacks/ertleader.rsi - type: Storage - maxSlots: 10 - maxTotalWeight: 40 + capacity: 250 - type: entity parent: ClothingBackpackERTLeader @@ -261,12 +259,8 @@ shader: unshaded - type: Clothing equippedPrefix: holding - - type: Item - size: Ginormous - type: Storage - maxSlots: 14 - maxItemSize: Large - maxTotalWeight: 56 #14 normal-sized items. + capacity: 9999 - type: entity parent: ClothingBackpackClown diff --git a/Resources/Prototypes/Entities/Clothing/Back/duffel.yml b/Resources/Prototypes/Entities/Clothing/Back/duffel.yml index 1fb4b67824..b9cc9ca266 100644 --- a/Resources/Prototypes/Entities/Clothing/Back/duffel.yml +++ b/Resources/Prototypes/Entities/Clothing/Back/duffel.yml @@ -7,8 +7,7 @@ - type: Sprite sprite: Clothing/Back/Duffels/duffel.rsi - type: Storage - maxSlots: 10 - maxTotalWeight: 40 + capacity: 120 - type: ClothingSpeedModifier walkModifier: 1 sprintModifier: 0.9 @@ -163,6 +162,8 @@ components: - type: Sprite sprite: Clothing/Back/Duffels/syndicate.rsi + - type: Storage + capacity: 131 - type: entity parent: ClothingBackpackDuffelSyndicate @@ -227,11 +228,7 @@ - state: icon - state: icon-unlit shader: unshaded - - type: Item - size: Ginormous - type: Storage - maxSlots: 14 - maxItemSize: Large - maxTotalWeight: 56 #14 normal-sized items. + capacity: 9999 - type: ClothingSpeedModifier sprintModifier: 1 # makes its stats identical to other variants of bag of holding diff --git a/Resources/Prototypes/Entities/Clothing/Back/satchel.yml b/Resources/Prototypes/Entities/Clothing/Back/satchel.yml index b3b36b70fb..e80b0d6f8b 100644 --- a/Resources/Prototypes/Entities/Clothing/Back/satchel.yml +++ b/Resources/Prototypes/Entities/Clothing/Back/satchel.yml @@ -167,9 +167,5 @@ - state: icon - state: icon-unlit shader: unshaded - - type: Item - size: Ginormous - type: Storage - maxSlots: 14 - maxItemSize: Large - maxTotalWeight: 56 #14 normal-sized items. + capacity: 9999 diff --git a/Resources/Prototypes/Entities/Clothing/Back/specific.yml b/Resources/Prototypes/Entities/Clothing/Back/specific.yml index c36ddde03b..5964007356 100644 --- a/Resources/Prototypes/Entities/Clothing/Back/specific.yml +++ b/Resources/Prototypes/Entities/Clothing/Back/specific.yml @@ -33,7 +33,7 @@ sprite: Clothing/Back/Backpacks/waterbackpack.rsi state: icon - type: Item - size: Huge + size: 200 - type: Clothing slots: BACK sprite: Clothing/Back/Backpacks/waterbackpack.rsi diff --git a/Resources/Prototypes/Entities/Clothing/Belt/base_clothingbelt.yml b/Resources/Prototypes/Entities/Clothing/Belt/base_clothingbelt.yml index ec6b48bf89..b37d3fd974 100644 --- a/Resources/Prototypes/Entities/Clothing/Belt/base_clothingbelt.yml +++ b/Resources/Prototypes/Entities/Clothing/Belt/base_clothingbelt.yml @@ -6,7 +6,7 @@ - type: Sprite state: icon - type: Item - size: Normal + size: 50 - type: Clothing slots: [belt] quickEquip: false @@ -22,10 +22,7 @@ id: ClothingBeltStorageBase components: - type: Storage - maxSlots: 7 - maxItemSize: Normal - - type: Item - size: Huge + capacity: 40 - type: ContainerContainer containers: storagebase: !type:Container diff --git a/Resources/Prototypes/Entities/Clothing/Belt/belts.yml b/Resources/Prototypes/Entities/Clothing/Belt/belts.yml index 28f8ed0dca..fa1a5e951f 100644 --- a/Resources/Prototypes/Entities/Clothing/Belt/belts.yml +++ b/Resources/Prototypes/Entities/Clothing/Belt/belts.yml @@ -11,7 +11,7 @@ - type: Clothing sprite: Clothing/Belt/utility.rsi - type: Storage - maxItemSize: Normal + capacity: 45 # TODO: Fill this out more. whitelist: tags: @@ -83,6 +83,7 @@ - type: Clothing sprite: Clothing/Belt/ce.rsi - type: Storage + capacity: 105 # TODO: Fill this out more. whitelist: tags: @@ -237,6 +238,7 @@ - type: Clothing sprite: Clothing/Belt/medical.rsi - type: Storage + capacity: 60 whitelist: tags: - Wrench @@ -391,7 +393,7 @@ - type: Clothing sprite: Clothing/Belt/sheath.rsi - type: Storage - maxSlots: 1 + capacity: 15 whitelist: tags: - CaptainSabre @@ -416,8 +418,9 @@ - type: Clothing sprite: Clothing/Belt/bandolier.rsi - type: Item - size: Large + size: 60 - type: Storage + capacity: 60 whitelist: tags: - ShellShotgun @@ -448,7 +451,7 @@ - type: Clothing sprite: Clothing/Belt/holster.rsi - type: Storage - maxSlots: 3 + capacity: 20 - type: entity parent: ClothingBeltStorageBase @@ -461,8 +464,9 @@ - type: Clothing sprite: Clothing/Belt/syndieholster.rsi - type: Item - size: Large + size: 60 - type: Storage + capacity: 60 whitelist: components: - Gun @@ -524,7 +528,9 @@ - type: Clothing sprite: Clothing/Belt/militarywebbingmed.rsi - type: Item - size: Large + size: 70 + - type: Storage + capacity: 70 - type: entity parent: ClothingBeltBase @@ -553,7 +559,7 @@ - type: Clothing sprite: Clothing/Belt/wand.rsi - type: Storage - maxSlots: 8 + capacity: 120 whitelist: tags: - WizardWand diff --git a/Resources/Prototypes/Entities/Clothing/Belt/quiver.yml b/Resources/Prototypes/Entities/Clothing/Belt/quiver.yml index e6685eb47a..10332e46aa 100644 --- a/Resources/Prototypes/Entities/Clothing/Belt/quiver.yml +++ b/Resources/Prototypes/Entities/Clothing/Belt/quiver.yml @@ -12,8 +12,7 @@ visible: false - type: Clothing - type: Storage - maxSlots: 15 - maxItemSize: Small + capacity: 150 whitelist: tags: - Arrow diff --git a/Resources/Prototypes/Entities/Clothing/Belt/waist_bags.yml b/Resources/Prototypes/Entities/Clothing/Belt/waist_bags.yml index e142376d07..6d47010efc 100644 --- a/Resources/Prototypes/Entities/Clothing/Belt/waist_bags.yml +++ b/Resources/Prototypes/Entities/Clothing/Belt/waist_bags.yml @@ -9,9 +9,8 @@ - type: Clothing sprite: Clothing/Belt/waistbag_leather.rsi - type: Storage - maxSlots: 5 - maxItemSize: Small - + capacity: 20 + #Colorization on worn items doesn't work. If this ever gets fixed, you can duplicate this entry and change the color on the sprite to add color variants. #- type: entity # parent: ClothingBeltStorageWaistbag @@ -30,4 +29,4 @@ # layers: # - state: "equipped-BELT" # color: "#bf1313" -# - state: "equipped-trinkets" +# - state: "equipped-trinkets" \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Clothing/Ears/headsets.yml b/Resources/Prototypes/Entities/Clothing/Ears/headsets.yml index 858ec6f0db..cae6a0ea17 100644 --- a/Resources/Prototypes/Entities/Clothing/Ears/headsets.yml +++ b/Resources/Prototypes/Entities/Clothing/Ears/headsets.yml @@ -17,8 +17,6 @@ keySlots: 4 - type: Sprite state: icon - - type: Item - size: Small - type: Clothing slots: - ears diff --git a/Resources/Prototypes/Entities/Clothing/Eyes/base_clothingeyes.yml b/Resources/Prototypes/Entities/Clothing/Eyes/base_clothingeyes.yml index a0c41120b8..dc37811fb8 100644 --- a/Resources/Prototypes/Entities/Clothing/Eyes/base_clothingeyes.yml +++ b/Resources/Prototypes/Entities/Clothing/Eyes/base_clothingeyes.yml @@ -7,5 +7,3 @@ state: icon - type: Clothing slots: [eyes] - - type: Item - size: Small diff --git a/Resources/Prototypes/Entities/Clothing/Hands/base_clothinghands.yml b/Resources/Prototypes/Entities/Clothing/Hands/base_clothinghands.yml index 5cf7fd645b..e7d8bec69f 100644 --- a/Resources/Prototypes/Entities/Clothing/Hands/base_clothinghands.yml +++ b/Resources/Prototypes/Entities/Clothing/Hands/base_clothinghands.yml @@ -9,8 +9,6 @@ slots: [gloves] - type: Food requiresSpecialDigestion: true - - type: Item - size: Small - type: SolutionContainerManager solutions: food: diff --git a/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml b/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml index dd67096b08..19fc25b233 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml @@ -8,8 +8,6 @@ - HEAD - type: Sprite state: icon - - type: Item - size: Small - type: Food requiresSpecialDigestion: true - type: SolutionContainerManager @@ -119,7 +117,7 @@ name: base space helmet components: - type: Item - size: Small + size: 10 - type: PressureProtection highPressureMultiplier: 0.6 lowPressureMultiplier: 1000 @@ -243,4 +241,4 @@ - type: GroupExamine - type: Tag tags: - - HidesHair + - HidesHair \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Clothing/Head/hats.yml b/Resources/Prototypes/Entities/Clothing/Head/hats.yml index 731513d31e..d5d13fbdd0 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/hats.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/hats.yml @@ -197,7 +197,7 @@ - type: Clothing sprite: Clothing/Head/Hats/chefhat.rsi - type: Storage - maxSlots: 1 + capacity: 5 - type: UserInterface interfaces: - key: enum.StorageUiKey.Key @@ -751,10 +751,10 @@ offset: "0, 0.12" sprite: Clothing/Head/Hats/magician.rsi - type: Item - size: Small + size: 10 sprite: Clothing/Head/Hats/magician.rsi - type: Storage - maxSlots: 1 + capacity: 10 - type: UserInterface interfaces: - key: enum.StorageUiKey.Key diff --git a/Resources/Prototypes/Entities/Clothing/Masks/base_clothingmask.yml b/Resources/Prototypes/Entities/Clothing/Masks/base_clothingmask.yml index d57065ba79..b79d76aa17 100644 --- a/Resources/Prototypes/Entities/Clothing/Masks/base_clothingmask.yml +++ b/Resources/Prototypes/Entities/Clothing/Masks/base_clothingmask.yml @@ -5,8 +5,6 @@ components: - type: Sprite state: icon - - type: Item - size: Small - type: Clothing slots: [mask] diff --git a/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml b/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml index 1bccb4c92a..06ec393c78 100644 --- a/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml +++ b/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml @@ -4,7 +4,7 @@ id: ClothingNeckBase components: - type: Item - size: Small + size: 10 - type: Clothing quickEquip: true slots: diff --git a/Resources/Prototypes/Entities/Clothing/Neck/pins.yml b/Resources/Prototypes/Entities/Clothing/Neck/pins.yml index 0d22a653db..fe72fd12e9 100644 --- a/Resources/Prototypes/Entities/Clothing/Neck/pins.yml +++ b/Resources/Prototypes/Entities/Clothing/Neck/pins.yml @@ -6,7 +6,7 @@ description: be nothing do crime components: - type: Item - size: Tiny + size: 1 - type: entity parent: ClothingNeckPinBase diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml index 6af455ab27..f92592f65e 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml @@ -15,7 +15,7 @@ id: ClothingOuterBaseLarge components: - type: Item - size: Large + size: 80 - type: Clothing slots: - outerClothing @@ -28,8 +28,10 @@ parent: ClothingOuterBase id: ClothingOuterStorageBase components: + - type: Item + size: 10 - type: Storage - maxSlots: 3 + capacity: 10 - type: ContainerContainer containers: storagebase: !type:Container @@ -70,7 +72,7 @@ walkModifier: 0.4 sprintModifier: 0.6 - type: Item - size: Huge + size: 121 - type: Armor modifiers: coefficients: @@ -105,7 +107,7 @@ walkModifier: 0.8 sprintModifier: 0.8 - type: Item - size: Large + size: 80 - type: entity parent: ClothingOuterBase @@ -128,7 +130,7 @@ id: ClothingOuterBaseMedium components: - type: Item - size: Large + size: 30 - type: Clothing slots: - outerClothing diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml index 166657d65e..5389eb8bfc 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml @@ -350,7 +350,7 @@ walkModifier: 0.75 sprintModifier: 0.75 - type: Item - size: Normal + size: 50 - type: Tag tags: - WhitelistChameleon diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml index f0aa96f613..16bef8c7b2 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml @@ -176,7 +176,7 @@ - type: Sprite sprite: Clothing/OuterClothing/Suits/iansuit.rsi - type: Item - size: Normal + size: 30 - type: Clothing sprite: Clothing/OuterClothing/Suits/iansuit.rsi - type: ToggleableClothing @@ -197,7 +197,7 @@ - type: Sprite sprite: Clothing/OuterClothing/Suits/carpsuit.rsi - type: Item - size: Normal + size: 30 - type: Clothing sprite: Clothing/OuterClothing/Suits/carpsuit.rsi - type: ToggleableClothing diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml index d15e114857..9bc3d25fc4 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml @@ -11,7 +11,7 @@ - type: TemperatureProtection coefficient: 0.1 - type: Item - size: Small + size: 10 - type: Armor modifiers: coefficients: diff --git a/Resources/Prototypes/Entities/Clothing/Shoes/base_clothingshoes.yml b/Resources/Prototypes/Entities/Clothing/Shoes/base_clothingshoes.yml index 9bd7e00546..c829dc5d44 100644 --- a/Resources/Prototypes/Entities/Clothing/Shoes/base_clothingshoes.yml +++ b/Resources/Prototypes/Entities/Clothing/Shoes/base_clothingshoes.yml @@ -8,8 +8,6 @@ - FEET - type: Sprite state: icon - - type: Item - size: Normal - type: Food requiresSpecialDigestion: true - type: SolutionContainerManager @@ -41,7 +39,7 @@ id: ClothingShoesStorageBase components: - type: Storage - maxSlots: 1 + capacity: 10 - type: ContainerContainer containers: storagebase: !type:Container diff --git a/Resources/Prototypes/Entities/Clothing/Shoes/specific.yml b/Resources/Prototypes/Entities/Clothing/Shoes/specific.yml index eae044f8dd..7b864e806e 100644 --- a/Resources/Prototypes/Entities/Clothing/Shoes/specific.yml +++ b/Resources/Prototypes/Entities/Clothing/Shoes/specific.yml @@ -181,7 +181,7 @@ - state: equipped-FEET offset: "0, -0.02" - type: Item - size: Small + size: 10 sprite: Clothing/Shoes/Specific/large_clown.rsi - type: ClothingSpeedModifier walkModifier: 0.85 diff --git a/Resources/Prototypes/Entities/Clothing/base_clothing.yml b/Resources/Prototypes/Entities/Clothing/base_clothing.yml index 7e9d6e9568..60a94fe291 100644 --- a/Resources/Prototypes/Entities/Clothing/base_clothing.yml +++ b/Resources/Prototypes/Entities/Clothing/base_clothing.yml @@ -3,8 +3,6 @@ parent: BaseItem id: Clothing components: - - type: Item - size: Normal - type: Sprite - type: Tag tags: diff --git a/Resources/Prototypes/Entities/Debugging/debug_sweps.yml b/Resources/Prototypes/Entities/Debugging/debug_sweps.yml index e3289569a2..2d374b8e12 100644 --- a/Resources/Prototypes/Entities/Debugging/debug_sweps.yml +++ b/Resources/Prototypes/Entities/Debugging/debug_sweps.yml @@ -101,7 +101,7 @@ types: Blunt: 20000 - type: Item - size: Tiny + size: 1 sprite: Objects/Weapons/Melee/debug.rsi - type: entity diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index c94d5983e1..adba78141c 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -959,7 +959,7 @@ - map: ["enum.DamageStateVisualLayers.Base"] state: mouse-0 - type: Item - size: Tiny + size: 5 - type: Clothing quickEquip: false sprite: Mobs/Animals/mouse.rsi @@ -1424,7 +1424,7 @@ groups: Brute: 5 - type: Item - size: Normal + size: 80 - type: OnUseTimerTrigger delay: 10 beepSound: @@ -2329,7 +2329,7 @@ - map: ["enum.DamageStateVisualLayers.Base"] state: hamster-0 - type: Item - size: Tiny + size: 5 - type: Physics - type: Fixtures fixtures: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml index 13719f111a..aaeeaf0bf6 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml @@ -172,9 +172,7 @@ graph: SupplyBot node: bot - type: Storage - maxSlots: 15 - maxItemSize: Large - maxTotalWeight: 60 + capacity: 250 - type: UserInterface interfaces: - key: enum.StorageUiKey.Key diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml index 11228d0ed6..118b242136 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml @@ -370,9 +370,9 @@ map: ["6pack6"] visible: false - type: Item - size: Normal + size: 6 - type: Storage - maxSlots: 6 + capacity: 30 whitelist: tags: - Cola diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/bread.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/bread.yml index e4ebcc4c00..a4cb797129 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/bread.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/bread.yml @@ -28,7 +28,7 @@ abstract: true components: - type: Item - size: Tiny + size: 1 - type: FlavorProfile flavors: - bread diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml index 7db9015295..09f5ce27ff 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml @@ -21,7 +21,7 @@ - ReagentId: Vitamin Quantity: 5 - type: Item - size: Normal + size: 25 - type: entity parent: FoodCakeBase @@ -43,7 +43,7 @@ - ReagentId: Vitamin Quantity: 1 - type: Item - size: Tiny + size: 5 # Custom Cake Example @@ -574,7 +574,7 @@ - type: Food transferAmount: 12 - type: Item - size: Normal + size: 40 - type: PointLight color: "#FFFF00" radius: 2 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donkpocket.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donkpocket.yml index b0be8011aa..061852f561 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donkpocket.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donkpocket.yml @@ -16,7 +16,7 @@ - ReagentId: Nutriment Quantity: 3 - type: Item - size: Tiny + size: 1 - type: Tag tags: - DonkPocket diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donut.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donut.yml index 9cf32f30b4..bd007d87cb 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donut.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donut.yml @@ -21,7 +21,7 @@ Quantity: 3 - type: Item sprite: Objects/Consumable/Food/Baked/donut.rsi - size: Tiny + size: 1 # Tastes like donut. # The sprinkles are now an overlay, so you can put them on any donut! If we really diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/misc.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/misc.yml index 1296bc4752..54fc4d6553 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/misc.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/misc.yml @@ -16,7 +16,7 @@ - ReagentId: Nutriment Quantity: 5 - type: Item - size: Tiny + size: 1 # Muffins/Buns diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/pizza.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/pizza.yml index 01f93ccced..1f6a307f4e 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/pizza.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/pizza.yml @@ -24,7 +24,7 @@ - type: SliceableFood count: 8 - type: Item - size: Normal + size: 8 - type: Tag tags: - Pizza @@ -53,7 +53,7 @@ - ReagentId: Vitamin Quantity: 0.8 - type: Item - size: Tiny + size: 1 - type: Tag tags: - Pizza diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/box.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/box.yml index 5cf48d3c9b..5130b9d7e2 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/box.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/box.yml @@ -38,14 +38,13 @@ map: ["pink-box6"] visible: false - type: Storage - maxSlots: 6 - maxTotalWeight: 12 + capacity: 6 whitelist: tags: - Donut - type: Item sprite: Objects/Consumable/Food/Baked/donut.rsi - size: Small + size: 6 heldPrefix: box - type: StorageFill contents: @@ -119,13 +118,13 @@ map: ["box12"] visible: false - type: Storage - maxSlots: 12 + capacity: 12 whitelist: tags: - Egg - type: Item sprite: Objects/Consumable/Food/egg.rsi - size: Small + size: 12 - type: StorageFill contents: - id: FoodEgg @@ -176,9 +175,6 @@ id: EggBoxBroken suffix: Broken components: - - type: Storage - maxSlots: 12 - maxItemSize: Small - type: StorageFill contents: - id: Eggshells @@ -210,8 +206,7 @@ map: ["enum.StorageVisualLayers.Door"] # TODO make these entitystorage again + placeablesurface after entity storage ECS gets merged. - type: Storage - maxSlots: 1 - maxItemSize: Normal + capacity: 8 whitelist: tags: - Pizza @@ -301,10 +296,10 @@ map: ["box6"] visible: false - type: Storage - maxSlots: 6 + capacity: 6 - type: Item sprite: Objects/Consumable/Food/Baked/nuggets.rsi - size: Small + size: 6 heldPrefix: box - type: StorageFill contents: @@ -338,10 +333,10 @@ whitelist: tags: - DonkPocket - maxSlots: 6 + capacity: 6 - type: Item sprite: Objects/Consumable/Food/Baked/donkpocket.rsi - size: Small + size: 6 - type: StorageFill contents: - id: FoodDonkpocket @@ -463,6 +458,8 @@ - type: Item sprite: Objects/Storage/Happyhonk/clown.rsi heldPrefix: box + - type: Storage + capacity: 30 - type: Tag tags: - Trash @@ -586,8 +583,10 @@ suffix: Toy Unsafe, Snacks name: syndicate snack box components: + - type: Item + size: 64 - type: Storage - maxSlots: 9 + capacity: 64 # need more room for goodies - type: StorageFill contents: # toy diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/tin.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/tin.yml index 89ec5a8c27..4e63ca5012 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/tin.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/tin.yml @@ -37,7 +37,7 @@ - type: Item sprite: Objects/Consumable/Food/snacks.rsi heldPrefix: packet - size: Tiny + size: 3 - type: DamageOnLand damage: types: @@ -63,7 +63,7 @@ - type: Item sprite: Objects/Consumable/Food/snacks.rsi heldPrefix: packet - size: Tiny + size: 3 - type: PhysicalComposition materialComposition: Steel: 100 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml index 3eb2b96684..4f6d10d98f 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml @@ -16,7 +16,7 @@ sprite: Objects/Consumable/Food/egg.rsi - type: Item sprite: Objects/Consumable/Food/egg.rsi - size: Tiny + size: 1 - type: SolutionContainerManager solutions: food: @@ -69,7 +69,7 @@ sprite: Objects/Consumable/Food/egg.rsi state: eggshells - type: Item - size: Tiny + size: 1 - type: SolutionContainerManager solutions: food: diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml index 2b7c9d6e16..35057aeacd 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml @@ -24,7 +24,7 @@ - ReagentId: Fat Quantity: 5 - type: Item - size: Tiny + size: 5 - type: Fixtures fixtures: fix1: @@ -209,7 +209,7 @@ graph: BearSteak node: start defaultTarget: filet migrawr - + - type: entity name: raw penguin meat diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml index 0fb8afc6d7..6439b2eb6c 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml @@ -136,7 +136,7 @@ - type: Sprite sprite: Objects/Specific/Hydroponics/nettle.rsi - type: Item - size: Small + size: 10 sprite: Objects/Specific/Hydroponics/nettle.rsi - type: MeleeWeapon damage: @@ -166,7 +166,7 @@ - type: Sprite sprite: Objects/Specific/Hydroponics/death_nettle.rsi - type: Item - size: Small + size: 10 sprite: Objects/Specific/Hydroponics/death_nettle.rsi - type: MeleeWeapon damage: @@ -184,7 +184,7 @@ - type: Produce seedId: deathNettle - type: MeleeChemicalInjector - transferAmount: 6 + transferAmount: 6 solution: food pierceArmor: true # We do a little trolling - type: Extractable @@ -222,7 +222,7 @@ - type: Tag tags: - Fruit - + - type: entity name: mimana parent: FoodProduceBase @@ -314,7 +314,7 @@ state: peel - type: Item sprite: Objects/Specific/Hydroponics/mimana.rsi - heldPrefix: peel + heldPrefix: peel - type: Slippery slipSound: path: /Audio/Effects/slip.ogg @@ -836,7 +836,7 @@ sprite: Objects/Specific/Hydroponics/corn.rsi state: cob - type: Item - size: Tiny + size: 1 - type: Tag tags: - Trash @@ -1237,7 +1237,7 @@ - type: Tag tags: - Galaxythistle - - Fruit # Probably? + - Fruit # Probably? - type: entity name: fly amanita @@ -1365,7 +1365,7 @@ description: Round green object that you can slice and eat. components: - type: Item - size: Small + size: 10 - type: FlavorProfile flavors: - watermelon @@ -1427,7 +1427,7 @@ description: Juicy green and red slice. components: - type: Item - size: Tiny + size: 2 - type: FlavorProfile flavors: - watermelon diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/skewer.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/skewer.yml index 8c8f55f804..0b32de1ce5 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/skewer.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/skewer.yml @@ -17,7 +17,7 @@ - ReagentId: Nutriment Quantity: 8 - type: Item - size: Small + size: 5 # Kebabs diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/snacks.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/snacks.yml index 82c31a01c5..c2274aef6d 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/snacks.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/snacks.yml @@ -21,7 +21,7 @@ - type: Item sprite: Objects/Consumable/Food/snacks.rsi heldPrefix: packet - size: Tiny + size: 3 # Snacks # "Snacks" means food in a packet. Down the line this stuff can have multiple @@ -101,7 +101,7 @@ state: chocolatebar - type: Item heldPrefix: chocolatebar - size: Tiny + size: 3 - type: Tag tags: - FoodSnack @@ -346,7 +346,7 @@ - type: Item sprite: Objects/Consumable/Food/snacks.rsi heldPrefix: packet - size: Tiny + size: 1 - type: Food trash: FoodCookieFortune @@ -357,7 +357,7 @@ description: A carefully synthesized brick designed to contain the highest ratio of nutriment to volume. Tastes like shit. components: - type: Item - size: Small + size: 10 - type: Tag tags: - FoodSnack @@ -381,7 +381,7 @@ flavors: - nutribrick - type: Item - size: Small + size: 10 - type: Sprite state: nutribrick-open - type: Food diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cartons.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cartons.yml index eff790cdd1..4d0b442c46 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cartons.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cartons.yml @@ -10,9 +10,11 @@ - state: closed - state: open map: ["openLayer"] + - type: Storage + capacity: 36 - type: Item sprite: Objects/Consumable/Smokeables/Cigarettes/Cartons/green.rsi - size: Normal + size: 36 - type: StorageFill contents: - id: CigPackGreen diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cigarette.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cigarette.yml index 3543db2ed1..09ac79b141 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cigarette.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cigarette.yml @@ -17,7 +17,7 @@ slots: [ mask ] equippedPrefix: unlit - type: Item - size: Tiny + size: 1 - type: Construction graph: smokeableCigarette node: cigarette @@ -41,7 +41,7 @@ slots: [ mask ] equippedPrefix: unlit - type: Item - size: Tiny + size: 1 - type: Construction graph: smokeableCigarette node: cigarette diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/joints.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/joints.yml index e3ae06ec9f..402dcd80f5 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/joints.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/joints.yml @@ -17,7 +17,7 @@ slots: [ mask ] equippedPrefix: unlit - type: Item - size: Tiny + size: 1 - type: Construction graph: smokeableJoint node: joint @@ -48,7 +48,7 @@ slots: [ mask ] equippedPrefix: unlit - type: Item - size: Tiny + size: 1 - type: Construction graph: smokeableBlunt node: blunt diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/packs.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/packs.yml index 6bc14cfb77..1d161b160a 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/packs.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/packs.yml @@ -43,9 +43,9 @@ Steel: 50 - type: SpaceGarbage - type: Storage - maxSlots: 5 + capacity: 5 - type: Item - size: Small + size: 5 - type: StorageFill contents: - id: Cigarette @@ -108,10 +108,9 @@ Steel: 50 - type: SpaceGarbage - type: Storage - maxSlots: 10 - maxTotalWeight: 20 + capacity: 10 - type: Item - size: Small + size: 10 - type: StorageFill contents: - id: CigaretteRandom diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/rolling_paper.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/rolling_paper.yml index 324a28caca..e1005bf113 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/rolling_paper.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/rolling_paper.yml @@ -9,7 +9,7 @@ tags: - RollingPaper - CigFilter - maxSlots: 20 + capacity: 20 - type: StorageFill contents: - id: PaperRolling @@ -31,6 +31,7 @@ tags: - RollingPaper - CigFilter + capacity: 32 - type: StorageFill contents: - id: PaperRolling @@ -53,7 +54,7 @@ state: cigpaper - type: Item sprite: Objects/Consumable/Smokeables/Cigarettes/paper.rsi - size: Tiny + size: 5 - type: Tag tags: - RollingPaper @@ -67,6 +68,8 @@ components: - type: Stack count: 1 + - type: Item + size: 1 - type: entity id: CigaretteFilter @@ -83,7 +86,7 @@ state: cigfilter - type: Item sprite: Objects/Consumable/Smokeables/Cigarettes/paper.rsi - size: Tiny + size: 10 - type: Tag tags: - CigFilter @@ -96,3 +99,5 @@ components: - type: Stack count: 1 + - type: Item + size: 2 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/case.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/case.yml index eede84cd4b..6034df179a 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/case.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/case.yml @@ -35,10 +35,10 @@ map: ["cigar8"] visible: false - type: Storage - maxSlots: 8 + capacity: 8 - type: Item sprite: Objects/Consumable/Smokeables/Cigars/case.rsi - size: Small + size: 8 - type: StorageFill contents: - id: Cigar diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/cigar.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/cigar.yml index 3495ae26f9..4ed5912fc5 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/cigar.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/cigar.yml @@ -19,7 +19,7 @@ slots: [ mask ] equippedPrefix: unlit - type: Item - size: Tiny + size: 1 - type: entity id: CigarSpent @@ -49,7 +49,7 @@ slots: [ mask ] equippedPrefix: unlit - type: Item - size: Tiny + size: 1 - type: entity id: CigarGoldSpent diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Pipes/pipe.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Pipes/pipe.yml index 7d2b234a58..21017465bc 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Pipes/pipe.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Pipes/pipe.yml @@ -12,7 +12,7 @@ slots: [ mask ] equippedPrefix: unlit - type: Item - size: Tiny + size: 3 sprite: Objects/Consumable/Smokeables/Pipes/pipe.rsi - type: Appearance - type: BurnStateVisuals diff --git a/Resources/Prototypes/Entities/Objects/Decoration/lidsalami.yml b/Resources/Prototypes/Entities/Objects/Decoration/lidsalami.yml index 65141af36f..dfff087e22 100644 --- a/Resources/Prototypes/Entities/Objects/Decoration/lidsalami.yml +++ b/Resources/Prototypes/Entities/Objects/Decoration/lidsalami.yml @@ -9,6 +9,6 @@ layers: - state: icon - type: Item - size: Huge + size: 1001 - type: StaticPrice price: 0 diff --git a/Resources/Prototypes/Entities/Objects/Decoration/present.yml b/Resources/Prototypes/Entities/Objects/Decoration/present.yml index a7fd1cd1de..14a1dfbb5e 100644 --- a/Resources/Prototypes/Entities/Objects/Decoration/present.yml +++ b/Resources/Prototypes/Entities/Objects/Decoration/present.yml @@ -15,7 +15,9 @@ suffix: Empty components: - type: Item - size: Normal + size: 30 + - type: Storage + capacity: 30 - type: entity id: PresentRandomUnsafe diff --git a/Resources/Prototypes/Entities/Objects/Devices/Electronics/triggers.yml b/Resources/Prototypes/Entities/Objects/Devices/Electronics/triggers.yml index c462a3cb03..4bb13bdd93 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Electronics/triggers.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Electronics/triggers.yml @@ -17,7 +17,7 @@ sprite: Objects/Devices/timer.rsi state: timer - type: Item - size: Small + size: 5 - type: PayloadTrigger components: - type: OnUseTimerTrigger diff --git a/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/chimp_upgrade_kit.yml b/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/chimp_upgrade_kit.yml index fc6c2ac787..aed09fe70b 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/chimp_upgrade_kit.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/chimp_upgrade_kit.yml @@ -6,9 +6,9 @@ components: - type: Sprite sprite: Objects/Misc/module.rsi - state: abductor_mod + state: abductor_mod - type: Item - size: Small + size: 10 - type: Tag tags: - - WeaponPistolCHIMPUpgradeKit + - WeaponPistolCHIMPUpgradeKit \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Objects/Devices/forensic_scanner.yml b/Resources/Prototypes/Entities/Objects/Devices/forensic_scanner.yml index 21943bfaff..ad05777cfa 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/forensic_scanner.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/forensic_scanner.yml @@ -8,7 +8,7 @@ sprite: Objects/Devices/forensic_scanner.rsi state: forensicnew - type: Item - size: Small + size: 5 - type: Clothing sprite: Objects/Devices/forensic_scanner.rsi quickEquip: false diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml index 91becb5251..f44f1aa998 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml @@ -37,7 +37,7 @@ components: - IdCard - type: Item - size: Tiny + size: 10 - type: ContainerContainer containers: PDA-id: !type:ContainerSlot {} diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/base_instruments.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/base_instruments.yml index 07d918b576..06b2301262 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/base_instruments.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/base_instruments.yml @@ -16,7 +16,7 @@ - key: enum.InstrumentUiKey.Key type: InstrumentBoundUserInterface - type: Item - size: Normal + size: 24 - type: StaticPrice price: 200 diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_brass.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_brass.yml index 260490ccad..e8ac6f7ce5 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_brass.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_brass.yml @@ -14,7 +14,7 @@ sprite: Objects/Fun/Instruments/trumpet.rsi state: icon - type: Item - size: Normal + size: 24 sprite: Objects/Fun/Instruments/trumpet.rsi - type: Tag tags: @@ -32,7 +32,7 @@ sprite: Objects/Fun/Instruments/trombone.rsi state: icon - type: Item - size: Normal + size: 48 sprite: Objects/Fun/Instruments/trombone.rsi - type: Tag tags: @@ -50,7 +50,7 @@ sprite: Objects/Fun/Instruments/frenchhorn.rsi state: icon - type: Item - size: Normal + size: 48 sprite: Objects/Fun/Instruments/frenchhorn.rsi - type: Tag tags: @@ -69,7 +69,7 @@ sprite: Objects/Fun/Instruments/euphonium.rsi state: icon - type: Item - size: Normal + size: 48 sprite: Objects/Fun/Instruments/euphonium.rsi - type: Tag tags: diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_misc.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_misc.yml index 47ea5ab2f6..15581cbd8d 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_misc.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_misc.yml @@ -10,7 +10,7 @@ - type: Instrument program: 121 - type: Item - size: Small + size: 10 - type: entity parent: BaseHandheldInstrument @@ -24,7 +24,7 @@ - type: Instrument program: 122 - type: Item - size: Small + size: 10 - type: entity parent: BaseHandheldInstrument @@ -38,7 +38,7 @@ - type: Instrument program: 123 - type: Item - size: Tiny + size: 5 - type: entity parent: BaseHandheldInstrument @@ -55,7 +55,7 @@ - type: Instrument program: 124 - type: Item - size: Small + size: 10 - type: Prayable sentMessage: prayer-popup-notify-centcom-sent notifiactionPrefix: prayer-chat-notify-centcom @@ -74,7 +74,7 @@ - type: Instrument program: 125 - type: Item - size: Small + size: 10 - type: entity parent: BaseHandheldInstrument @@ -88,7 +88,7 @@ - type: Instrument program: 126 - type: Item - size: Tiny + size: 5 - type: entity parent: BaseHandheldInstrument @@ -102,7 +102,7 @@ sprite: Objects/Fun/Instruments/gunpet.rsi state: icon - type: Item - size: Normal + size: 15 sprite: Objects/Fun/Instruments/gunpet.rsi - type: Tag tags: @@ -125,7 +125,7 @@ - BrassInstrument #Go figure. - type: Item sprite: Objects/Fun/Instruments/bike_horn.rsi - size: Small + size: 10 - type: Clothing sprite: Objects/Fun/Instruments/bike_horn.rsi slots: [Belt] diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_percussion.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_percussion.yml index d79b354df4..1ab803c5e2 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_percussion.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_percussion.yml @@ -9,7 +9,7 @@ sprite: Objects/Fun/Instruments/glockenspiel.rsi state: icon - type: Item - size: Normal + size: 24 sprite: Objects/Fun/Instruments/glockenspiel.rsi - type: Tag tags: @@ -58,7 +58,7 @@ sprite: Objects/Fun/Instruments/microphone.rsi state: icon - type: Item - size: Small + size: 10 sprite: Objects/Fun/Instruments/microphone.rsi - type: entity @@ -76,7 +76,7 @@ sprite: Objects/Fun/Instruments/h_synthesizer.rsi state: icon - type: Item - size: Normal + size: 24 sprite: Objects/Fun/Instruments/h_synthesizer.rsi - type: Tag tags: @@ -135,5 +135,5 @@ sprite: Objects/Fun/Instruments/h_synthesizer.rsi state: icon - type: Item - size: Normal - sprite: Objects/Fun/Instruments/h_synthesizer.rsi + size: 24 + sprite: Objects/Fun/Instruments/h_synthesizer.rsi \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_string.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_string.yml index 70d1444bc4..c71fecd91b 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_string.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_string.yml @@ -15,7 +15,7 @@ sprite: Objects/Fun/Instruments/eguitar.rsi state: icon - type: Item - size: Normal + size: 24 sprite: Objects/Fun/Instruments/eguitar.rsi - type: Clothing quickEquip: false @@ -44,7 +44,7 @@ sprite: Objects/Fun/Instruments/bassguitar.rsi state: icon - type: Item - size: Normal + size: 24 sprite: Objects/Fun/Instruments/bassguitar.rsi - type: Clothing quickEquip: false @@ -72,7 +72,7 @@ sprite: Objects/Fun/Instruments/rockguitar.rsi state: icon - type: Item - size: Normal + size: 24 sprite: Objects/Fun/Instruments/rockguitar.rsi - type: Clothing quickEquip: false @@ -115,7 +115,7 @@ - StringInstrument - type: Item sprite: Objects/Fun/Instruments/guitar.rsi - size: Normal + size: 24 - type: Clothing quickEquip: false slots: @@ -178,7 +178,7 @@ sprite: Objects/Fun/Instruments/banjo.rsi state: icon - type: Item - size: Normal + size: 24 sprite: Objects/Fun/Instruments/banjo.rsi - type: Tag tags: @@ -200,7 +200,7 @@ sprite: Objects/Fun/Instruments/violin.rsi state: icon - type: Item - size: Normal + size: 24 sprite: Objects/Fun/Instruments/violin.rsi - type: Tag tags: @@ -218,7 +218,7 @@ sprite: Objects/Fun/Instruments/viola.rsi state: icon - type: Item - size: Normal + size: 24 sprite: Objects/Fun/Instruments/viola.rsi - type: Tag tags: @@ -236,7 +236,7 @@ sprite: Objects/Fun/Instruments/cello.rsi state: icon - type: Item - size: Normal + size: 48 sprite: Objects/Fun/Instruments/cello.rsi - type: Tag tags: diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_wind.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_wind.yml index afba6c2774..09db613313 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_wind.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_wind.yml @@ -16,7 +16,7 @@ sprite: Objects/Fun/Instruments/saxophone.rsi state: icon - type: Item - size: Normal + size: 24 sprite: Objects/Fun/Instruments/saxophone.rsi - type: Tag tags: @@ -45,7 +45,7 @@ sprite: Objects/Fun/Instruments/accordion.rsi state: icon - type: Item - size: Normal + size: 24 sprite: Objects/Fun/Instruments/accordion.rsi - type: Tag tags: @@ -62,7 +62,7 @@ sprite: Objects/Fun/Instruments/harmonica.rsi state: icon - type: Item - size: Small + size: 10 sprite: Objects/Fun/Instruments/harmonica.rsi - type: Tag tags: @@ -80,7 +80,7 @@ sprite: Objects/Fun/Instruments/clarinet.rsi state: icon - type: Item - size: Normal + size: 20 sprite: Objects/Fun/Instruments/clarinet.rsi - type: Tag tags: @@ -98,7 +98,7 @@ sprite: Objects/Fun/Instruments/flute.rsi state: icon - type: Item - size: Normal + size: 20 sprite: Objects/Fun/Instruments/flute.rsi - type: Tag tags: @@ -116,7 +116,7 @@ sprite: Objects/Fun/Instruments/recorder.rsi state: icon - type: Item - size: Normal + size: 24 sprite: Objects/Fun/Instruments/recorder.rsi - type: Tag tags: @@ -134,7 +134,7 @@ sprite: Objects/Fun/Instruments/panflute.rsi state: icon - type: Item - size: Normal + size: 15 sprite: Objects/Fun/Instruments/panflute.rsi - type: Tag tags: @@ -153,7 +153,7 @@ sprite: Objects/Fun/Instruments/ocarina.rsi state: icon - type: Item - size: Normal + size: 15 sprite: Objects/Fun/Instruments/ocarina.rsi - type: Tag tags: @@ -171,8 +171,8 @@ sprite: Objects/Fun/Instruments/bagpipes.rsi state: icon - type: Item - size: Normal + size: 48 sprite: Objects/Fun/Instruments/bagpipes.rsi - type: Tag tags: - - WoodwindInstrument + - WoodwindInstrument \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Objects/Fun/bike_horn.yml b/Resources/Prototypes/Entities/Objects/Fun/bike_horn.yml index 58b168e882..fc20f1a58d 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/bike_horn.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/bike_horn.yml @@ -9,7 +9,7 @@ state: icon - type: Item sprite: Objects/Fun/bikehorn.rsi - size: Tiny + size: 5 - type: Clothing sprite: Objects/Fun/bikehorn.rsi slots: [Belt] @@ -58,7 +58,7 @@ state: icon - type: Item sprite: Objects/Fun/cluwnehorn.rsi - size: Tiny + size: 5 - type: Clothing sprite: Objects/Fun/cluwnehorn.rsi slots: [Belt] @@ -100,7 +100,7 @@ state: icon - type: Item sprite: Objects/Fun/goldbikehorn.rsi - size: Tiny + size: 5 - type: Clothing sprite: Objects/Fun/goldbikehorn.rsi slots: [Belt] @@ -119,7 +119,7 @@ state: icon - type: Item sprite: Objects/Fun/bananiumhorn.rsi - size: Tiny + size: 5 - type: Clothing sprite: Objects/Fun/bananiumhorn.rsi slots: [Belt] diff --git a/Resources/Prototypes/Entities/Objects/Fun/crayons.yml b/Resources/Prototypes/Entities/Objects/Fun/crayons.yml index 2ec93b9c9b..3ed188bd8e 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/crayons.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/crayons.yml @@ -9,7 +9,7 @@ sprite: Objects/Fun/crayons.rsi - type: Item sprite: Objects/Fun/crayons.rsi - size: Tiny + size: 1 - type: Tag tags: - Write @@ -235,11 +235,10 @@ sprite: Objects/Fun/crayons.rsi state: box - type: Storage - maxSlots: 7 - maxTotalWeight: 7 + capacity: 7 - type: Item sprite: Objects/Fun/crayons.rsi - size: Small + size: 7 heldPrefix: box - type: StorageFill contents: diff --git a/Resources/Prototypes/Entities/Objects/Fun/darts.yml b/Resources/Prototypes/Entities/Objects/Fun/darts.yml index 34486ac93e..bd4163d974 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/darts.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/darts.yml @@ -40,7 +40,7 @@ types: Piercing: 4 - type: Item - size: Tiny + size: 2 sprite: Objects/Fun/Darts/dart_red.rsi - type: ItemCooldown - type: SolutionContainerManager @@ -86,7 +86,7 @@ - type: SolutionContainerVisuals maxFillLevels: 1 fillBaseName: dart - + - type: entity parent: Dart id: DartBlue @@ -95,7 +95,7 @@ sprite: Objects/Fun/Darts/dart_blue.rsi - type: Item sprite: Objects/Fun/Darts/dart_blue.rsi - + - type: entity parent: Dart id: DartPurple @@ -104,7 +104,7 @@ sprite: Objects/Fun/Darts/dart_purple.rsi - type: Item sprite: Objects/Fun/Darts/dart_purple.rsi - + - type: entity parent: Dart id: DartYellow diff --git a/Resources/Prototypes/Entities/Objects/Fun/dice.yml b/Resources/Prototypes/Entities/Objects/Fun/dice.yml index d2c33b90f0..6903a0bcac 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/dice.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/dice.yml @@ -13,7 +13,7 @@ tags: - Dice - type: Item - size: Tiny + size: 2 - type: entity parent: BaseDice diff --git a/Resources/Prototypes/Entities/Objects/Fun/dice_bag.yml b/Resources/Prototypes/Entities/Objects/Fun/dice_bag.yml index 20c3c12736..8c3b5aea8b 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/dice_bag.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/dice_bag.yml @@ -17,11 +17,11 @@ sprite: Objects/Fun/dice.rsi state: dicebag - type: Item - size: Small - type: Storage + capacity: 18 whitelist: tags: - - Dice + - Dice - type: entity parent: DiceBag @@ -32,5 +32,4 @@ sprite: Objects/Fun/dice.rsi state: magicdicebag - type: Storage - maxSlots: 14 - maxTotalWeight: 28 + capacity: 30 diff --git a/Resources/Prototypes/Entities/Objects/Fun/puppet.yml b/Resources/Prototypes/Entities/Objects/Fun/puppet.yml index 01a15d2e5b..c0649d0acf 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/puppet.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/puppet.yml @@ -14,7 +14,7 @@ - type: DoAfter - type: VentriloquistPuppet - type: Item - size: Normal + size: 30 - type: Muted - type: TypingIndicator proto: robot diff --git a/Resources/Prototypes/Entities/Objects/Fun/toys.yml b/Resources/Prototypes/Entities/Objects/Fun/toys.yml index c326fc9707..491ae0037a 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/toys.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/toys.yml @@ -554,7 +554,7 @@ components: - type: Sprite - type: Item - size: Normal + size: 24 - type: entity parent: FoamWeaponBase @@ -566,7 +566,7 @@ sprite: Objects/Fun/toys.rsi state: foamcrossbow - type: Item - size: Normal + size: 24 sprite: Objects/Fun/toys.rsi heldPrefix: foamcrossbow - type: Gun @@ -672,7 +672,7 @@ types: Blunt: 0 - type: Item - size: Small + size: 20 sprite: Objects/Fun/toys.rsi heldPrefix: foamblade - type: ItemCooldown @@ -692,7 +692,7 @@ sound: path: /Audio/Effects/Footsteps/bounce.ogg - type: Item - size: Normal + size: 24 sprite: Objects/Fun/toys.rsi heldPrefix: bask - type: TileFrictionModifier @@ -708,7 +708,7 @@ sprite: Objects/Fun/toys.rsi state: football - type: Item - size: Small + size: 12 sprite: Objects/Fun/toys.rsi heldPrefix: footb @@ -725,7 +725,7 @@ sound: path: /Audio/Effects/Footsteps/bounce.ogg - type: Item - size: Normal + size: 24 sprite: Objects/Fun/toys.rsi heldPrefix: beachb - type: TileFrictionModifier @@ -741,7 +741,7 @@ sprite: Objects/Fun/toys.rsi state: synb - type: Item - size: Small + size: 24 sprite: Objects/Fun/toys.rsi heldPrefix: synb - type: Damageable @@ -760,7 +760,7 @@ sprite: Objects/Fun/toys.rsi state: corgib - type: Item - size: Normal + size: 24 sprite: Objects/Fun/toys.rsi heldPrefix: corgib - type: Damageable @@ -785,7 +785,7 @@ intensity: 2000 falloffPower: 2.6 - type: Item - size: Small + size: 12 sprite: Objects/Fun/toys.rsi heldPrefix: singularitytoy @@ -803,7 +803,7 @@ radius: 2 color: "#00CCFF" - type: Item - size: Normal + size: 24 sprite: Objects/Fun/toys.rsi heldPrefix: orb - type: TileFrictionModifier @@ -828,7 +828,7 @@ shader: unshaded map: [ "blade" ] - type: Item - size: Small + size: 5 sprite: Objects/Weapons/Melee/e_sword.rsi - type: UseDelay delay: 1.0 @@ -892,7 +892,7 @@ types: Blunt: 0 - type: Item - size: Normal + size: 15 sprite: Objects/Weapons/Melee/cutlass.rsi - type: entity @@ -934,7 +934,7 @@ - type: StaminaDamageOnHit damage: 8 - type: Item - size: Small + size: 5 sprite: Objects/Fun/rubber_hammer.rsi - type: Appearance - type: DisarmMalus diff --git a/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml b/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml index 898d2c37c1..2c1a8e628d 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml @@ -9,7 +9,7 @@ sprite: Objects/Materials/Sheets/glass.rsi - type: Item sprite: Objects/Materials/Sheets/glass.rsi - size: Normal + size: 30 - type: StaticPrice price: 0 - type: Tag @@ -83,6 +83,8 @@ - type: Stack stackType: Glass count: 10 + - type: Item + size: 10 - type: entity parent: SheetGlass @@ -94,12 +96,16 @@ - type: Stack stackType: Glass count: 1 + - type: Item + size: 1 - type: entity parent: SheetGlass id: SheetGlassLingering0 suffix: Lingering, 0 components: + - type: Item + size: 0 - type: Stack lingering: true count: 0 @@ -168,6 +174,8 @@ - type: Stack stackType: ReinforcedGlass count: 1 + - type: Item + size: 1 - type: entity parent: SheetGlassBase @@ -193,6 +201,7 @@ map: ["base"] - type: Item heldPrefix: pglass + size: 30 - type: Construction graph: Glass node: SheetPGlass @@ -230,6 +239,8 @@ - type: Stack stackType: PlasmaGlass count: 1 + - type: Item + size: 1 - type: entity parent: SheetPGlass @@ -270,6 +281,8 @@ - type: Stack stackType: ReinforcedPlasmaGlass count: 1 + - type: Item + size: 1 - type: entity parent: SheetGlassBase @@ -332,6 +345,8 @@ - type: Stack stackType: UraniumGlass count: 1 + - type: Item + size: 1 - type: entity parent: SheetUGlass @@ -371,3 +386,5 @@ - type: Stack stackType: ReinforcedUraniumGlass count: 1 + - type: Item + size: 1 diff --git a/Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml b/Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml index 99c7ae0e11..69b7f83ddb 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml @@ -8,7 +8,7 @@ sprite: Objects/Materials/Sheets/metal.rsi - type: Item sprite: Objects/Materials/Sheets/metal.rsi - size: Normal + size: 30 - type: StaticPrice price: 0 - type: Tag @@ -75,6 +75,8 @@ name: steel suffix: 10 components: + - type: Item + size: 10 - type: Sprite state: steel - type: Stack @@ -87,6 +89,8 @@ name: steel suffix: Single components: + - type: Item + size: 1 - type: Sprite state: steel - type: Stack @@ -98,6 +102,8 @@ id: SheetSteelLingering0 suffix: Lingering, 0 components: + - type: Item + size: 0 - type: Stack lingering: true count: 0 @@ -139,6 +145,8 @@ - type: Stack stackType: Plasteel count: 10 + - type: Item + size: 10 - type: entity parent: SheetPlasteel @@ -151,3 +159,5 @@ - type: Stack stackType: Plasteel count: 1 + - type: Item + size: 1 diff --git a/Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml b/Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml index ed1a1e3da0..3cb6f027a9 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml @@ -8,7 +8,7 @@ sprite: Objects/Materials/Sheets/other.rsi - type: Item sprite: Objects/Materials/Sheets/other.rsi - size: Normal + size: 30 - type: Tag tags: - Sheet @@ -56,6 +56,8 @@ state: paper - type: Stack count: 1 + - type: Item + size: 1 - type: entity parent: SheetOtherBase @@ -104,6 +106,8 @@ state: plasma - type: Stack count: 1 + - type: Item + size: 1 - type: entity parent: SheetOtherBase @@ -134,6 +138,7 @@ map: ["base"] - type: Item heldPrefix: plastic + size: 30 - type: Appearance - type: entity @@ -144,6 +149,8 @@ components: - type: Sprite state: plastic + - type: Item + size: 10 - type: Stack count: 10 @@ -155,6 +162,8 @@ components: - type: Sprite state: plastic + - type: Item + size: 1 - type: Stack count: 1 @@ -203,6 +212,8 @@ components: - type: Stack count: 1 + - type: Item + size: 1 - type: entity parent: SheetOtherBase @@ -244,3 +255,5 @@ state: meat - type: Stack count: 1 + - type: Item + size: 1 diff --git a/Resources/Prototypes/Entities/Objects/Materials/ingots.yml b/Resources/Prototypes/Entities/Objects/Materials/ingots.yml index d383a7266d..61aefee332 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/ingots.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/ingots.yml @@ -8,7 +8,7 @@ sprite: Objects/Materials/ingots.rsi - type: Item sprite: Objects/Materials/ingots.rsi - size: Normal + size: 30 - type: StaticPrice price: 0 - type: Tag @@ -62,6 +62,8 @@ state: gold - type: Stack count: 1 + - type: Item + size: 1 - type: entity parent: IngotBase @@ -97,3 +99,7 @@ components: - type: Sprite state: silver + - type: Stack + count: 1 + - type: Item + size: 1 diff --git a/Resources/Prototypes/Entities/Objects/Materials/materials.yml b/Resources/Prototypes/Entities/Objects/Materials/materials.yml index 4af2886c24..7386eaee4d 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/materials.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/materials.yml @@ -8,7 +8,7 @@ sprite: Objects/Materials/materials.rsi - type: Item sprite: Objects/Materials/materials.rsi - size: Normal + size: 30 - type: Tag tags: - DroneUsable @@ -47,6 +47,8 @@ - state: cardboard_3 map: ["base"] - type: Appearance + - type: Item + size: 30 - type: entity parent: MaterialCardboard @@ -57,6 +59,8 @@ state: cardboard - type: Stack count: 10 + - type: Item + size: 10 - type: entity parent: MaterialCardboard @@ -67,6 +71,8 @@ state: cardboard - type: Stack count: 1 + - type: Item + size: 1 - type: entity parent: MaterialBase @@ -108,6 +114,8 @@ - state: cloth_3 map: ["base"] - type: Appearance + - type: Item + size: 30 - type: Food requiresSpecialDigestion: true - type: SolutionContainerManager @@ -136,6 +144,8 @@ state: cloth - type: Stack count: 10 + - type: Item + size: 10 - type: entity parent: MaterialCloth @@ -146,6 +156,8 @@ state: cloth - type: Stack count: 1 + - type: Item + size: 1 - type: entity parent: MaterialBase @@ -197,6 +209,8 @@ state: durathread - type: Stack count: 1 + - type: Item + size: 1 - type: entity parent: MaterialBase @@ -231,6 +245,8 @@ components: - type: Stack count: 10 + - type: Item + size: 10 - type: entity parent: MaterialWoodPlank @@ -239,6 +255,8 @@ components: - type: Stack count: 1 + - type: Item + size: 1 - type: entity parent: MaterialBase @@ -260,6 +278,8 @@ - type: GuideHelp guides: - Cloning + - type: Item + size: 100 - type: entity parent: MaterialBiomass @@ -268,6 +288,8 @@ components: - type: Stack count: 1 + - type: Item + size: 1 # Following not used currently - type: entity @@ -330,6 +352,7 @@ state: diamond - type: Item heldPrefix: diamond + size: 60 - type: entity parent: MaterialDiamond @@ -338,6 +361,8 @@ components: - type: Stack count: 1 + - type: Item + size: 2 - type: entity parent: MaterialBase @@ -358,6 +383,8 @@ - state: cotton_3 map: ["base"] - type: Appearance + - type: Item + size: 30 - type: Food requiresSpecialDigestion: true - type: SolutionContainerManager @@ -383,6 +410,8 @@ state: cotton - type: Stack count: 1 + - type: Item + size: 1 - type: entity parent: MaterialBase @@ -433,6 +462,8 @@ - ReagentId: Honk Quantity: 5 - type: Appearance + - type: Item + size: 20 - type: entity parent: MaterialBananium @@ -443,6 +474,8 @@ state: bananium - type: Stack count: 1 + - type: Item + size: 2 - type: entity parent: MaterialBase @@ -460,6 +493,8 @@ - type: Stack count: 50 stackType: WebSilk + - type: Item + size: 50 - type: Food requiresSpecialDigestion: true - type: FlavorProfile @@ -487,6 +522,8 @@ components: - type: Stack count: 25 + - type: Item + size: 25 - type: entity parent: MaterialWebSilk @@ -495,6 +532,8 @@ components: - type: Stack count: 1 + - type: Item + size: 1 - type: entity parent: MaterialBase @@ -515,6 +554,8 @@ - state: cotton_3 map: ["base"] - type: Appearance + - type: Item + size: 30 - type: Food - type: BadFood - type: SolutionContainerManager @@ -532,3 +573,5 @@ components: - type: Stack count: 1 + - type: Item + size: 1 diff --git a/Resources/Prototypes/Entities/Objects/Materials/ore.yml b/Resources/Prototypes/Entities/Objects/Materials/ore.yml index 2b6fec873b..f27d1b770e 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/ore.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/ore.yml @@ -8,7 +8,7 @@ sprite: Objects/Materials/ore.rsi - type: Item sprite: Objects/Materials/ore.rsi - size: Normal + size: 60 - type: Tag tags: - Ore @@ -57,6 +57,8 @@ components: - type: Stack count: 1 + - type: Item + size: 2 - type: entity parent: OreBase @@ -80,6 +82,8 @@ components: - type: Stack count: 1 + - type: Item + size: 2 - type: entity parent: OreBase @@ -103,6 +107,8 @@ components: - type: Stack count: 1 + - type: Item + size: 2 - type: entity parent: OreBase @@ -126,6 +132,8 @@ components: - type: Stack count: 1 + - type: Item + size: 2 - type: entity parent: OreBase @@ -149,6 +157,8 @@ components: - type: Stack count: 1 + - type: Item + size: 2 - type: entity parent: OreBase @@ -172,6 +182,9 @@ components: - type: Stack count: 1 + - type: Item + size: 2 + - type: entity parent: OreBase @@ -195,3 +208,5 @@ components: - type: Stack count: 1 + - type: Item + size: 2 diff --git a/Resources/Prototypes/Entities/Objects/Materials/parts.yml b/Resources/Prototypes/Entities/Objects/Materials/parts.yml index 7529bdee04..e75704c2a4 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/parts.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/parts.yml @@ -44,7 +44,7 @@ - state: rods_5 map: ["base"] - type: Item - size: Normal + size: 30 # heldPrefix: rods - type: Construction graph: MetalRod @@ -73,6 +73,8 @@ state: rods - type: Stack count: 10 + - type: Item + size: 10 - type: entity parent: PartRodMetal @@ -88,12 +90,16 @@ state: rods - type: Stack count: 1 + - type: Item + size: 1 - type: entity parent: PartRodMetal id: PartRodMetalLingering0 suffix: Lingering, 0 components: + - type: Item + size: 0 - type: Stack lingering: true count: 0 diff --git a/Resources/Prototypes/Entities/Objects/Materials/shards.yml b/Resources/Prototypes/Entities/Objects/Materials/shards.yml index 8129ab2116..affd08edb1 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/shards.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/shards.yml @@ -26,7 +26,7 @@ Slash: 3.5 - type: Item sprite: Objects/Materials/Shards/shard.rsi - size: Tiny + size: 4 - type: CollisionWake enabled: false - type: Fixtures diff --git a/Resources/Prototypes/Entities/Objects/Misc/bedsheets.yml b/Resources/Prototypes/Entities/Objects/Misc/bedsheets.yml index 2945c4f68e..6c6f2d484e 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/bedsheets.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/bedsheets.yml @@ -13,7 +13,7 @@ sprite: Objects/Misc/bedsheets.rsi noRot: true - type: Item - size: Small + size: 10 - type: Clothing quickEquip: true slots: diff --git a/Resources/Prototypes/Entities/Objects/Misc/box.yml b/Resources/Prototypes/Entities/Objects/Misc/box.yml index fa54570d27..59a2abd566 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/box.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/box.yml @@ -7,9 +7,9 @@ sprite: Objects/Storage/boxes.rsi - type: Item sprite: Objects/Storage/boxes.rsi - size: Normal + size: 30 - type: Storage - maxSlots: 7 + capacity: 30 - type: ContainerContainer containers: storagebase: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Misc/briefcases.yml b/Resources/Prototypes/Entities/Objects/Misc/briefcases.yml index ebf776a7b1..1866d3513e 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/briefcases.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/briefcases.yml @@ -5,10 +5,9 @@ description: Useful for carrying items in your hands. components: - type: Item - size: Large + size: 60 - type: Storage - maxSlots: 4 - maxTotalWeight: 16 + capacity: 60 - type: Tag tags: - Briefcase @@ -26,17 +25,16 @@ sprite: Objects/Storage/Briefcases/briefcase_brown.rsi - type: entity - parent: BriefcaseBase + parent: BaseStorageItem abstract: true id: BriefcaseSyndieBase suffix: Syndicate, Empty description: Useful for carrying items in your hands. components: - type: Item - size: Large + size: 80 - type: Storage - maxSlots: 6 - maxTotalWeight: 24 + capacity: 80 - type: Tag tags: - Briefcase diff --git a/Resources/Prototypes/Entities/Objects/Misc/eggspider.yml b/Resources/Prototypes/Entities/Objects/Misc/eggspider.yml index c2357ed3c8..f53e39e364 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/eggspider.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/eggspider.yml @@ -14,7 +14,7 @@ Structural: 2 animation: WeaponArcPunch - type: Item - size: Small + size: 5 - type: PointLight radius: 1.5 energy: 3 diff --git a/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml b/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml index 0697281a0f..a90f598a5d 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml @@ -11,7 +11,7 @@ map: [ "enabled" ] - type: Item sprite: Objects/Misc/fire_extinguisher.rsi - size: Small + size: 10 - type: SolutionContainerManager solutions: spray: diff --git a/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml b/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml index 1b925b5cb0..77b321f951 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml @@ -38,7 +38,7 @@ sprite: Objects/Misc/Lights/lights.rsi - type: Item sprite: Objects/Misc/Lights/lights.rsi - size: Normal + size: 20 heldPrefix: off - type: PointLight enabled: false @@ -158,7 +158,7 @@ description: A pole with powerful mounted lights on it. components: - type: Item - size: Normal + size: 50 - type: Sprite layers: - state: floodlight diff --git a/Resources/Prototypes/Entities/Objects/Misc/handcuffs.yml b/Resources/Prototypes/Entities/Objects/Misc/handcuffs.yml index 4f2199bfa8..befd24f36e 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/handcuffs.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/handcuffs.yml @@ -5,7 +5,7 @@ parent: BaseItem components: - type: Item - size: Small + size: 3 - type: Handcuff cuffedRSI: Objects/Misc/handcuffs.rsi bodyIconState: body-overlay @@ -31,6 +31,8 @@ id: Cablecuffs parent: Handcuffs components: + - type: Item + size: 5 - type: Handcuff breakoutTime: 15 cuffedRSI: Objects/Misc/cablecuffs.rsi @@ -63,7 +65,7 @@ parent: Handcuffs components: - type: Item - size: Tiny + size: 2 - type: Handcuff breakoutTime: 20 # halfway between improvised cablecuffs and metal ones cuffedRSI: Objects/Misc/cablecuffs.rsi # cablecuffs will look fine @@ -90,7 +92,7 @@ abstract: true components: - type: Item - size: Tiny + size: 2 - type: Tag tags: - Trash @@ -126,7 +128,7 @@ description: Used to restrain those who may cause harm to themselves or others. components: - type: Item - size: Normal + size: 20 - type: Handcuff cuffedRSI: Clothing/OuterClothing/Misc/straight_jacket.rsi breakoutTime: 100 diff --git a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml index df8a007576..24462d5113 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml @@ -12,7 +12,6 @@ - idcard sprite: Objects/Misc/id_cards.rsi - type: Item - size: Small heldPrefix: default - type: Access - type: IdCard diff --git a/Resources/Prototypes/Entities/Objects/Misc/implanters.yml b/Resources/Prototypes/Entities/Objects/Misc/implanters.yml index dd609dee6c..41966ab93f 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/implanters.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/implanters.yml @@ -81,7 +81,7 @@ components: - type: Item sprite: Objects/Specific/Medical/syndi_implanter.rsi - size: Tiny + size: 3 - type: Sprite sprite: Objects/Specific/Medical/syndi_implanter.rsi state: implanter1 diff --git a/Resources/Prototypes/Entities/Objects/Misc/improvised_gun_parts.yml b/Resources/Prototypes/Entities/Objects/Misc/improvised_gun_parts.yml index abf4e0974a..d94193e49a 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/improvised_gun_parts.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/improvised_gun_parts.yml @@ -2,12 +2,12 @@ #TODO: Assimilate these into the same RSI. - type: entity parent: BaseItem - id: ModularReceiver - name: modular receiver + id: ModularReceiver + name: modular receiver description: A vital part used in the creation of firearms. #Could use a better description, but I'm not a gun nut so I can't really do that. components: # - type: Item -# size: Normal +# size: 15 - type: Sprite sprite: Objects/Misc/modular_receiver.rsi state: icon @@ -23,7 +23,7 @@ description: A robust wooden stock, used in the creation of firearms. #Same as above components: # - type: Item -# size: Normal +# size: 25 - type: Sprite sprite: Objects/Misc/rifle_stock.rsi state: icon diff --git a/Resources/Prototypes/Entities/Objects/Misc/machine_parts.yml b/Resources/Prototypes/Entities/Objects/Misc/machine_parts.yml index c38239a08d..be1f4f65ee 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/machine_parts.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/machine_parts.yml @@ -8,7 +8,7 @@ - type: Sprite sprite: Objects/Misc/stock_parts.rsi - type: Item - size: Tiny + size: 1 - type: GuideHelp guides: - MachineUpgrading diff --git a/Resources/Prototypes/Entities/Objects/Misc/medalcase.yml b/Resources/Prototypes/Entities/Objects/Misc/medalcase.yml index d1ceae2c60..64c11d5a2f 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/medalcase.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/medalcase.yml @@ -9,10 +9,9 @@ state: icon - type: Item sprite: Objects/Storage/medalcase.rsi - size: Normal + size: 80 - type: Storage - maxSlots: 8 - maxTotalWeight: 16 + capacity: 80 - type: StorageFill contents: - id: ClothingNeckGoldmedal diff --git a/Resources/Prototypes/Entities/Objects/Misc/monkeycube.yml b/Resources/Prototypes/Entities/Objects/Misc/monkeycube.yml index fcf47d713d..32ad0552c0 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/monkeycube.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/monkeycube.yml @@ -8,6 +8,7 @@ whitelist: tags: - MonkeyCube + capacity: 30 - type: StorageFill contents: - id: MonkeyCubeWrapped @@ -46,6 +47,7 @@ whitelist: tags: - MonkeyCube + capacity: 30 - type: StorageFill contents: - id: SyndicateSpongeWrapped diff --git a/Resources/Prototypes/Entities/Objects/Misc/paper.yml b/Resources/Prototypes/Entities/Objects/Misc/paper.yml index 99dc9c07c6..132d6b7aff 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/paper.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/paper.yml @@ -23,7 +23,7 @@ - key: enum.PaperUiKey.Key type: PaperBoundUserInterface - type: Item - size: Tiny + size: 1 - type: Tag tags: - Document @@ -245,7 +245,7 @@ - type: Item sprite: Objects/Misc/bureaucracy.rsi heldPrefix: pen - size: Tiny + size: 2 - type: PhysicalComposition materialComposition: Steel: 25 @@ -277,7 +277,7 @@ - type: Item sprite: Objects/Misc/bureaucracy.rsi heldPrefix: overpriced_pen - size: Tiny + size: 2 - type: entity name: captain's fountain pen @@ -336,11 +336,9 @@ # black: "#3f3f3f" - type: Item sprite: Objects/Misc/bureaucracy.rsi - size: Small + size: 5 - type: Storage - maxSlots: 10 - maxItemSize: Small - maxTotalWeight: 20 + capacity: 10 whitelist: tags: - Document @@ -470,14 +468,13 @@ insertOnInteract: false - type: Item sprite: Objects/Misc/clipboard.rsi - size: Small + size: 10 - type: Clothing slots: [belt] quickEquip: false sprite: Objects/Misc/clipboard.rsi - type: Storage - maxSlots: 15 - maxTotalWeight: 30 + capacity: 20 whitelist: tags: - Document @@ -529,13 +526,13 @@ insertOnInteract: true - type: Item sprite: Objects/Misc/qm_clipboard.rsi - size: Normal + size: 30 - type: Clothing slots: [belt] quickEquip: false sprite: Objects/Misc/qm_clipboard.rsi - type: Storage - maxSlots: 20 + capacity: 90 quickInsert: true whitelist: tags: @@ -588,7 +585,7 @@ sprite: Objects/Misc/bureaucracy.rsi state: stamp-mime - type: Item - size: Tiny + size: 3 - type: entity name: alternate rubber stamp diff --git a/Resources/Prototypes/Entities/Objects/Misc/potatoai_chip.yml b/Resources/Prototypes/Entities/Objects/Misc/potatoai_chip.yml index 0f871831e2..528aa30a14 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/potatoai_chip.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/potatoai_chip.yml @@ -8,10 +8,10 @@ sprite: Objects/Misc/potatoai_chip.rsi state: icon - type: Item - size: Tiny + size: 3 - type: Tag tags: - SmallAIChip - type: Construction graph: PotatoAIChip - node: potatoaichip + node: potatoaichip \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Objects/Misc/subdermal_implants.yml b/Resources/Prototypes/Entities/Objects/Misc/subdermal_implants.yml index 4335461660..6632010a79 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/subdermal_implants.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/subdermal_implants.yml @@ -110,10 +110,9 @@ - type: SubdermalImplant implantAction: ActionOpenStorageImplant - type: Item - size: Huge + size: 9999 - type: Storage - maxSlots: 4 - maxItemSize: Small + capacity: 20 #10-20 should be more than enough for this - type: ContainerContainer containers: storagebase: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Power/antimatter_jar.yml b/Resources/Prototypes/Entities/Objects/Power/antimatter_jar.yml index 22e5b9bb3c..8267903dbb 100644 --- a/Resources/Prototypes/Entities/Objects/Power/antimatter_jar.yml +++ b/Resources/Prototypes/Entities/Objects/Power/antimatter_jar.yml @@ -5,7 +5,7 @@ description: A hermetically sealed jar containing antimatter for use in an antimatter reactor. components: - type: Item - size: Normal + size: 5 sprite: Objects/Power/AME/ame_jar.rsi - type: Sprite sprite: Objects/Power/AME/ame_jar.rsi diff --git a/Resources/Prototypes/Entities/Objects/Power/antimatter_part.yml b/Resources/Prototypes/Entities/Objects/Power/antimatter_part.yml index 7d428bcc5a..a393cad617 100644 --- a/Resources/Prototypes/Entities/Objects/Power/antimatter_part.yml +++ b/Resources/Prototypes/Entities/Objects/Power/antimatter_part.yml @@ -5,7 +5,7 @@ description: A flatpack used for constructing an antimatter engine reactor. Use a multitool to unpack it. components: - type: Item - size: Small + size: 5 sprite: Objects/Power/AME/ame_part.rsi - type: Sprite sprite: Objects/Power/AME/ame_part.rsi diff --git a/Resources/Prototypes/Entities/Objects/Power/powersink.yml b/Resources/Prototypes/Entities/Objects/Power/powersink.yml index c8684323a9..9317dd741f 100644 --- a/Resources/Prototypes/Entities/Objects/Power/powersink.yml +++ b/Resources/Prototypes/Entities/Objects/Power/powersink.yml @@ -5,7 +5,7 @@ description: Drains immense amounts of electricity from the grid. components: - type: Item - size: Large + size: 150 - type: NodeContainer examinable: true nodes: diff --git a/Resources/Prototypes/Entities/Objects/Power/solar_parts.yml b/Resources/Prototypes/Entities/Objects/Power/solar_parts.yml index 5b3f5e90ce..ff333b93c2 100644 --- a/Resources/Prototypes/Entities/Objects/Power/solar_parts.yml +++ b/Resources/Prototypes/Entities/Objects/Power/solar_parts.yml @@ -4,7 +4,7 @@ name: solar assembly part components: - type: Item - size: Small + size: 10 - type: Sprite sprite: Objects/Power/solar_parts.rsi state: solar_assembly_parts diff --git a/Resources/Prototypes/Entities/Objects/Shields/shields.yml b/Resources/Prototypes/Entities/Objects/Shields/shields.yml index 76a8e576a5..8afe40bfe7 100644 --- a/Resources/Prototypes/Entities/Objects/Shields/shields.yml +++ b/Resources/Prototypes/Entities/Objects/Shields/shields.yml @@ -10,7 +10,7 @@ state: riot-icon - type: Item sprite: Objects/Weapons/Melee/shields.rsi - size: Huge + size: 100 heldPrefix: riot - type: Blocking passiveBlockModifier: @@ -308,7 +308,7 @@ path: /Audio/Weapons/ebladeon.ogg deActivateSound: path: /Audio/Weapons/ebladeoff.ogg - offSize: Small + offSize: 5 - type: Sprite sprite: Objects/Weapons/Melee/e_shield.rsi layers: @@ -319,7 +319,7 @@ shader: unshaded map: [ "shield" ] - type: Item - size: Small + size: 5 sprite: Objects/Weapons/Melee/e_shield.rsi heldPrefix: eshield - type: UseDelay @@ -398,7 +398,7 @@ state: eshield-icon - type: Item sprite: Objects/Weapons/Melee/e_shield.rsi - size: Small + size: 5 heldPrefix: eshield - type: entity @@ -417,7 +417,7 @@ path: /Audio/Weapons/telescopicoff.ogg params: volume: -5 - offSize: Small + offSize: 10 - type: Sprite sprite: Objects/Weapons/Melee/teleriot_shield.rsi layers: @@ -426,7 +426,7 @@ visible: false map: [ "shield" ] - type: Item - size: Small + size: 10 sprite: Objects/Weapons/Melee/teleriot_shield.rsi heldPrefix: teleriot - type: UseDelay diff --git a/Resources/Prototypes/Entities/Objects/Specific/Chapel/bibles.yml b/Resources/Prototypes/Entities/Objects/Specific/Chapel/bibles.yml index 3e72257d5c..19414d0997 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Chapel/bibles.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Chapel/bibles.yml @@ -31,13 +31,13 @@ sprite: Objects/Specific/Chapel/bible.rsi state: icon - type: Item - size: Normal + size: 15 sprite: Objects/Specific/Chapel/bible.rsi - type: Clothing slots: - Belt - type: Storage - maxSlots: 1 + capacity: 10 - type: UserInterface interfaces: - key: enum.StorageUiKey.Key @@ -74,7 +74,7 @@ sprite: Objects/Specific/Chapel/necronomicon.rsi state: icon - type: Item - size: Normal + size: 15 sprite: Objects/Specific/Chapel/necronomicon.rsi - type: Clothing slots: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chem_bag.yml b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chem_bag.yml index 597f48744c..8be5fecb4f 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chem_bag.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chem_bag.yml @@ -13,9 +13,9 @@ slots: - belt - type: Item - size: Normal + size: 46 - type: Storage - maxSlots: 40 + capacity: 45 quickInsert: true areaInsert: true whitelist: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Forensics/forensics.yml b/Resources/Prototypes/Entities/Objects/Specific/Forensics/forensics.yml index b7627e1016..a3abd4f1e3 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Forensics/forensics.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Forensics/forensics.yml @@ -5,7 +5,7 @@ description: A forensic pad for collecting fingerprints or fibers. components: - type: Item - size: Tiny + size: 3 - type: ForensicPad - type: Sprite sprite: Objects/Misc/bureaucracy.rsi diff --git a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/leaves.yml b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/leaves.yml index 8e26898daa..6da11b53fb 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/leaves.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/leaves.yml @@ -63,7 +63,7 @@ tags: - Smokable - type: Item - size: Tiny + size: 1 - type: entity name: tobacco leaves @@ -121,4 +121,4 @@ tags: - Smokable - type: Item - size: Tiny + size: 1 diff --git a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml index af66e528c9..16d9fd1a64 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml @@ -8,7 +8,7 @@ sprite: Objects/Specific/Hydroponics/seeds.rsi state: seed - type: Item - size: Tiny + size: 2 - type: StaticPrice price: 20 @@ -457,7 +457,7 @@ seedId: watermelon - type: Sprite sprite: Objects/Specific/Hydroponics/watermelon.rsi - + - type: entity parent: SeedBase name: packet of grape seeds @@ -497,4 +497,4 @@ - type: Seed seedId: bungo - type: Sprite - sprite: Objects/Specific/Hydroponics/bungo.rsi + sprite: Objects/Specific/Hydroponics/bungo.rsi \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/tools.yml b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/tools.yml index 026c47f176..c939cc9ca1 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/tools.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/tools.yml @@ -59,7 +59,7 @@ types: Slash: 10 - type: Item - size: Normal + size: 20 - type: Clothing sprite: Objects/Tools/Hydroponics/scythe.rsi slots: @@ -123,13 +123,13 @@ - type: Sprite sprite: Objects/Specific/Hydroponics/Equipment/plant_bag.rsi state: icon + - type: Item - type: Clothing quickEquip: false slots: - belt - type: Storage - maxSlots: 40 - maxItemSize: Small + capacity: 200 quickInsert: true areaInsert: true whitelist: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml index d865dd172f..333c17b217 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml @@ -20,7 +20,7 @@ types: Blunt: 5 - type: Item - size: Normal + size: 15 sprite: Objects/Specific/Janitorial/mop.rsi - type: Absorbent - type: SolutionContainerManager @@ -59,7 +59,7 @@ types: Blunt: 5 - type: Item - size: Normal + size: 15 sprite: Objects/Specific/Janitorial/advmop.rsi - type: Absorbent pickupAmount: 100 @@ -203,7 +203,7 @@ sprite: Objects/Specific/Janitorial/wet_floor_sign.rsi - type: Item sprite: Objects/Specific/Janitorial/wet_floor_sign.rsi - size: Normal + size: 15 - type: Armor modifiers: coefficients: @@ -544,7 +544,7 @@ types: Blunt: 0 - type: Item - size: Small + size: 10 sprite: Objects/Specific/Janitorial/rag.rsi - type: Absorbent pickupAmount: 15 diff --git a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/trashbag.yml b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/trashbag.yml index da12222595..80aace05e7 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/trashbag.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/trashbag.yml @@ -9,8 +9,7 @@ - state: icon-0 map: ["enum.StorageFillLayers.Fill"] - type: Storage - maxSlots: 20 - maxItemSize: Small + capacity: 125 quickInsert: true areaInsert: true storageOpenSound: @@ -34,7 +33,7 @@ slots: [belt] sprite: Objects/Specific/Janitorial/trashbag.rsi - type: Item - size: Normal + size: 125 - type: entity name: trash bag @@ -56,9 +55,7 @@ parent: TrashBagBlue components: - type: Storage - maxSlots: 100 - maxItemSize: Huge - maxTotalWeight: 200 + capacity: 125000 quickInsert: true areaInsert: true areaInsertRadius: 1000 diff --git a/Resources/Prototypes/Entities/Objects/Specific/Kitchen/foodcarts.yml b/Resources/Prototypes/Entities/Objects/Specific/Kitchen/foodcarts.yml index 20ec7354fb..22faf499f1 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Kitchen/foodcarts.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Kitchen/foodcarts.yml @@ -47,9 +47,10 @@ - key: enum.StorageUiKey.Key type: StorageBoundUserInterface - type: Storage + capacity: 30 - type: TileFrictionModifier - modifier: 0.4 # makes it slide - + modifier: 0.4 # makes it slide + # Add this if freezing/heating container/objects thermodynamics becomes a thing #- type: PowerCellSlot @@ -62,7 +63,7 @@ # cell_slot: # name: power-cell-slot-component-slot-name-default # startingItem: PowerCellMedium - + - type: entity name: Hot Food Cart id: FoodCartHot @@ -72,11 +73,11 @@ - type: Sprite netSync: false noRot: true - sprite: Objects/Specific/Kitchen/food_carts.rsi + sprite: Objects/Specific/Kitchen/food_carts.rsi layers: - state: stand-food - type: Storage - blacklist: + blacklist: tags: - Coldsauce - Hotsauce @@ -99,7 +100,7 @@ whitelist: tags: - Hotsauce - priority: 5 + priority: 5 bbqsauce_slot: name: BBQ Sauce insertSound: /Audio/Items/bottle_clunk.ogg @@ -107,7 +108,7 @@ whitelist: tags: - BBQsauce - priority: 4 + priority: 4 ketchup_slot: name: Ketchup insertSound: /Audio/Items/bottle_clunk.ogg @@ -115,7 +116,7 @@ whitelist: tags: - Ketchup - priority: 3 + priority: 3 - type: ItemMapper mapLayers: cart_hotsauce: @@ -153,7 +154,7 @@ - type: Sprite netSync: false noRot: true - sprite: Objects/Specific/Kitchen/food_carts.rsi + sprite: Objects/Specific/Kitchen/food_carts.rsi layers: - state: stand-ice - type: ContainerContainer diff --git a/Resources/Prototypes/Entities/Objects/Specific/Librarian/books_bag.yml b/Resources/Prototypes/Entities/Objects/Specific/Librarian/books_bag.yml index a2675ffaaf..2ad28399a6 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Librarian/books_bag.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Librarian/books_bag.yml @@ -13,9 +13,9 @@ slots: - belt - type: Item - size: Huge + size: 151 - type: Storage - maxSlots: 15 + capacity: 150 quickInsert: true areaInsert: true whitelist: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Mech/mech_construction.yml b/Resources/Prototypes/Entities/Objects/Specific/Mech/mech_construction.yml index a79e6e9037..678cd5ea12 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Mech/mech_construction.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Mech/mech_construction.yml @@ -44,7 +44,7 @@ abstract: true components: - type: Item - size: Huge + size: 50 - type: entity parent: BaseRipleyPart @@ -172,7 +172,7 @@ abstract: true components: - type: Item - size: Huge + size: 50 - type: entity parent: BaseHonkerPart @@ -300,7 +300,7 @@ abstract: true components: - type: Item - size: Large + size: 50 - type: entity parent: BaseHamtrPart @@ -428,7 +428,7 @@ abstract: true components: - type: Item - size: Small + size: 10 - type: entity parent: BaseVimPartItem diff --git a/Resources/Prototypes/Entities/Objects/Specific/Mech/mecha_equipment.yml b/Resources/Prototypes/Entities/Objects/Specific/Mech/mecha_equipment.yml index ac550b8e61..8539c473b9 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Mech/mecha_equipment.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Mech/mecha_equipment.yml @@ -7,7 +7,7 @@ sprite: Objects/Specific/Mech/mecha_equipment.rsi - type: Item sprite: Objects/Specific/Mech/mecha_equipment.rsi - size: Huge + size: 50 - type: MechEquipment - type: GuideHelp guides: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/defib.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/defib.yml index 74b0cbb0d9..a69147b610 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/defib.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/defib.yml @@ -28,7 +28,7 @@ True: { visible: true } False: { visible: false } - type: Item - size: Normal + size: 50 - type: ItemCooldown - type: Speech speechVerb: Robotic diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/disease.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/disease.yml index b85f708777..9c67cbb28c 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/disease.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/disease.yml @@ -5,7 +5,7 @@ description: Used for taking and transfering samples. Sterile until open. Single use only. components: - type: Item - size: Tiny + size: 1 - type: Sprite sprite: Objects/Specific/Medical/mouth_swab.rsi state: icon @@ -26,7 +26,7 @@ description: Prevents people who DON'T already have a disease from catching it. components: - type: Item - size: Tiny + size: 3 - type: Sprite sprite: Objects/Specific/Medical/medipen.rsi state: salpen diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml index 88b7401f74..5083ae4a44 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml @@ -6,7 +6,7 @@ - type: Sprite sprite: Objects/Specific/Medical/medical.rsi - type: Item - size: Small + size: 10 sprite: Objects/Specific/Medical/medical.rsi heldPrefix: ointment # Inherited @@ -54,6 +54,8 @@ - type: Stack stackType: Ointment count: 1 + - type: Item + size: 1 - type: entity id: Ointment10Lingering @@ -103,6 +105,8 @@ - type: Stack stackType: RegenerativeMesh count: 1 + - type: Item + size: 1 - type: entity name: bruise pack @@ -140,6 +144,8 @@ - type: Stack stackType: Brutepack count: 1 + - type: Item + size: 1 - type: entity id: Brutepack10Lingering @@ -187,6 +193,8 @@ - type: Stack stackType: MedicatedSuture count: 1 + - type: Item + size: 1 - type: entity name: blood pack @@ -265,6 +273,8 @@ components: - type: Stack count: 1 + - type: Item + size: 1 - type: entity id: Gauze10Lingering @@ -328,16 +338,6 @@ - ReagentId: Dexalin Quantity: 10 -- type: entity - parent: PillCanister - id: PillCanisterDexalin - suffix: Dexalin, 7 - components: - - type: StorageFill - contents: - - id: PillDexalin - amount: 7 - - type: entity name: dylovene pill (10u) parent: Pill @@ -351,16 +351,6 @@ - ReagentId: Dylovene Quantity: 10 -- type: entity - parent: PillCanister - id: PillCanisterDylovene - suffix: Dylovene, 5 - components: - - type: StorageFill - contents: - - id: PillDylovene - amount: 5 - - type: entity name: hyronalin pill (10u) parent: Pill @@ -374,16 +364,6 @@ - ReagentId: Hyronalin Quantity: 10 -- type: entity - parent: PillCanister - id: PillCanisterHyronalin - suffix: Hyronalin, 5 - components: - - type: StorageFill - contents: - - id: PillHyronalin - amount: 5 - - type: entity name: iron pill (10u) parent: Pill @@ -397,16 +377,6 @@ - ReagentId: Iron Quantity: 10 -- type: entity - parent: PillCanister - id: PillCanisterIron - suffix: Iron, 5 - components: - - type: StorageFill - contents: - - id: PillIron - amount: 5 - - type: entity name: kelotane pill (10u) parent: Pill @@ -420,16 +390,6 @@ - ReagentId: Kelotane Quantity: 10 -- type: entity - parent: PillCanister - id: PillCanisterKelotane - suffix: Kelotane, 5 - components: - - type: StorageFill - contents: - - id: PillKelotane - amount: 5 - - type: entity name: dermaline pill (10u) parent: Pill @@ -443,16 +403,6 @@ - ReagentId: Dermaline Quantity: 10 -- type: entity - parent: PillCanister - id: PillCanisterDermaline - suffix: Dermaline, 5 - components: - - type: StorageFill - contents: - - id: PillDermaline - amount: 5 - - type: entity name: space drugs parent: Pill @@ -479,16 +429,6 @@ - ReagentId: Tricordrazine Quantity: 10 -- type: entity - parent: PillCanister - id: PillCanisterTricordrazine - suffix: Tricordrazine, 5 - components: - - type: StorageFill - contents: - - id: PillTricordrazine - amount: 5 - - type: entity name: bicaridine pill (10u) parent: Pill @@ -502,16 +442,6 @@ - ReagentId: Bicaridine Quantity: 10 -- type: entity - parent: PillCanister - id: PillCanisterBicaridine - suffix: Bicaridine, 5 - components: - - type: StorageFill - contents: - - id: PillBicaridine - amount: 5 - - type: entity name: charcoal pill (10u) parent: Pill @@ -528,16 +458,6 @@ - ReagentId: Charcoal Quantity: 10 -- type: entity - parent: PillCanister - id: PillCanisterCharcoal - suffix: Charcoal, 3 - components: - - type: StorageFill - contents: - - id: PillCharcoal - amount: 3 - - type: entity name: romerol pill parent: Pill diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml index 709bc751a4..dccbbc7328 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml @@ -101,7 +101,7 @@ map: ["enum.SolutionContainerLayers.Fill"] - type: Item sprite: Objects/Specific/Medical/medipen.rsi - size: Tiny + size: 3 - type: SolutionContainerManager solutions: pen: @@ -291,7 +291,7 @@ map: ["enum.SolutionContainerLayers.Fill"] - type: Item sprite: Objects/Specific/Medical/medipen.rsi - size: Small + size: 10 - type: SolutionContainerManager solutions: pen: @@ -320,7 +320,7 @@ map: ["enum.SolutionContainerLayers.Fill"] - type: Item sprite: Objects/Specific/Medical/medipen.rsi - size: Tiny + size: 5 - type: SolutionContainerManager solutions: pen: @@ -346,7 +346,7 @@ map: ["enum.SolutionContainerLayers.Fill"] - type: Item sprite: Objects/Specific/Medical/medipen.rsi - size: Tiny + size: 5 - type: SolutionContainerManager solutions: pen: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/medkits.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/medkits.yml index 3328316112..400f6670ab 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/medkits.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/medkits.yml @@ -8,8 +8,9 @@ sprite: Objects/Specific/Medical/firstaidkits.rsi state: firstaid - type: Storage + capacity: 60 - type: Item - size: Normal + size: 60 sprite: Objects/Specific/Medical/firstaidkits.rsi heldPrefix: firstaid - type: Tag @@ -92,5 +93,7 @@ state: blackkit - type: Item heldPrefix: blackkit - size: Normal + size: 50 + - type: Storage + capacity: 50 diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml index 1ef73f2396..18e502ccdf 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml @@ -5,7 +5,7 @@ description: A plastic bag designed for the storage and transportation of cadavers. components: - type: Item - size: Small + size: 6 - type: Sprite drawdepth: SmallObjects # I guess body bags need appear above a coroner's table? sprite: Objects/Specific/Medical/Morgue/bodybags.rsi diff --git a/Resources/Prototypes/Entities/Objects/Specific/Research/rped.yml b/Resources/Prototypes/Entities/Objects/Specific/Research/rped.yml index dd9d771ebe..268a91c8de 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Research/rped.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Research/rped.yml @@ -9,13 +9,13 @@ state: icon - type: Item sprite: Objects/Specific/Research/rped.rsi - size: Normal + size: 50 - type: GuideHelp guides: - MachineUpgrading - type: PartExchanger - type: Storage - maxSlots: 30 + capacity: 150 quickInsert: true areaInsert: true whitelist: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Salvage/ore_bag.yml b/Resources/Prototypes/Entities/Objects/Specific/Salvage/ore_bag.yml index 814ddb30da..583aef374a 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Salvage/ore_bag.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Salvage/ore_bag.yml @@ -14,10 +14,9 @@ slots: - belt - type: Item - size: Huge + size: 176 - type: Storage - maxSlots: 5 - maxItemSize: Normal + capacity: 175 quickInsert: true areaInsert: true whitelist: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml b/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml index 6abdd790c9..6ada51176c 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml @@ -22,7 +22,7 @@ soundSwing: path: /Audio/Weapons/punchmiss.ogg - type: Item - size: Normal + size: 50 - type: Damageable damageContainer: Inorganic damageModifierSet: Metallic diff --git a/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/item_artifacts.yml b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/item_artifacts.yml index 6c49fd7a5e..465e1a458c 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/item_artifacts.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/item_artifacts.yml @@ -55,7 +55,7 @@ type: IntercomBoundUserInterface - type: Appearance - type: Item - size: Normal + size: 40 sprite: Objects/Specific/Xenoarchaeology/item_artifacts.rsi heldPrefix: ano01 - type: Actions diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml b/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml index 51d705f617..0e679c7096 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml @@ -17,7 +17,7 @@ map: [ "enum.SolutionContainerLayers.Fill" ] visible: false - type: Item - size: Normal + size: 20 sprite: Objects/Specific/Chemistry/jug.rsi - type: RefillableSolution solution: beaker diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemistry-bottles.yml b/Resources/Prototypes/Entities/Objects/Specific/chemistry-bottles.yml index b869a2008f..da1a15e238 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/chemistry-bottles.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/chemistry-bottles.yml @@ -46,7 +46,7 @@ - key: enum.TransferAmountUiKey.Key type: TransferAmountBoundUserInterface - type: Item - size: Tiny + size: 3 sprite: Objects/Specific/Chemistry/beaker.rsi - type: Spillable solution: drink diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml b/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml index 6ccb29f1cc..bf323067ac 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml @@ -187,7 +187,7 @@ map: ["enum.SolutionContainerLayers.Fill"] visible: false - type: Item - size: Small + size: 10 sprite: Objects/Specific/Chemistry/beaker_large.rsi - type: SolutionContainerManager solutions: @@ -317,7 +317,7 @@ sprite: Objects/Specific/Chemistry/syringe.rsi state: "syringe_base0" - type: Item - size: Tiny + size: 3 sprite: Objects/Specific/Chemistry/syringe.rsi heldPrefix: 0 - type: SolutionContainerManager @@ -393,7 +393,7 @@ sprite: Objects/Specific/Chemistry/pills.rsi state: pill - type: Item - size: Tiny + size: 1 sprite: Objects/Specific/Chemistry/pills.rsi - type: Pill - type: Food @@ -436,20 +436,18 @@ name: pill canister id: PillCanister parent: BaseStorageItem - description: Holds up to 10 pills. + description: Holds up to 9 pills. components: - type: Sprite sprite: Objects/Specific/Chemistry/pills_canister.rsi state: pill_canister - type: Item sprite: Objects/Specific/Chemistry/pills_canister.rsi - size: Small - type: Tag tags: - PillCanister - type: Storage - maxSlots: 10 - maxTotalWeight: 10 + capacity: 9 quickInsert: true areaInsert: true areaInsertRadius: 1 diff --git a/Resources/Prototypes/Entities/Objects/Specific/syndicate.yml b/Resources/Prototypes/Entities/Objects/Specific/syndicate.yml index aa6a64789e..81836f9c6c 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/syndicate.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/syndicate.yml @@ -10,7 +10,7 @@ state: telecrystal - type: Item sprite: Objects/Specific/Syndicate/telecrystal.rsi - size: Tiny + size: 20 - type: Stack count: 20 stackType: Telecrystal @@ -29,6 +29,8 @@ components: - type: Stack count: 1 + - type: Item + size: 1 - type: entity parent: Telecrystal @@ -37,6 +39,8 @@ components: - type: Stack count: 5 + - type: Item + size: 5 - type: entity parent: Telecrystal @@ -45,6 +49,8 @@ components: - type: Stack count: 10 + - type: Item + size: 10 # Uplinks - type: entity diff --git a/Resources/Prototypes/Entities/Objects/Tools/access_configurator.yml b/Resources/Prototypes/Entities/Objects/Tools/access_configurator.yml index 7863cf8c09..c8b05c6959 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/access_configurator.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/access_configurator.yml @@ -11,7 +11,7 @@ sprite: Objects/Tools/access_configurator.rsi state: icon - type: Item - size: Small + size: 5 - type: Clothing sprite: Objects/Tools/access_configurator.rsi quickEquip: false @@ -62,12 +62,12 @@ - type: UserInterface interfaces: - key: enum.AccessOverriderUiKey.Key - type: AccessOverriderBoundUserInterface - - type: ActivatableUI + type: AccessOverriderBoundUserInterface + - type: ActivatableUI key: enum.AccessOverriderUiKey.Key - requireHands: true - closeOnHandDeselect: false - singleUser: true + requireHands: true + closeOnHandDeselect: false + singleUser: true - type: ItemSlots - type: ContainerContainer containers: diff --git a/Resources/Prototypes/Entities/Objects/Tools/bucket.yml b/Resources/Prototypes/Entities/Objects/Tools/bucket.yml index c7d62d759b..2a5870908f 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/bucket.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/bucket.yml @@ -16,7 +16,7 @@ state: fill-1 visible: false - type: Item - size: Normal + size: 100 - type: Clothing sprite: Objects/Tools/bucket.rsi slots: diff --git a/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml b/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml index e8d95ff9cb..e73d80f83b 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml @@ -19,7 +19,7 @@ sprite: Objects/Tools/cable-coils.rsi - type: Item sprite: Objects/Tools/cable-coils.rsi - size: Small + size: 30 - type: CablePlacer - type: Clickable - type: StaticPrice @@ -62,6 +62,8 @@ state: coilhv-10 - type: Stack count: 10 + - type: Item + size: 10 - type: entity parent: CableHVStack10 @@ -81,6 +83,8 @@ state: coilhv-10 - type: Stack count: 1 + - type: Item + size: 1 - type: entity parent: CableStack @@ -117,6 +121,8 @@ state: coilmv-10 - type: Stack count: 10 + - type: Item + size: 10 - type: entity parent: CableMVStack10 @@ -136,6 +142,8 @@ state: coilmv-10 - type: Stack count: 1 + - type: Item + size: 1 - type: entity parent: CableStack @@ -171,6 +179,8 @@ state: coillv-10 - type: Stack count: 10 + - type: Item + size: 10 - type: entity parent: CableApcStack10 @@ -190,3 +200,5 @@ state: coillv-10 - type: Stack count: 1 + - type: Item + size: 1 diff --git a/Resources/Prototypes/Entities/Objects/Tools/cowtools.yml b/Resources/Prototypes/Entities/Objects/Tools/cowtools.yml index e6a7a43fa4..24eb0b02b2 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/cowtools.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/cowtools.yml @@ -127,7 +127,7 @@ - type: Sprite sprite: Objects/Tools/Cowtools/cowelder.rsi - type: Item - size: Small + size: 10 sprite: Objects/Tools/Cowtools/cowelder.rsi - type: Tool speed: 0.05 diff --git a/Resources/Prototypes/Entities/Objects/Tools/fulton.yml b/Resources/Prototypes/Entities/Objects/Tools/fulton.yml index 612c8b93b9..8e54b4277f 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/fulton.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/fulton.yml @@ -28,7 +28,7 @@ mask: - Impassable - type: Item - size: Normal + size: 30 - type: Foldable folded: true - type: Clickable @@ -58,7 +58,7 @@ components: - type: Fulton - type: Item - size: Normal + size: 20 - type: Stack stackType: Fulton count: 10 @@ -84,7 +84,7 @@ suffix: One components: - type: Item - size: Small + size: 2 - type: Stack count: 1 diff --git a/Resources/Prototypes/Entities/Objects/Tools/gas_tanks.yml b/Resources/Prototypes/Entities/Objects/Tools/gas_tanks.yml index 9887d8cdc0..09d9945213 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/gas_tanks.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/gas_tanks.yml @@ -7,7 +7,7 @@ sprite: Objects/Tanks/generic.rsi state: icon - type: Item - size: Normal + size: 15 sprite: Objects/Tanks/generic.rsi - type: Clothing sprite: Objects/Tanks/generic.rsi @@ -100,7 +100,7 @@ - type: Sprite sprite: Objects/Tanks/emergency.rsi - type: Item - size: Small + size: 10 sprite: Objects/Tanks/emergency.rsi - type: GasTank outputPressure: 21.3 diff --git a/Resources/Prototypes/Entities/Objects/Tools/inflatable_wall.yml b/Resources/Prototypes/Entities/Objects/Tools/inflatable_wall.yml index 5c30cfdea3..b3d117dced 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/inflatable_wall.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/inflatable_wall.yml @@ -13,7 +13,7 @@ state: item_wall - type: Item sprite: Objects/Misc/inflatable_wall.rsi - size: Small + size: 10 - type: SpawnAfterInteract prototype: InflatableWall doAfter: 1 @@ -39,7 +39,7 @@ state: item_door - type: Item sprite: Objects/Misc/inflatable_door.rsi - size: Small + size: 4 - type: SpawnAfterInteract prototype: InflatableDoor doAfter: 1 @@ -57,6 +57,8 @@ components: - type: Sprite state: item_wall + - type: Item + size: 5 - type: Stack count: 5 @@ -67,6 +69,8 @@ components: - type: Sprite state: item_wall + - type: Item + size: 1 - type: Stack count: 1 @@ -77,5 +81,7 @@ components: - type: Sprite state: item_door + - type: Item + size: 1 - type: Stack count: 1 diff --git a/Resources/Prototypes/Entities/Objects/Tools/jaws_of_life.yml b/Resources/Prototypes/Entities/Objects/Tools/jaws_of_life.yml index 31d852354b..36f96f61af 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/jaws_of_life.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/jaws_of_life.yml @@ -11,7 +11,7 @@ sprite: Objects/Tools/jaws_of_life.rsi state: jaws_pry - type: Item - size: Normal + size: 50 - type: Clothing sprite: Objects/Tools/jaws_of_life.rsi quickEquip: false @@ -61,7 +61,7 @@ sprite: Objects/Tools/jaws_of_life.rsi state: syn_jaws_pry - type: Item - size: Normal + size: 35 - type: Tool qualities: - Prying diff --git a/Resources/Prototypes/Entities/Objects/Tools/jetpacks.yml b/Resources/Prototypes/Entities/Objects/Tools/jetpacks.yml index d63225b2bd..b87bbae0d8 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/jetpacks.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/jetpacks.yml @@ -37,7 +37,7 @@ state: icon - type: Item sprite: Objects/Tanks/Jetpacks/blue.rsi - size: Large + size: 100 - type: UserInterface interfaces: - key: enum.SharedGasTankUiKey.Key @@ -153,7 +153,7 @@ - Back - type: Item sprite: Objects/Tanks/Jetpacks/captain.rsi - size: Normal + size: 30 - type: Tag tags: - HighRiskItem diff --git a/Resources/Prototypes/Entities/Objects/Tools/lighters.yml b/Resources/Prototypes/Entities/Objects/Tools/lighters.yml index a3b6b3fd6e..e3422f2a4a 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/lighters.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/lighters.yml @@ -40,7 +40,7 @@ visible: false - state: basic_icon_top - type: Item - size: Tiny + size: 1 sprite: Objects/Tools/lighters.rsi heldPrefix: off - type: ItemCooldown diff --git a/Resources/Prototypes/Entities/Objects/Tools/matches.yml b/Resources/Prototypes/Entities/Objects/Tools/matches.yml index 98affd271c..fd7e185cb0 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/matches.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/matches.yml @@ -4,10 +4,9 @@ abstract: true components: - type: Storage - maxSlots: 7 - maxTotalWeight: 14 + capacity: 10 - type: Item - size: Small + size: 10 - type: entity name: match stick @@ -27,7 +26,7 @@ - type: Item sprite: Objects/Tools/matches.rsi heldPrefix: unlit - size: Tiny + size: 1 - type: Matchstick duration: 10 igniteSound: @@ -81,10 +80,9 @@ - type: Item sprite: Objects/Tools/matches.rsi heldPrefix: matchbox - size: Small + size: 5 - type: Storage - maxSlots: 5 - maxTotalWeight: 5 + capacity: 5 - type: StorageFill contents: - id: Matchstick diff --git a/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml b/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml index 8a1c33df76..e9f0526796 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml @@ -8,11 +8,9 @@ sound: path: /Audio/Items/toolbox_drop.ogg - type: Storage - maxSlots: 7 - maxItemSize: Normal - maxTotalWeight: 14 + capacity: 60 - type: Item - size: Huge + size: 9999 - type: ItemCooldown - type: MeleeWeapon damage: @@ -116,8 +114,7 @@ - type: Item sprite: Objects/Tools/Toolboxes/toolbox_syn.rsi - type: Storage - maxItemSize: Large - maxTotalWeight: 28 + capacity: 170 # this seems silly high - type: MeleeWeapon damage: types: diff --git a/Resources/Prototypes/Entities/Objects/Tools/tools.yml b/Resources/Prototypes/Entities/Objects/Tools/tools.yml index 566c72dafd..12a6ede231 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/tools.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/tools.yml @@ -140,7 +140,7 @@ state: icon - type: Item sprite: Objects/Tools/crowbar.rsi - size: Small + size: 10 - type: ItemCooldown - type: MeleeWeapon wideAnimationRotation: -135 @@ -191,7 +191,7 @@ - state: green-unlit shader: unshaded - type: Item - size: Small + size: 5 - type: Clothing sprite: Objects/Tools/multitool.rsi quickEquip: false @@ -240,7 +240,7 @@ map: ["enum.NetworkConfiguratorLayers.ModeLight"] shader: unshaded - type: Item - size: Small + size: 5 - type: Clothing sprite: Objects/Tools/network_configurator.rsi quickEquip: false @@ -290,7 +290,7 @@ state: drill_screw - type: Item sprite: Objects/Tools/drill.rsi - size: Small + size: 10 - type: Tool qualities: - Screwing @@ -346,7 +346,7 @@ sprite: Objects/Tools/rcd.rsi state: icon - type: Item - size: Normal + size: 20 - type: Clothing sprite: Objects/Tools/rcd.rsi quickEquip: false @@ -422,7 +422,7 @@ state: omnitool-screwing - type: Item sprite: Objects/Tools/omnitool.rsi - size: Normal + size: 20 - type: Tag tags: - Multitool @@ -497,7 +497,7 @@ types: Blunt: 14 - type: Item - size: Normal + size: 90 sprite: Objects/Tools/shovel.rsi - type: PhysicalComposition materialComposition: @@ -517,7 +517,7 @@ state: icon - type: Item sprite: Objects/Tools/rolling_pin.rsi - size: Small + size: 10 - type: Clothing sprite: Objects/Tools/rolling_pin.rsi quickEquip: false diff --git a/Resources/Prototypes/Entities/Objects/Tools/welders.yml b/Resources/Prototypes/Entities/Objects/Tools/welders.yml index caa0d4c208..7c3de82d0a 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/welders.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/welders.yml @@ -17,7 +17,7 @@ shader: unshaded visible: false - type: Item - size: Small + size: 10 sprite: Objects/Tools/welder.rsi - type: ToggleableLightVisuals spriteLayer: flame @@ -142,7 +142,7 @@ - type: Sprite sprite: Objects/Tools/welder_mini.rsi - type: Item - size: Tiny + size: 5 sprite: Objects/Tools/welder_mini.rsi - type: RefillableSolution solution: Welder diff --git a/Resources/Prototypes/Entities/Objects/Vehicles/keys.yml b/Resources/Prototypes/Entities/Objects/Vehicles/keys.yml index 468f1aa3a5..f361c2b877 100644 --- a/Resources/Prototypes/Entities/Objects/Vehicles/keys.yml +++ b/Resources/Prototypes/Entities/Objects/Vehicles/keys.yml @@ -5,7 +5,7 @@ description: Interesting design. components: - type: Item - size: Tiny + size: 2 - type: Tag tags: - VehicleKey diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/funny.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/funny.yml index 84883c975d..c33c1f92c5 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/funny.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/funny.yml @@ -12,7 +12,7 @@ map: ["base"] - type: Item sprite: Objects/Weapons/Bombs/hot_potato.rsi - size: Small + size: 5 - type: AmbientSound enabled: false range: 8 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/plastic.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/plastic.yml index e3581370f0..4d9fed1f91 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/plastic.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/plastic.yml @@ -12,7 +12,7 @@ map: ["base"] - type: Item sprite: Objects/Weapons/Bombs/c4.rsi - size: Small + size: 10 - type: OnUseTimerTrigger delay: 10 delayOptions: [10, 30, 60, 120, 300] diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/spider.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/spider.yml index 8f997b7687..50a7ea8687 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/spider.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/spider.yml @@ -10,7 +10,7 @@ state: icon - type: Item sprite: Objects/Weapons/Bombs/spidercharge.rsi - size: Small + size: 10 - type: SpiderCharge - type: OnUseTimerTrigger delay: 10 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/antimateriel.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/antimateriel.yml index 28157ef345..c7980f845f 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/antimateriel.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/antimateriel.yml @@ -12,7 +12,7 @@ proto: CartridgeAntiMateriel capacity: 10 - type: Item - size: Small + size: 5 - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/caseless_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/caseless_rifle.yml index 063268d8b5..4a77bfcfc5 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/caseless_rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/caseless_rifle.yml @@ -12,7 +12,7 @@ proto: CartridgeCaselessRifle capacity: 60 - type: Item - size: Small + size: 5 - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/light_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/light_rifle.yml index 0751d3608c..1c8fbc26e1 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/light_rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/light_rifle.yml @@ -12,7 +12,7 @@ proto: CartridgeLightRifle capacity: 50 - type: Item - size: Small + size: 5 - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/magnum.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/magnum.yml index 1ff05558e5..5a9a850e9c 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/magnum.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/magnum.yml @@ -11,7 +11,7 @@ proto: CartridgeMagnum capacity: 60 - type: Item - size: Small + size: 5 - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/pistol.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/pistol.yml index 867aa15a34..a9a78f399a 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/pistol.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/pistol.yml @@ -12,7 +12,7 @@ proto: CartridgePistol capacity: 60 - type: Item - size: Small + size: 5 - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/rifle.yml index 5ed2fcc63e..3725ad91af 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/rifle.yml @@ -11,7 +11,7 @@ proto: CartridgeRifle capacity: 60 - type: Item - size: Small + size: 5 - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/base_cartridge.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/base_cartridge.yml index 1831db28e7..de6f9f92a5 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/base_cartridge.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/base_cartridge.yml @@ -20,7 +20,7 @@ tags: - Cartridge - type: Item - size: Tiny + size: 1 - type: SpaceGarbage - type: EmitSoundOnLand sound: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/caseless_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/caseless_rifle.yml index 0d16f1e966..773ff01ed8 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/caseless_rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/caseless_rifle.yml @@ -15,7 +15,7 @@ proto: CartridgeCaselessRifle capacity: 30 - type: Item - size: Small + size: 5 - type: ContainerContainer containers: ballistic-ammo: !type:Container @@ -42,7 +42,7 @@ proto: CartridgeCaselessRifle capacity: 10 - type: Item - size: Tiny + size: 3 - type: Sprite sprite: Objects/Weapons/Guns/Ammunition/Magazine/CaselessRifle/caseless_rifle_mag_short.rsi layers: @@ -67,7 +67,7 @@ proto: CartridgeCaselessRifle capacity: 10 - type: Item - size: Small + size: 5 - type: Sprite sprite: Objects/Weapons/Guns/Ammunition/Magazine/CaselessRifle/caseless_pistol_mag.rsi layers: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/heavy_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/heavy_rifle.yml index d8af7064a4..239533c940 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/heavy_rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/heavy_rifle.yml @@ -8,7 +8,7 @@ tags: - MagazineHeavyRifle - type: Item - size: Small + size: 10 - type: BallisticAmmoProvider mayTransfer: true capacity: 100 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/light_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/light_rifle.yml index 7ae4f32524..e586364369 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/light_rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/light_rifle.yml @@ -16,7 +16,7 @@ proto: CartridgeLightRifle capacity: 30 - type: Item - size: Small + size: 5 - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/magnum.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/magnum.yml index b65dac5d15..6060898d49 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/magnum.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/magnum.yml @@ -14,7 +14,7 @@ - CartridgeMagnum capacity: 25 - type: Item - size: Small + size: 10 - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/pistol.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/pistol.yml index 8793a717e7..4ed38fdeb3 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/pistol.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/pistol.yml @@ -14,7 +14,7 @@ - CartridgePistol capacity: 10 - type: Item - size: Small + size: 5 - type: ContainerContainer containers: ballistic-ammo: !type:Container @@ -47,7 +47,7 @@ - CartridgePistol capacity: 16 - type: Item - size: Small + size: 5 - type: ContainerContainer containers: ballistic-ammo: !type:Container @@ -80,7 +80,7 @@ - CartridgePistol capacity: 35 - type: Item - size: Small + size: 10 - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/rifle.yml index 8e65cd992e..ca1f9b8de2 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/rifle.yml @@ -9,7 +9,7 @@ tags: - MagazineRifle - type: Item - size: Small + size: 5 - type: BallisticAmmoProvider mayTransfer: true whitelist: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/shotgun.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/shotgun.yml index cbe9bbfbe9..b78825f3e1 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/shotgun.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/shotgun.yml @@ -16,7 +16,7 @@ soundRack: path: /Audio/Weapons/Guns/Cock/smg_cock.ogg - type: Item - size: Small + size: 5 - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/explosives.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/explosives.yml index 86da8e6662..56d420cb33 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/explosives.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/explosives.yml @@ -10,7 +10,7 @@ tags: - CartridgeRocket - type: Item - size: Small + size: 5 - type: CartridgeAmmo proto: BulletRocket deleteOnSpawn: true @@ -30,7 +30,7 @@ tags: - CartridgeRocket - type: Item - size: Small + size: 5 - type: CartridgeAmmo proto: BulletWeakRocket deleteOnSpawn: true @@ -52,7 +52,7 @@ tags: - Grenade - type: Item - size: Small + size: 5 - type: Sprite - type: entity diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_pka.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_pka.yml index f85e93b893..041cf446c1 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_pka.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_pka.yml @@ -7,7 +7,7 @@ sprite: Objects/Weapons/Guns/Basic/kinetic_accelerator.rsi - type: Item sprite: Objects/Weapons/Guns/Basic/kinetic_accelerator.rsi - size: Normal + size: 30 - type: GunWieldBonus minAngle: -43 maxAngle: -43 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_staff.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_staff.yml index 9cab4cac25..76bd0b9e75 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_staff.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_staff.yml @@ -7,7 +7,7 @@ sprite: Objects/Weapons/Guns/Basic/staves.rsi - type: Item heldPrefix: staff - size: Normal + size: 60 - type: Gun fireRate: 1 selectedMode: SemiAuto diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_wand.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_wand.yml index c4a937ee2c..3b97eac8ee 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_wand.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_wand.yml @@ -7,7 +7,7 @@ sprite: Objects/Weapons/Guns/Basic/wands.rsi - type: Item heldPrefix: wand - size: Normal + size: 30 - type: Gun fireRate: 0.5 selectedMode: SemiAuto diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/spraynozzle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/spraynozzle.yml index f2e93a607e..d4d00252f5 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/spraynozzle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/spraynozzle.yml @@ -9,7 +9,7 @@ state: icon - type: Item sprite: Objects/Weapons/Guns/Basic/spraynozzle.rsi - size: Normal + size: 30 - type: Gun cameraRecoilScalar: 0 #no recoil fireRate: 4 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/watergun.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/watergun.yml index e925bdab87..a815f9c0cd 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/watergun.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/watergun.yml @@ -10,7 +10,7 @@ slots: BELT - type: Item sprite: Objects/Weapons/Guns/Pistols/water_pistol.rsi - size: Small + size: 10 - type: Gun clumsyProof: true cameraRecoilScalar: 0 #no recoil @@ -95,7 +95,7 @@ map: [ "enum.DamageStateVisualLayers.Base" ] - type: Item sprite: Objects/Weapons/Guns/Pistols/soaker.rsi - size: Normal + size: 35 - type: RandomSprite getAllGroups: true available: @@ -132,7 +132,7 @@ map: [ "enum.DamageStateVisualLayers.Base" ] - type: Item sprite: Objects/Weapons/Guns/Pistols/soaker.rsi - size: Normal + size: 35 - type: RandomSprite getAllGroups: true available: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml index d4b9142504..461a6cc437 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml @@ -5,7 +5,7 @@ components: - type: Sprite - type: Item - size: Large + size: 50 - type: Clothing sprite: Objects/Weapons/Guns/Battery/laser_retro.rsi quickEquip: false @@ -37,7 +37,7 @@ abstract: true components: - type: Item - size: Small + size: 10 - type: Tag tags: - Sidearm @@ -408,7 +408,7 @@ description: An experimental high-energy laser pistol with a self-charging nuclear battery. components: - type: Item - size: Normal # Intentionally larger than other pistols + size: 30 # Intentionally larger than other pistols - type: Sprite sprite: Objects/Weapons/Guns/Battery/advancedlasergun.rsi layers: @@ -464,7 +464,7 @@ path: /Audio/Weapons/Guns/Gunshots/taser2.ogg - type: ProjectileBatteryAmmoProvider proto: AnomalousParticleDeltaStrong - fireCost: 100 + fireCost: 100 - type: BatteryWeaponFireModes fireModes: - proto: AnomalousParticleDeltaStrong @@ -476,13 +476,13 @@ - type: Construction graph: UpgradeWeaponPistolCHIMP node: start - + - type: entity name: experimental C.H.I.M.P. handcannon parent: WeaponPistolCHIMP id: WeaponPistolCHIMPUpgraded description: This C.H.I.M.P. seems to have a greater punch than is usual... - components: + components: - type: BatteryWeaponFireModes fireModes: - proto: AnomalousParticleDeltaStrong @@ -490,7 +490,7 @@ - proto: AnomalousParticleEpsilonStrong fireCost: 100 - proto: AnomalousParticleOmegaStrong - fireCost: 100 + fireCost: 100 - proto: AnomalousParticleZetaStrong fireCost: 100 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Bow/bow.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Bow/bow.yml index 4b7125f571..88640f7812 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Bow/bow.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Bow/bow.yml @@ -8,7 +8,7 @@ - type: Sprite sprite: Objects/Weapons/Guns/Bow/bow.rsi - type: Item - size: Normal + size: 60 - type: Clothing quickEquip: false slots: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/HMGs/hmgs.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/HMGs/hmgs.yml index 1b318beac8..785b36cc62 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/HMGs/hmgs.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/HMGs/hmgs.yml @@ -7,7 +7,6 @@ components: - type: Sprite - type: Item - size: Huge - type: Gun fireRate: 20 selectedMode: FullAuto @@ -34,6 +33,7 @@ map: ["enum.GunVisualLayers.Base"] - type: Item sprite: Objects/Weapons/Guns/HMGs/minigun.rsi + size: 90 - type: Gun fireRate: 15 soundGunshot: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml index 3d6cd680a0..62142519bf 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml @@ -7,7 +7,7 @@ components: - type: Sprite - type: Item - size: Large + size: 60 - type: Clothing sprite: Objects/Weapons/Guns/LMGs/l6.rsi quickEquip: false diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml index 2dbf71840c..3796ac92b8 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml @@ -12,7 +12,7 @@ slots: - Back - type: Item - size: Large + size: 60 - type: StaticPrice price: 500 - type: ContainerContainer diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml index a6c6f1e677..7bfd914d94 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml @@ -12,7 +12,7 @@ - state: mag-0 map: ["enum.GunVisualLayers.Mag"] - type: Item - size: Small + size: 10 - type: Tag tags: - Sidearm diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml index 8dbcf2b303..32a2ea4623 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml @@ -4,7 +4,7 @@ abstract: true components: - type: Item - size: Small + size: 10 - type: Sprite sprite: Objects/Weapons/Guns/Projectiles/arrows.rsi - type: Fixtures diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Revolvers/revolvers.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Revolvers/revolvers.yml index c523fd2797..1851dcddf6 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Revolvers/revolvers.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Revolvers/revolvers.yml @@ -8,7 +8,7 @@ - type: Sprite state: icon - type: Item - size: Small + size: 10 - type: Tag tags: - Sidearm @@ -122,7 +122,7 @@ params: volume: 2.25 -- type: entity +- type: entity name: Python parent: WeaponRevolverPython id: WeaponRevolverPythonAP # For the uplink. @@ -155,4 +155,4 @@ - type: RevolverAmmoProvider capacity: 5 chambers: [ True, True, True, True, True ] - ammoSlots: [ null, null, null, null, null ] + ammoSlots: [ null, null, null, null, null ] \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml index d460c0c8f0..114573c087 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml @@ -7,7 +7,7 @@ components: - type: Sprite - type: Item - size: Large + size: 50 - type: Clothing sprite: Objects/Weapons/Guns/Rifles/ak.rsi quickEquip: false diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml index 6bf6fcf695..e423c09841 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml @@ -7,7 +7,7 @@ components: - type: Sprite - type: Item - size: Normal + size: 30 - type: Clothing sprite: Objects/Weapons/Guns/SMGs/atreides.rsi quickEquip: false diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml index 5a08eb3636..4bee243d57 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml @@ -11,7 +11,7 @@ map: [ "enum.GunVisualLayers.Base" ] - type: Item # If you update this also update the bulldog's size. - size: Large + size: 30 - type: Clothing sprite: Objects/Weapons/Guns/Shotguns/db_shotgun.rsi quickEquip: false @@ -57,6 +57,8 @@ map: ["enum.GunVisualLayers.Base"] - state: mag-0 map: ["enum.GunVisualLayers.Mag"] + - type: Item + size: 30 - type: Clothing sprite: Objects/Weapons/Guns/Shotguns/bulldog.rsi quickEquip: false @@ -135,7 +137,7 @@ - type: Clothing sprite: Objects/Weapons/Guns/Shotguns/enforcer.rsi - type: BallisticAmmoProvider - + - type: entity name: Enforcer parent: BaseWeaponShotgun @@ -149,7 +151,7 @@ sprite: Objects/Weapons/Guns/Shotguns/enforcer.rsi - type: BallisticAmmoProvider proto: ShellShotgunBeanbag - + - type: entity name: Kammerer parent: BaseWeaponShotgun @@ -160,8 +162,6 @@ sprite: Objects/Weapons/Guns/Shotguns/pump.rsi - type: Clothing sprite: Objects/Weapons/Guns/Shotguns/pump.rsi - - type: Item - size: Normal - type: BallisticAmmoProvider capacity: 4 @@ -176,7 +176,7 @@ - type: Clothing sprite: Objects/Weapons/Guns/Shotguns/sawn.rsi - type: Item - size: Small + size: 10 - type: Gun fireRate: 4 - type: BallisticAmmoProvider @@ -210,6 +210,8 @@ sprite: Objects/Weapons/Guns/Shotguns/hm_pistol.rsi - type: Clothing sprite: Objects/Weapons/Guns/Shotguns/hm_pistol.rsi + - type: Item + size: 10 - type: Gun fireRate: 4 - type: BallisticAmmoProvider @@ -243,6 +245,8 @@ sprite: Objects/Weapons/Guns/Shotguns/improvised_shotgun.rsi - type: Clothing sprite: Objects/Weapons/Guns/Shotguns/improvised_shotgun.rsi + - type: Item + size: 75 - type: Gun fireRate: 4 #No reason to stifle the firerate since you have to manually reload every time anyways. - type: BallisticAmmoProvider diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml index 4a16aadb65..68c494b888 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml @@ -10,7 +10,7 @@ - state: base map: ["enum.GunVisualLayers.Base"] - type: Item - size: Large + size: 50 - type: Clothing sprite: Objects/Weapons/Guns/Snipers/bolt_gun_wood.rsi quickEquip: false diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/flare_gun.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/flare_gun.yml index cfcc0a01cd..d41346380c 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/flare_gun.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/flare_gun.yml @@ -10,7 +10,7 @@ - state: icon map: ["enum.GunVisualLayers.Base"] - type: Item - size: Small + size: 10 sprite: Objects/Weapons/Guns/Shotguns/flaregun.rsi - type: Gun fireRate: 8 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/pneumatic_cannon.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/pneumatic_cannon.yml index fcd028a64e..9f3aec5c39 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/pneumatic_cannon.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/pneumatic_cannon.yml @@ -12,7 +12,7 @@ map: [ "tank" ] visible: false - type: Item - size: Large + size: 50 - type: Clothing quickEquip: false slots: @@ -32,9 +32,7 @@ container: storagebase - type: PneumaticCannon - type: Storage - maxSlots: 8 - maxItemSize: Normal - maxTotalWeight: 32 + capacity: 30 blacklist: tags: - CannonRestrict @@ -77,12 +75,10 @@ layers: - state: piecannon - type: Storage - maxSlots: 8 - maxItemSize: Normal - maxTotalWeight: 32 whitelist: components: - CreamPie + capacity: 40 - type: Gun fireRate: 1 selectedMode: SemiAuto @@ -97,7 +93,7 @@ - type: ContainerAmmoProvider container: storagebase - type: Item - size: Normal + size: 50 - type: Clothing sprite: Objects/Weapons/Guns/Cannons/pie_cannon.rsi quickEquip: false @@ -124,13 +120,9 @@ suffix: Admeme components: - type: Item - size: Huge + size: 9999 - type: Storage - maxSlots: 100 - maxItemSize: Huge - maxTotalWeight: 1600 - whitelist: - tags: [] #dodging a test fail like the IRS + capacity: 9999 - type: PneumaticCannon gasUsage: 0 throwItems: false diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/armblade.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/armblade.yml index 497876f359..9e9288c8d4 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/armblade.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/armblade.yml @@ -16,7 +16,7 @@ Slash: 25 Piercing: 15 - type: Item - size: Normal + size: 15 sprite: Objects/Weapons/Melee/armblade.rsi - type: Tool qualities: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/baseball_bat.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/baseball_bat.yml index a1a4f484fa..c1fc668d59 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/baseball_bat.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/baseball_bat.yml @@ -18,7 +18,7 @@ types: Blunt: 8 - type: Item - size: Normal + size: 80 - type: Tool qualities: - Rolling diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/chainsaw.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/chainsaw.yml index bfddd764ca..13f5191c10 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/chainsaw.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/chainsaw.yml @@ -31,7 +31,7 @@ Blunt: 5 Structural: 20 - type: Item - size: Normal + size: 50 sprite: Objects/Weapons/Melee/chainsaw.rsi - type: DisarmMalus - type: RefillableSolution diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/cult.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/cult.yml index ff80144f9f..661ee379b2 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/cult.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/cult.yml @@ -15,7 +15,7 @@ types: Slash: 12 - type: Item - size: Normal + size: 20 - type: Clothing sprite: Objects/Weapons/Melee/cult_dagger.rsi slots: @@ -39,7 +39,7 @@ types: Slash: 33 - type: Item - size: Normal + size: 20 - type: Clothing sprite: Objects/Weapons/Melee/cult_blade.rsi slots: @@ -75,7 +75,7 @@ Slash: 12 Structural: 30 - type: Item - size: Huge + size: 150 - type: Clothing sprite: Objects/Weapons/Melee/cult_halberd.rsi quickEquip: false diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml index c00fd1ab86..47dfea9d86 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml @@ -30,7 +30,7 @@ types: Blunt: 4.5 - type: Item - size: Small + size: 5 sprite: Objects/Weapons/Melee/e_sword.rsi - type: UseDelay delay: 1.0 @@ -95,7 +95,7 @@ types: Blunt: 1 - type: Item - size: Tiny + size: 2 sprite: Objects/Weapons/Melee/e_dagger.rsi - type: UseDelay delay: 1.0 @@ -161,7 +161,7 @@ shader: unshaded map: [ "blade" ] - type: Item - size: Small + size: 5 sprite: Objects/Weapons/Melee/e_cutlass.rsi - type: entity @@ -198,7 +198,7 @@ shader: unshaded map: [ "blade" ] - type: Item - size: Small + size: 10 sprite: Objects/Weapons/Melee/e_sword_double.rsi - type: Reflect enabled: true diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/fireaxe.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/fireaxe.yml index 1c786371b3..6d27e3e7d6 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/fireaxe.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/fireaxe.yml @@ -29,7 +29,7 @@ Slash: 10.5 Structural: 60 - type: Item - size: Huge + size: 150 - type: Clothing sprite: Objects/Weapons/Melee/fireaxe.rsi quickEquip: false diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/gohei.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/gohei.yml index ec9717ea22..9e673da49d 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/gohei.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/gohei.yml @@ -13,5 +13,5 @@ types: Blunt: 3 #You'd be better off punching people - type: Item - size: Small + size: 12 sprite: Objects/Weapons/Melee/gohei.rsi diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml index 98ecaa28a6..bbd18927e1 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml @@ -37,9 +37,10 @@ - Knife - type: Sprite sprite: Objects/Weapons/Melee/kitchen_knife.rsi + size: 2 state: icon - type: Item - size: Small + size: 10 sprite: Objects/Weapons/Melee/kitchen_knife.rsi - type: GuideHelp guides: @@ -56,6 +57,7 @@ - Knife - type: Sprite sprite: Objects/Weapons/Melee/cleaver.rsi + size: 4 state: butch - type: MeleeWeapon wideAnimationRotation: -135 @@ -64,7 +66,7 @@ types: Slash: 10 - type: Item - size: Small + size: 10 sprite: Objects/Weapons/Melee/cleaver.rsi - type: GuideHelp guides: @@ -82,7 +84,7 @@ - Knife - type: Sprite sprite: Objects/Weapons/Melee/combat_knife.rsi - size: Tiny + size: 2 state: icon - type: MeleeWeapon wideAnimationRotation: -135 @@ -91,7 +93,7 @@ types: Slash: 10 - type: Item - size: Small + size: 10 sprite: Objects/Weapons/Melee/combat_knife.rsi - type: DisarmMalus malus: 0.225 @@ -104,10 +106,10 @@ components: - type: Sprite sprite: Objects/Weapons/Melee/survival_knife.rsi - size: Tiny + size: 2 state: icon - type: Item - size: Small + size: 10 sprite: Objects/Weapons/Melee/survival_knife.rsi - type: entity @@ -118,7 +120,7 @@ components: - type: Sprite sprite: Objects/Weapons/Melee/kukri_knife.rsi - size: Tiny + size: 2 state: icon - type: MeleeWeapon attackRate: 1.0 @@ -126,7 +128,7 @@ types: Slash: 15 - type: Item - size: Small + size: 10 sprite: Objects/Weapons/Melee/kukri_knife.rsi - type: entity @@ -145,7 +147,7 @@ node: icon - type: Sprite sprite: Objects/Weapons/Melee/shiv.rsi - size: Tiny + size: 2 state: icon - type: MeleeWeapon attackRate: 1.5 @@ -153,7 +155,7 @@ types: Slash: 5.5 - type: Item - size: Tiny #as much as a regular glass shard + size: 4 #as much as a regular glass shard sprite: Objects/Weapons/Melee/shiv.rsi - type: DisarmMalus malus: 0.225 @@ -167,7 +169,7 @@ - type: Construction graph: ReinforcedShiv node: icon - size: Tiny + size: 2 state: icon - type: MeleeWeapon attackRate: 1.5 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/mining.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/mining.yml index e5046d5c1f..f3bb0ceec9 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/mining.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/mining.yml @@ -57,7 +57,7 @@ Slash: 2.5 - type: GunRequiresWield - type: Item - size: Huge + size: 150 - type: DisarmMalus - type: Tool qualities: @@ -80,7 +80,7 @@ types: Slash: 6.5 - type: Item - size: Small + size: 10 - type: Tag tags: - Knife @@ -112,4 +112,4 @@ wideAnimationRotation: -135 attackRate: 1.25 - type: Item - size: Huge + size: 150 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/needle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/needle.yml index 11efeba5f8..48b2d6ad2b 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/needle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/needle.yml @@ -13,5 +13,5 @@ types: Piercing: 1 - type: Item - size: Tiny + size: 1 - type: BalloonPopper diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/pickaxe.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/pickaxe.yml index 85f1e4a4c7..a0f497bd26 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/pickaxe.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/pickaxe.yml @@ -26,7 +26,7 @@ types: Structural: 10 - type: Item - size: Normal + size: 80 sprite: Objects/Weapons/Melee/pickaxe.rsi - type: UseDelay delay: 1 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml index 037844507f..d34d29d5eb 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml @@ -47,7 +47,7 @@ types: Piercing: 15 - type: Item - size: Huge + size: 95 - type: Clothing quickEquip: false slots: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml index 87b7c468c3..25c9cf6125 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml @@ -26,7 +26,7 @@ - type: ItemCooldown - type: Item heldPrefix: off - size: Large + size: 100 - type: Clothing sprite: Objects/Weapons/Melee/stunprod.rsi quickEquip: false diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml index 9bd9d6c12f..23160f13ea 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml @@ -21,7 +21,7 @@ reflectProb: .5 spread: 90 - type: Item - size: Normal + size: 15 sprite: Objects/Weapons/Melee/captain_sabre.rsi - type: Tag tags: @@ -49,7 +49,7 @@ soundHit: path: /Audio/Weapons/bladeslice.ogg - type: Item - size: Normal + size: 15 sprite: Objects/Weapons/Melee/katana.rsi - type: DisarmMalus @@ -68,7 +68,7 @@ types: Slash: 30 - type: Item - size: Normal + size: 15 sprite: Objects/Weapons/Melee/energykatana.rsi - type: EnergyKatana - type: DashAbility @@ -105,7 +105,7 @@ soundHit: path: /Audio/Weapons/bladeslice.ogg - type: Item - size: Normal + size: 15 sprite: Objects/Weapons/Melee/machete.rsi - type: DisarmMalus @@ -128,7 +128,7 @@ soundHit: path: /Audio/Weapons/bladeslice.ogg - type: Item - size: Normal + size: 20 - type: Clothing sprite: Objects/Weapons/Melee/claymore.rsi slots: @@ -156,6 +156,6 @@ soundHit: path: /Audio/Weapons/bladeslice.ogg - type: Item - size: Normal + size: 15 sprite: Objects/Weapons/Melee/cutlass.rsi - type: DisarmMalus diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/weapon_toolbox.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/weapon_toolbox.yml index e5a03d5136..b5f8590304 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/weapon_toolbox.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/weapon_toolbox.yml @@ -9,7 +9,7 @@ sprite: Objects/Tools/Toolboxes/toolbox_red.rsi state: icon - type: Item - size: Huge + size: 150 sprite: Objects/Tools/Toolboxes/toolbox_red.rsi - type: MeleeWeapon wideAnimationRotation: -135 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/white_cane.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/white_cane.yml index 997c3771d5..c76ebf4d78 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/white_cane.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/white_cane.yml @@ -8,7 +8,7 @@ sprite: Objects/Weapons/Melee/white_cane.rsi state: icon - type: Item - size: Normal + size: 15 sprite: Objects/Weapons/Melee/white_cane.rsi - type: MeleeWeapon wideAnimationRotation: 45 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml index f694762a09..1afb564036 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml @@ -5,7 +5,7 @@ description: Linked together with some spare cuffs and metal. components: - type: Item - size: Normal + size: 20 - type: Sprite sprite: Objects/Weapons/Throwable/bola.rsi state: icon diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml index ece4ec4ef4..9f18b94d2c 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml @@ -9,7 +9,7 @@ - state: icon map: ["enum.TriggerVisualLayers.Base"] - type: Item - size: Small + size: 5 - type: Clothing quickEquip: false slots: @@ -267,7 +267,7 @@ - state: empty map: [ "enum.ConstructionVisuals.Layer" ] - type: Item - size: Small + size: 8 - type: PayloadCase - type: Construction graph: ModularGrenadeGraph diff --git a/Resources/Prototypes/Entities/Objects/Weapons/security.yml b/Resources/Prototypes/Entities/Objects/Weapons/security.yml index bf4a155ee4..92e7dbd4c1 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/security.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/security.yml @@ -31,7 +31,7 @@ - type: ItemCooldown - type: Item heldPrefix: off - size: Normal + size: 20 - type: Clothing sprite: Objects/Weapons/Melee/stunbaton.rsi quickEquip: false @@ -81,7 +81,7 @@ Blunt: 20 bluntStaminaDamageFactor: 1.5 - type: Item - size: Normal + size: 20 - type: Clothing sprite: Objects\Weapons\Melee\truncheon.rsi quickEquip: false @@ -122,7 +122,7 @@ Blunt: 0 # melee weapon to allow flashing individual targets angle: 10 - type: Item - size: Small + size: 5 sprite: Objects/Weapons/Melee/flash.rsi - type: ItemCooldown - type: StaticPrice diff --git a/Resources/Prototypes/Entities/Objects/base_item.yml b/Resources/Prototypes/Entities/Objects/base_item.yml index bcc8e0dce4..32325603c1 100644 --- a/Resources/Prototypes/Entities/Objects/base_item.yml +++ b/Resources/Prototypes/Entities/Objects/base_item.yml @@ -4,7 +4,7 @@ abstract: true components: - type: Item - size: Small + size: 5 - type: Clickable - type: InteractionOutline - type: MovedByPressure diff --git a/Resources/Prototypes/Entities/Structures/Furniture/bookshelf.yml b/Resources/Prototypes/Entities/Structures/Furniture/bookshelf.yml index 6d5e0e3dcd..9f1de3ff39 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/bookshelf.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/bookshelf.yml @@ -47,8 +47,7 @@ - type: Pullable - type: Occluder - type: Storage - maxSlots: 32 - maxItemSize: Normal + capacity: 200 whitelist: tags: - Document diff --git a/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml b/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml index 8d669ab6d2..aaff4e1e28 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml @@ -305,7 +305,7 @@ map: ["foldedLayer"] visible: false - type: Item - size: Large + size: 50 - type: Appearance - type: MeleeWeapon damage: @@ -339,4 +339,4 @@ - type: Rotatable - type: Sprite state: steel-bench - + diff --git a/Resources/Prototypes/Entities/Structures/Furniture/dresser.yml b/Resources/Prototypes/Entities/Structures/Furniture/dresser.yml index 29061a06b1..da2b82270f 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/dresser.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/dresser.yml @@ -25,8 +25,7 @@ - !type:DoActsBehavior acts: [ "Destruction" ] - type: Storage - maxSlots: 6 - maxItemSize: Normal + capacity: 50 - type: ContainerContainer containers: storagebase: !type:Container @@ -68,7 +67,7 @@ - id: ClothingUniformJumpskirtColorPink prob: 0.05 - id: ClothingUniformJumpsuitLoungewear - prob: 0.05 + prob: 0.05 orGroup: dressermainloot - id: Pen # It`s pen. prob: 0.03 @@ -98,7 +97,7 @@ prob: 0.03 orGroup: dressermainloot - id: ClothingUniformJumpsuitColorRed - prob: 0.03 + prob: 0.03 orGroup: dressermainloot - id: ClothingUniformJumpskirtColorRed prob: 0.03 @@ -185,7 +184,7 @@ prob: 0.03 orGroup: dresserthirdloot - id: ClothingUnderSocksCoder - prob: 0.03 + prob: 0.03 orGroup: dressermainloot - id: ClothingUnderSocksBee prob: 0.03 @@ -225,7 +224,7 @@ orGroup: dresserthirdloot - id: PlushieLizard prob: 0.03 - orGroup: dresserthirdloot + orGroup: dresserthirdloot - id: ClothingOuterSuitShrineMaiden prob: 0.03 orGroup: dressersecondloot @@ -424,7 +423,7 @@ - id: BrokenBottle prob: 0.001 orGroup: dressersecondloot - - id: FoodMeatRotten + - id: FoodMeatRotten prob: 0.001 orGroup: dressersecondloot - id: ClothingOuterSkub diff --git a/Resources/Prototypes/Entities/Structures/Furniture/rollerbeds.yml b/Resources/Prototypes/Entities/Structures/Furniture/rollerbeds.yml index 406ff7fa48..695a529734 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/rollerbeds.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/rollerbeds.yml @@ -7,7 +7,7 @@ - type: Transform noRot: true - type: Item - size: Normal + size: 25 - type: Sprite sprite: Structures/Furniture/rollerbeds.rsi noRot: true diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml index b84499d533..132da2f1a8 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml @@ -8,7 +8,7 @@ mode: SnapgridCenter components: - type: Item - size: Small + size: 10 - type: Transform anchored: true - type: Damageable diff --git a/Resources/Prototypes/Entities/Structures/Specific/Atmospherics/sensor.yml b/Resources/Prototypes/Entities/Structures/Specific/Atmospherics/sensor.yml index 4466b21b44..6fa085646a 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Atmospherics/sensor.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Atmospherics/sensor.yml @@ -87,7 +87,7 @@ description: Air sensor assembly. An assembly of air sensors? components: - type: Item - size: Small + size: 10 - type: Anchorable - type: Construction graph: AirSensor diff --git a/Resources/Prototypes/Entities/Structures/Storage/filing_cabinets.yml b/Resources/Prototypes/Entities/Structures/Storage/filing_cabinets.yml index f0ce9c46d3..b79921815b 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/filing_cabinets.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/filing_cabinets.yml @@ -6,8 +6,7 @@ description: A cabinet for all your filing needs. components: - type: Storage - maxSlots: 12 - maxItemSize: Normal + capacity: 80 whitelist: tags: - Document @@ -66,8 +65,7 @@ description: A small drawer for all your filing needs, Now with wheels! components: - type: Storage - maxSlots: 8 - maxItemSize: Normal + capacity: 50 whitelist: tags: - Document diff --git a/Resources/Prototypes/Entities/Structures/Storage/ore_box.yml b/Resources/Prototypes/Entities/Structures/Storage/ore_box.yml index 6bad8c319f..7099e1b45d 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/ore_box.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/ore_box.yml @@ -50,8 +50,7 @@ True: { visible: false } False: { visible: true } - type: Storage - maxSlots: 60 - maxItemSize: Normal + capacity: 525 storageOpenSound: /Audio/Effects/closetopen.ogg storageCloseSound: /Audio/Effects/closetclose.ogg whitelist: diff --git a/Resources/Prototypes/XenoArch/Effects/utility_effects.yml b/Resources/Prototypes/XenoArch/Effects/utility_effects.yml index c9297d901b..f819946a4d 100644 --- a/Resources/Prototypes/XenoArch/Effects/utility_effects.yml +++ b/Resources/Prototypes/XenoArch/Effects/utility_effects.yml @@ -52,9 +52,7 @@ storagebase: !type:Container ents: [ ] - type: Storage - maxSlots: 5 - maxItemSize: Huge - maxTotalWeight: 40 + capacity: 50 - type: artifactEffect id: EffectPhasing From d6d8fff3cbaea15f1f9fcf61cc932fe40632af6d Mon Sep 17 00:00:00 2001 From: DrSmugleaf Date: Thu, 26 Oct 2023 01:27:12 -0700 Subject: [PATCH 058/102] Add missing changelog for storage refactor revert (#21259) --- Resources/Changelog/Parts/a.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Resources/Changelog/Parts/a.yml diff --git a/Resources/Changelog/Parts/a.yml b/Resources/Changelog/Parts/a.yml new file mode 100644 index 0000000000..2adaac2e51 --- /dev/null +++ b/Resources/Changelog/Parts/a.yml @@ -0,0 +1,4 @@ +author: metalgearsloth +changes: +- type: Tweak + message: Reverted storage to function with numerical values again, instead of slots and sizes. From e96fbaf4e45a1bd6fdb4c34b4585936fb6c7e38e Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 26 Oct 2023 04:28:17 -0400 Subject: [PATCH 059/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 12 ++++++------ Resources/Changelog/Parts/a.yml | 4 ---- 2 files changed, 6 insertions(+), 10 deletions(-) delete mode 100644 Resources/Changelog/Parts/a.yml diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 7f718932bd..8a27f45d7d 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,10 +1,4 @@ Entries: -- author: Cripes - changes: - - {message: 'Paper stamps have been heavily tweaked with new looks, now each paper - will lay out the stamps slightly differently and with an overlap.', type: Tweak} - id: 4563 - time: '2023-08-13T18:28:10.0000000+00:00' - author: PixelTheKermit changes: - {message: Arachnid zombies no longer get functional hands., type: Fix} @@ -2895,3 +2889,9 @@ Entries: - {message: Fixed not being to create pills at the ChemMaster 5000., type: Fix} id: 5062 time: '2023-10-26T02:47:45.0000000+00:00' +- author: metalgearsloth + changes: + - {message: 'Reverted storage to function with numerical values again, instead of + slots and sizes.', type: Tweak} + id: 5063 + time: '2023-10-26T08:28:16.776154+00:00' diff --git a/Resources/Changelog/Parts/a.yml b/Resources/Changelog/Parts/a.yml deleted file mode 100644 index 2adaac2e51..0000000000 --- a/Resources/Changelog/Parts/a.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: metalgearsloth -changes: -- type: Tweak - message: Reverted storage to function with numerical values again, instead of slots and sizes. From 8fcb20894ce8911b3e85581014eb19c0d1d26672 Mon Sep 17 00:00:00 2001 From: chromiumboy <50505512+chromiumboy@users.noreply.github.com> Date: Thu, 26 Oct 2023 09:08:24 -0500 Subject: [PATCH 060/102] BBQ rib sandwich (#21180) --- .../Prototypes/Entities/Objects/Consumable/Food/burger.yml | 4 ++-- Resources/Prototypes/Recipes/Cooking/meal_recipes.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/burger.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/burger.yml index a1d816b32a..9b8411b803 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/burger.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/burger.yml @@ -613,10 +613,10 @@ - Meat - type: entity - name: McRib + name: BBQ Rib Sandwich parent: FoodBurgerBase id: FoodBurgerMcrib - description: An elusive rib shaped burger with limited availablity across the galaxy. Not as good as you remember it. + description: An elusive rib shaped burger with limited availability across the galaxy. Not as good as you remember it. components: - type: FlavorProfile flavors: diff --git a/Resources/Prototypes/Recipes/Cooking/meal_recipes.yml b/Resources/Prototypes/Recipes/Cooking/meal_recipes.yml index d83d58bc92..a9ea6b0876 100644 --- a/Resources/Prototypes/Recipes/Cooking/meal_recipes.yml +++ b/Resources/Prototypes/Recipes/Cooking/meal_recipes.yml @@ -218,7 +218,7 @@ - type: microwaveMealRecipe id: RecipeBurgerMcrib - name: McRib recipe + name: BBQ rib sandwich recipe result: FoodBurgerMcrib time: 10 solids: From 8891890ad1fd8ce91c6196ff1afab66fbe2af655 Mon Sep 17 00:00:00 2001 From: faint <46868845+ficcialfaint@users.noreply.github.com> Date: Thu, 26 Oct 2023 18:19:37 +0300 Subject: [PATCH 061/102] Fix missing toggle fullscreen loc string (#21264) --- Resources/Locale/en-US/escape-menu/ui/options-menu.ftl | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl index 97d1da949b..5540b6609b 100644 --- a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl +++ b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl @@ -148,6 +148,7 @@ ui-options-function-escape-context = Close recent window or toggle game menu ui-options-function-take-screenshot = Take screenshot ui-options-function-take-screenshot-no-ui = Take screenshot (without UI) +ui-options-function-toggle-fullscreen = Toggle fullscreen ui-options-function-editor-place-object = Place object ui-options-function-editor-cancel-place = Cancel placement From 354d999c8e7ddd1cbb43c7368ff5fb31f83a0f8f Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Fri, 27 Oct 2023 04:58:27 +0300 Subject: [PATCH 062/102] Cave Decoration pack (#21265) * add chromite chasm * add desert chasm * snow chasm * finish --- .../Entities/Objects/Decoration/flora.yml | 56 +++++- .../Entities/Objects/Decoration/mining.yml | 179 ++++++++++++++++++ Resources/Prototypes/Entities/Tiles/chasm.yml | 34 +++- .../Flora/flora_stalagmite.rsi/meta.json | 29 +++ .../flora_stalagmite.rsi/stalagmite1.png | Bin 0 -> 714 bytes .../flora_stalagmite.rsi/stalagmite2.png | Bin 0 -> 557 bytes .../flora_stalagmite.rsi/stalagmite3.png | Bin 0 -> 733 bytes .../flora_stalagmite.rsi/stalagmite4.png | Bin 0 -> 695 bytes .../flora_stalagmite.rsi/stalagmite5.png | Bin 0 -> 610 bytes .../flora_stalagmite.rsi/stalagmite6.png | Bin 0 -> 579 bytes .../Objects/Decoration/mines.rsi/meta.json | 29 +++ .../Decoration/mines.rsi/sign_left.png | Bin 0 -> 422 bytes .../Decoration/mines.rsi/sign_right.png | Bin 0 -> 423 bytes .../Objects/Decoration/mines.rsi/support.png | Bin 0 -> 404 bytes .../Decoration/mines.rsi/support_beams.png | Bin 0 -> 364 bytes .../Decoration/mines.rsi/support_wall.png | Bin 0 -> 571 bytes .../mines.rsi/support_wall_broken.png | Bin 0 -> 852 bytes .../basalt_chasm.rsi}/chasm.png | Bin .../basalt_chasm.rsi}/chasm0.png | Bin .../basalt_chasm.rsi}/chasm1.png | Bin .../basalt_chasm.rsi}/chasm2.png | Bin .../basalt_chasm.rsi}/chasm3.png | Bin .../basalt_chasm.rsi}/chasm4.png | Bin .../basalt_chasm.rsi}/chasm5.png | Bin .../basalt_chasm.rsi}/chasm6.png | Bin .../basalt_chasm.rsi}/chasm7.png | Bin .../basalt_chasm.rsi}/full.png | Bin .../basalt_chasm.rsi}/meta.json | 0 .../Chasms/chromite_chasm.rsi/chasm.png | Bin 0 -> 180 bytes .../Chasms/chromite_chasm.rsi/chasm0.png | Bin 0 -> 1402 bytes .../Chasms/chromite_chasm.rsi/chasm1.png | Bin 0 -> 920 bytes .../Chasms/chromite_chasm.rsi/chasm2.png | Bin 0 -> 1402 bytes .../Chasms/chromite_chasm.rsi/chasm3.png | Bin 0 -> 920 bytes .../Chasms/chromite_chasm.rsi/chasm4.png | Bin 0 -> 926 bytes .../Chasms/chromite_chasm.rsi/chasm5.png | Bin 0 -> 478 bytes .../Chasms/chromite_chasm.rsi/chasm6.png | Bin 0 -> 926 bytes .../Chasms/chromite_chasm.rsi/chasm7.png | Bin 0 -> 96 bytes .../Planet/Chasms/chromite_chasm.rsi/full.png | Bin 0 -> 974 bytes .../Chasms/chromite_chasm.rsi/meta.json | 49 +++++ .../Planet/Chasms/desert_chasm.rsi/chasm.png | Bin 0 -> 272 bytes .../Planet/Chasms/desert_chasm.rsi/chasm0.png | Bin 0 -> 2295 bytes .../Planet/Chasms/desert_chasm.rsi/chasm1.png | Bin 0 -> 1298 bytes .../Planet/Chasms/desert_chasm.rsi/chasm2.png | Bin 0 -> 2295 bytes .../Planet/Chasms/desert_chasm.rsi/chasm3.png | Bin 0 -> 1298 bytes .../Planet/Chasms/desert_chasm.rsi/chasm4.png | Bin 0 -> 1464 bytes .../Planet/Chasms/desert_chasm.rsi/chasm5.png | Bin 0 -> 635 bytes .../Planet/Chasms/desert_chasm.rsi/chasm6.png | Bin 0 -> 1464 bytes .../Planet/Chasms/desert_chasm.rsi/chasm7.png | Bin 0 -> 96 bytes .../Planet/Chasms/desert_chasm.rsi/full.png | Bin 0 -> 1951 bytes .../Planet/Chasms/desert_chasm.rsi/meta.json | 49 +++++ .../Planet/Chasms/snow_chasm.rsi/chasm.png | Bin 0 -> 183 bytes .../Planet/Chasms/snow_chasm.rsi/chasm0.png | Bin 0 -> 1574 bytes .../Planet/Chasms/snow_chasm.rsi/chasm1.png | Bin 0 -> 904 bytes .../Planet/Chasms/snow_chasm.rsi/chasm2.png | Bin 0 -> 1574 bytes .../Planet/Chasms/snow_chasm.rsi/chasm3.png | Bin 0 -> 904 bytes .../Planet/Chasms/snow_chasm.rsi/chasm4.png | Bin 0 -> 806 bytes .../Planet/Chasms/snow_chasm.rsi/chasm5.png | Bin 0 -> 489 bytes .../Planet/Chasms/snow_chasm.rsi/chasm6.png | Bin 0 -> 806 bytes .../Planet/Chasms/snow_chasm.rsi/chasm7.png | Bin 0 -> 96 bytes .../Planet/Chasms/snow_chasm.rsi/full.png | Bin 0 -> 1225 bytes .../Planet/Chasms/snow_chasm.rsi/meta.json | 49 +++++ 61 files changed, 471 insertions(+), 3 deletions(-) create mode 100644 Resources/Prototypes/Entities/Objects/Decoration/mining.yml create mode 100644 Resources/Textures/Objects/Decoration/Flora/flora_stalagmite.rsi/meta.json create mode 100644 Resources/Textures/Objects/Decoration/Flora/flora_stalagmite.rsi/stalagmite1.png create mode 100644 Resources/Textures/Objects/Decoration/Flora/flora_stalagmite.rsi/stalagmite2.png create mode 100644 Resources/Textures/Objects/Decoration/Flora/flora_stalagmite.rsi/stalagmite3.png create mode 100644 Resources/Textures/Objects/Decoration/Flora/flora_stalagmite.rsi/stalagmite4.png create mode 100644 Resources/Textures/Objects/Decoration/Flora/flora_stalagmite.rsi/stalagmite5.png create mode 100644 Resources/Textures/Objects/Decoration/Flora/flora_stalagmite.rsi/stalagmite6.png create mode 100644 Resources/Textures/Objects/Decoration/mines.rsi/meta.json create mode 100644 Resources/Textures/Objects/Decoration/mines.rsi/sign_left.png create mode 100644 Resources/Textures/Objects/Decoration/mines.rsi/sign_right.png create mode 100644 Resources/Textures/Objects/Decoration/mines.rsi/support.png create mode 100644 Resources/Textures/Objects/Decoration/mines.rsi/support_beams.png create mode 100644 Resources/Textures/Objects/Decoration/mines.rsi/support_wall.png create mode 100644 Resources/Textures/Objects/Decoration/mines.rsi/support_wall_broken.png rename Resources/Textures/Tiles/Planet/{chasm.rsi => Chasms/basalt_chasm.rsi}/chasm.png (100%) rename Resources/Textures/Tiles/Planet/{chasm.rsi => Chasms/basalt_chasm.rsi}/chasm0.png (100%) rename Resources/Textures/Tiles/Planet/{chasm.rsi => Chasms/basalt_chasm.rsi}/chasm1.png (100%) rename Resources/Textures/Tiles/Planet/{chasm.rsi => Chasms/basalt_chasm.rsi}/chasm2.png (100%) rename Resources/Textures/Tiles/Planet/{chasm.rsi => Chasms/basalt_chasm.rsi}/chasm3.png (100%) rename Resources/Textures/Tiles/Planet/{chasm.rsi => Chasms/basalt_chasm.rsi}/chasm4.png (100%) rename Resources/Textures/Tiles/Planet/{chasm.rsi => Chasms/basalt_chasm.rsi}/chasm5.png (100%) rename Resources/Textures/Tiles/Planet/{chasm.rsi => Chasms/basalt_chasm.rsi}/chasm6.png (100%) rename Resources/Textures/Tiles/Planet/{chasm.rsi => Chasms/basalt_chasm.rsi}/chasm7.png (100%) rename Resources/Textures/Tiles/Planet/{chasm.rsi => Chasms/basalt_chasm.rsi}/full.png (100%) rename Resources/Textures/Tiles/Planet/{chasm.rsi => Chasms/basalt_chasm.rsi}/meta.json (100%) create mode 100644 Resources/Textures/Tiles/Planet/Chasms/chromite_chasm.rsi/chasm.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/chromite_chasm.rsi/chasm0.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/chromite_chasm.rsi/chasm1.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/chromite_chasm.rsi/chasm2.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/chromite_chasm.rsi/chasm3.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/chromite_chasm.rsi/chasm4.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/chromite_chasm.rsi/chasm5.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/chromite_chasm.rsi/chasm6.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/chromite_chasm.rsi/chasm7.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/chromite_chasm.rsi/full.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/chromite_chasm.rsi/meta.json create mode 100644 Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/chasm.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/chasm0.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/chasm1.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/chasm2.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/chasm3.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/chasm4.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/chasm5.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/chasm6.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/chasm7.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/full.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/meta.json create mode 100644 Resources/Textures/Tiles/Planet/Chasms/snow_chasm.rsi/chasm.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/snow_chasm.rsi/chasm0.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/snow_chasm.rsi/chasm1.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/snow_chasm.rsi/chasm2.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/snow_chasm.rsi/chasm3.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/snow_chasm.rsi/chasm4.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/snow_chasm.rsi/chasm5.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/snow_chasm.rsi/chasm6.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/snow_chasm.rsi/chasm7.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/snow_chasm.rsi/full.png create mode 100644 Resources/Textures/Tiles/Planet/Chasms/snow_chasm.rsi/meta.json diff --git a/Resources/Prototypes/Entities/Objects/Decoration/flora.yml b/Resources/Prototypes/Entities/Objects/Decoration/flora.yml index 374a9a272c..8c6a87b563 100644 --- a/Resources/Prototypes/Entities/Objects/Decoration/flora.yml +++ b/Resources/Prototypes/Entities/Objects/Decoration/flora.yml @@ -170,6 +170,60 @@ - type: Sprite state: rocksolid03 +- type: entity + parent: BaseRock + id: FloraStalagmite1 + name: rock + components: + - type: Sprite + sprite: Objects/Decoration/Flora/flora_stalagmite.rsi + state: stalagmite1 + +- type: entity + parent: BaseRock + id: FloraStalagmite2 + name: rock + components: + - type: Sprite + sprite: Objects/Decoration/Flora/flora_stalagmite.rsi + state: stalagmite2 + +- type: entity + parent: BaseRock + id: FloraStalagmite3 + name: rock + components: + - type: Sprite + sprite: Objects/Decoration/Flora/flora_stalagmite.rsi + state: stalagmite3 + +- type: entity + parent: BaseRock + id: FloraStalagmite4 + name: rock + components: + - type: Sprite + sprite: Objects/Decoration/Flora/flora_stalagmite.rsi + state: stalagmite4 + +- type: entity + parent: BaseRock + id: FloraStalagmite5 + name: rock + components: + - type: Sprite + sprite: Objects/Decoration/Flora/flora_stalagmite.rsi + state: stalagmite5 + +- type: entity + parent: BaseRock + id: FloraStalagmite6 + name: rock + components: + - type: Sprite + sprite: Objects/Decoration/Flora/flora_stalagmite.rsi + state: stalagmite6 + - type: entity parent: BaseTree id: FloraTree01 @@ -440,4 +494,4 @@ name: tree components: - type: Sprite - state: tree06 \ No newline at end of file + state: tree06 diff --git a/Resources/Prototypes/Entities/Objects/Decoration/mining.yml b/Resources/Prototypes/Entities/Objects/Decoration/mining.yml new file mode 100644 index 0000000000..fb5afcd3f5 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Decoration/mining.yml @@ -0,0 +1,179 @@ +- type: entity + id: WoodenSign + name: wooden sign + description: He's pointing somewhere. + components: + - type: Clickable + - type: InteractionOutline + - type: Sprite + sprite: Objects/Decoration/mines.rsi + state: sign_left + - type: Physics + bodyType: Static + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.35,-0.4,0.35,0.4" + density: 100 + - type: Damageable + damageContainer: Inorganic + damageModifierSet: Wood + - type: MeleeSound + soundGroups: + Brute: + path: /Audio/Effects/chop.ogg + params: + variation: 0.05 + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:SpawnEntitiesBehavior + spawn: + Log: + min: 1 + max: 1 + +- type: entity + parent: WoodenSign + id: WoodenSignRight + components: + - type: Sprite + sprite: Objects/Decoration/mines.rsi + state: sign_right + +- type: entity + id: WoodenSupport + parent: BaseStructure + name: wooden support + description: Increases your confidence that a rock won't fall on your head. + placement: + mode: SnapgridCenter + components: + - type: Sprite + sprite: Objects/Decoration/mines.rsi + state: support + - type: Damageable + damageContainer: Inorganic + damageModifierSet: Wood + - type: Physics + bodyType: Static + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.1,-0.5,0.1,0.5" + mask: + - FullTileMask + layer: + - WallLayer + density: 1000 + - type: MeleeSound + soundGroups: + Brute: + path: /Audio/Effects/chop.ogg + params: + variation: 0.05 + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 150 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:SpawnEntitiesBehavior + spawn: + Log: + min: 1 + max: 3 + +- type: entity + id: WoodenSupportBeam + name: wooden support beam + parent: WoodenSupport + components: + - type: Sprite + sprite: Objects/Decoration/mines.rsi + state: support_beams + - type: Fixtures + fixtures: + fix1: + hard: false + shape: + !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.5,0.5" + mask: + - FullTileMask + layer: + - WallLayer + density: 1000 + +- type: entity + id: WoodenSupportWall + parent: BaseStructure + name: wooden support wall + description: An old, rotten wall. + placement: + mode: SnapgridCenter + components: + - type: Sprite + sprite: Objects/Decoration/mines.rsi + state: support_wall + - type: Damageable + damageContainer: Inorganic + damageModifierSet: Wood + - type: Physics + bodyType: Static + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.5,0.5" + mask: + - FullTileMask + layer: + - WallLayer + density: 1000 + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 250 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:SpawnEntitiesBehavior + spawn: + Log: + min: 2 + max: 5 + +- type: entity + id: WoodenSupportWallBroken + parent: WoodenSupportWall + components: + - type: Sprite + sprite: Objects/Decoration/mines.rsi + state: support_wall_broken + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 150 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:SpawnEntitiesBehavior + spawn: + Log: + min: 1 + max: 3 \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Tiles/chasm.yml b/Resources/Prototypes/Entities/Tiles/chasm.yml index 2347532587..23f3ad8395 100644 --- a/Resources/Prototypes/Entities/Tiles/chasm.yml +++ b/Resources/Prototypes/Entities/Tiles/chasm.yml @@ -18,12 +18,12 @@ anchored: true - type: Clickable - type: Sprite - sprite: Tiles/Planet/chasm.rsi + sprite: Tiles/Planet/Chasms/basalt_chasm.rsi drawdepth: BelowFloor layers: - state: chasm - type: Icon - sprite: Tiles/Planet/chasm.rsi + sprite: Tiles/Planet/Chasms/basalt_chasm.rsi state: full - type: IconSmooth key: chasm @@ -45,3 +45,33 @@ - type: Tag tags: - HideContextMenu + +- type: entity + parent: FloorChasmEntity + id: FloorChromiteChasm + suffix: Chromite + components: + - type: Sprite + sprite: Tiles/Planet/Chasms/chromite_chasm.rsi + - type: Icon + sprite: Tiles/Planet/Chasms/chromite_chasm.rsi + +- type: entity + parent: FloorChasmEntity + id: FloorDesertChasm + suffix: Desert + components: + - type: Sprite + sprite: Tiles/Planet/Chasms/desert_chasm.rsi + - type: Icon + sprite: Tiles/Planet/Chasms/desert_chasm.rsi + +- type: entity + parent: FloorChasmEntity + id: FloorSnowChasm + suffix: Snow + components: + - type: Sprite + sprite: Tiles/Planet/Chasms/snow_chasm.rsi + - type: Icon + sprite: Tiles/Planet/Chasms/snow_chasm.rsi \ No newline at end of file diff --git a/Resources/Textures/Objects/Decoration/Flora/flora_stalagmite.rsi/meta.json b/Resources/Textures/Objects/Decoration/Flora/flora_stalagmite.rsi/meta.json new file mode 100644 index 0000000000..33dc4fa073 --- /dev/null +++ b/Resources/Textures/Objects/Decoration/Flora/flora_stalagmite.rsi/meta.json @@ -0,0 +1,29 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from TGMC at commit https://github.com/tgstation/TerraGov-Marine-Corps/commit/4bf5d1aafbcbbb7bd2a7d0f52ef87f28e2bbb384", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "stalagmite1" + }, + { + "name": "stalagmite2" + }, + { + "name": "stalagmite3" + }, + { + "name": "stalagmite4" + }, + { + "name": "stalagmite5" + }, + { + "name": "stalagmite6" + } + ] +} diff --git a/Resources/Textures/Objects/Decoration/Flora/flora_stalagmite.rsi/stalagmite1.png b/Resources/Textures/Objects/Decoration/Flora/flora_stalagmite.rsi/stalagmite1.png new file mode 100644 index 0000000000000000000000000000000000000000..ed9ddfd8abbb2528608aa6441247d98c2164c2d7 GIT binary patch literal 714 zcmV;*0yX`KP)RCt`lmc32_K@^3DC=1H2@?%1@kiw_3F(wq6m}nst4Y9G( zLK71$NQ{lI!K>J4BNAZ|Su|_T;$82KGrJ>^>`llnFmvadbI<%Nb~+uAW-OXEJZtRv zjkB9fY5?;JV}R;v z3Z>}23?lzsHV^#6)2ql}PtSc}8pb7Xy$|8_M}ZFp?kM~ZP~;21kYD}{0P<4|C!gUv zm4WXMh3tYhk4h;c0A0B6lkgqO^Yp0h+l9Qa6m0>!SuHB_XaUfvQg(t_L4E|y5M=-W zmK--H0%g+e7pf&3s{jTh10t~;e_e8_hy~z-F(N|R(B>++Px^AQllnBv%eG^rt3?=7~s!7Rv zgjNAET#!(zzc=|%CRa@aGTr{{!{-lWOqf|idAb%f^C&BC-FBt}HWfiml zTrvzw^`oZ@fC2Z$SYt6T74x|N$Bj$rsVmP1ITn>W3r?R>n{3hQcB0XUY7)0e@ zymJWdX6_lN0x&wZ(Jt=t@(W!)EO5Kw3Xp^}GXmlJ0Noej2G#<|L02mrw;U2m5eSFI wN>bH+W&n!jMLRMZ-Obo!)-wUjD^dse0x~>jWzmT`n*aa+07*qoM6N<$f>V|-GXMYp literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Decoration/Flora/flora_stalagmite.rsi/stalagmite2.png b/Resources/Textures/Objects/Decoration/Flora/flora_stalagmite.rsi/stalagmite2.png new file mode 100644 index 0000000000000000000000000000000000000000..e8167762612ca6556da02e8340ee882a1eaaf1f2 GIT binary patch literal 557 zcmV+|0@D47P)oZP4!>$n&T+Fqit+VcuTo*_ulXQ-@EITY};l)vM(h6;uu=WdP9`*_FcAInWk#(g}V?D>6n-4Yib~dEGl@&lR%7(H>aQe@ie6xW&49mc) zfN^GkI4Az^-iQ1I;R|O0$^j^VCY3=608R*mj;M!lL`dJ?|Ii7O`i(eQ3(J6#QKWOCH91- z&7KFaxGP&C03A9s2E=Q(AN%R$ft-)eC}Y_@QK|rC!7CstB4)biT`B{d3({PX%I5~X#!CTNwO7QB*qvZAbQ%&05YN(r_vVeLp zzC^ITIwolD02ZAd(|e7n1rRNUi{fidNEyyP_ElKBt%jrD^A`Xx+$3zY>Z;ct%uc|`!OP_7 z;jy!xL@YiKQH*_j;3Z&Eq!8fv{>6BtlmkJ7$j=AfCCEo321MMj7wPdJs%dh3pi)Cd zsV6E6INpDeP*WRXK%o0ReV=zeBJBNPY5_vdVm64hnf}rRG6r!v))`PL^FX1Bf7%Z9^noAsdf)fH}Ogv%%O^2B(0aHrYh7D-z+?;jb*! z{FmJiGUvUdq|+l{XOIc~-6E+7J-`Hiep z09S2pJQ-0+-uwPT)x(u+PUZt6!Y*0946d7UVFvQ|eRi}=kTD#9NXVt{?T9O#1va)f z*E4b%lU_SgyXHP0EH}OpP3nyQ_GKhQcmq%Dzd4zjcq##TA+x~3zmER^dk$?gAvotc P00000NkvXXu0mjfKAKS0 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Decoration/Flora/flora_stalagmite.rsi/stalagmite4.png b/Resources/Textures/Objects/Decoration/Flora/flora_stalagmite.rsi/stalagmite4.png new file mode 100644 index 0000000000000000000000000000000000000000..90e0e75a07f4cadaeecc9a07d152c611def74f96 GIT binary patch literal 695 zcmV;o0!aOdP)6l7a`zi~F(zJ2O!VN*i}B*k zgC-_kNQ@W12A{$^nwStpP+OIPseQ$PVQsftz!($X#afn`-@KXKmSnYB6~C$EPXw(T z?6}vpdvSbmm6#a7>HfC6b99yv8Y(Pgh427$qz#ZSnqqHb&DE(Yj6PFJjya#}6Z0!Yox1m5R!0ho+26K&YMzwy%~KhX&5fO!r#_ zP(bJmZR{aL8?3v>Z*yVU@BU1X03oE7#RkBaG0hMLi>xg#7l!7d<^dJwXZT74N(kEj3u002ovPDHLkV1ly@HfsO? literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Decoration/Flora/flora_stalagmite.rsi/stalagmite5.png b/Resources/Textures/Objects/Decoration/Flora/flora_stalagmite.rsi/stalagmite5.png new file mode 100644 index 0000000000000000000000000000000000000000..a10cdb5d9b9ed3928573eef898bab2d329f47bc0 GIT binary patch literal 610 zcmV-o0-gPdP)LJ+j6O)ZirHFU(!FyE_3#zFAjJ7dxdGB~4ip7Wj$M|VD-XLfa- z+3oISFI+0$bu$MPiRtWkXR~{9c`FU!2!O7+nbBw~eb*5HJNo|ssC{~EiRnJiYycpm z)nP&1&knXWy1AQssYbL7kc@}zAe=o(Qv#0fdZ%0q$}~-G|3F zX3Y%NYph=ejG|F%Ob1|`Qj1YOe&wQ}d=F&+)Oj_vz{d{`0D_uOW*-OvAXs`m$ul

ZI6-PQ+ro_~1b~cCV{3h@Mx8|}US>x^09ZC8uh+v}Ae+&IB$S}l?(olu zKA=nlKroD&IneS-g1tN!`aw$75kLqf0H8=2gdCtPhZ|dikyN&zFaX^g8OH|aU^8BT zqU*4qu8|A20q~$<7InKG@UddgegrcIw`x)ul=c87g0e=Y<3uh@(nNs6(<>Jm(RvTJ%Kf;%z=<^WHxpL`>ds0YlTGLizItX|(s w{D|z#uBb=~V4R(qvumY4rAh$P(98jT0m%{iXN36K-T(jq07*qoM6N<$g5`4nyZ`_I literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Decoration/Flora/flora_stalagmite.rsi/stalagmite6.png b/Resources/Textures/Objects/Decoration/Flora/flora_stalagmite.rsi/stalagmite6.png new file mode 100644 index 0000000000000000000000000000000000000000..b424d6dfe0c1c0e23ed1b8bae86f6f2652af67e9 GIT binary patch literal 579 zcmV-J0=)f+P)?K@^2Y%%3C?lOUo+(r6h|(?j#<;%Y8509^$Jkc`f&ljd3QI`X7L^gIzPf zvNSRW`=L}KI(-0&^#;)T#_C`WV1D}`kRCAV?LiN`x4PC`skmbKc2#ub4xw)bMOh$lCEJCI4nRjc=9)f+&VTY4C8YoFvr}A5X;0Qoch2K zAeT*BzvJ$kYT%em8%16G8q)zPmpn2 zlk;Bw6EkKq7 zK7aYmz{|smAx1X`>^O3Y!AMOWMeN+IhYTsSb^xxp$0tuHT@dYn$+hYKRTbpHL60pB zC@aZeh!GPl1RVgfSWHxmfs<2^;rsXZ46k1O!cfD@%f|5e^Dj6J6FYeJHo<7Y>wuM$ zYX5^Qe)akln2*g8m^iXy(8b7h!0H`G8I)zj8DzxyPz;CB$N<@55F48sk{z&S+dgmt z3h{CRCoX$qRjlfeEu(4(;Bp8EfI@~EfTU~)a|kHA@pEx7eEjx<0YrlUs2qUF)64;unFC+|Iako#0n`WuibDVdC~*kc4uIu%N&&?oK&eA0a=??9pTOA=MAOv)cb~jO zX%E240=hW>1VDulHa1-x04jz-p@1$%HwTc@`lYG^s0l_LFzSF&2Mo9a0G+OWIR%an Q!2kdN07*qoM6N<$f=DcEkKq7 zK7aYmz{|smAx1X`>^O3Y!AMOWMeN+IhYTsSZ~(6O#;2B)v_Q}SstWQL!Hq2qC@aZ; zX;4&5u1)`++dPvfM-X%XD7fv7RT(~i{srdq^0I;1Fd7|z#5p+y8CFiJ{r~FqD+WRi zAu0{PEW{;-?l=a9_YB{^Gr%1Zp4W`i5kxrv*&+}d-S^0jLuTK8@Q~r|la~zPdAQ9c zDFkp?gbog#y$z<%AV7&j$aVm>!ila9pq4`@a=??9pTOA=MAOv)ph5?^ zJ%C&m(8U2DfLt;XDkZ7z0A(3*l%f|VMmGnL)B2^V1E>i`9Wd&EQ3njT0|1t7jG@n< R{cHdL002ovPDHLkV1norrz8LX literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Decoration/mines.rsi/support.png b/Resources/Textures/Objects/Decoration/mines.rsi/support.png new file mode 100644 index 0000000000000000000000000000000000000000..29f7482b2868daf33dc53bd4a5a85622ed6aa436 GIT binary patch literal 404 zcmV;F0c-w=P)QXc@@ z!_l!Us%})I|Eb1)1(+|EZ~L_0>sl~?bpauds2i1%9afqhAX?4pt9-iNUUku)62J)v z5M&r%7>9E)zchwmRL)%iI6=U8r`@po0fNX-Kgw>Ly9VGPD4%=;NN&UK3qXVroukdG zbI$+-A-k}=I`;)2)3h@9HwFCc|BEm&fH3qM y0Er#Nxc~oaAV~Oq1BkER*a7hT!oyQ+^P?x4o19oyf!w(O0000<}`Dwl-p$UKgzP!9ND$6ojuNGet*lc$#3V=^v=}tPI5)z-j zqJ}99QG%T)49Q`a5KK&mOBa=scA5A;}0000< KMNUMnLSTX&|CC_> literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Decoration/mines.rsi/support_wall.png b/Resources/Textures/Objects/Decoration/mines.rsi/support_wall.png new file mode 100644 index 0000000000000000000000000000000000000000..9b14590952a23fc1b830cf42f1f4d97f9b5956c4 GIT binary patch literal 571 zcmV-B0>u4^P)>0%UU06CCXC%iyFlYF2;fP=U4SA|R?8)!tnnN;mN=YA zXnP86Vm^r}hKs{-P666s;mZY_pNm!xBZ5yCm~!b~T)?-+T8jI-o29002ov JPDHLkV1gr|`-}hp literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Decoration/mines.rsi/support_wall_broken.png b/Resources/Textures/Objects/Decoration/mines.rsi/support_wall_broken.png new file mode 100644 index 0000000000000000000000000000000000000000..4032c6e45cf763e1a07ec62648aad5e9c568fd9d GIT binary patch literal 852 zcmV-a1FQUrP)zVT_ZLdF7}SF45; zbUJ&diYAU&-~>iL4u-R}OKWH5qQbBMbL>GMy7UyX4s36K+2IJlD9VWD+^LncW~s*T z*B?JC>s&4p0Q(tDb|3X4N}NcbzpJ#=9L-6Fs1&dmLzY3YODcU zfC5FwCKSVvq7rW3f0EdML5dLneD_2()yRO9(6g&2mM7oSDrbi07F31@#I)E|3 z4xH_v z_y{oI&jJkR6a!5~_O~v=NDyVYXvB!^f2Go`y=IJ=Gtb z@jgm)SSE63hehKg)J9q@I^%Ugkz5mU9acwz@*d=jpAGfuu&E5$E%Nq0`)S2&X34=azHQBi^N}L6cmmzge(h|4e}oy zI5rra1<3heYXsEq2-&G8#Zd}StjkK16Bb^swu?M-uq>3X2ZT}H1 e$&te7;_?T0CMoetaI+5p0000!lvI6;>1s;*b3=Dh+L6~vJ#O${~K~GN?$B+p3x91GG7!-J%FNVzN`fk5+ae$yz z$Li*0d+*DtHpSlqj%A%zJNn}0yP~{x_4oBE=Yxzx20vsKd`%v4#kPdp{Rk5GboFyt I=akR{0HEwN_5c6? literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Chasms/chromite_chasm.rsi/chasm0.png b/Resources/Textures/Tiles/Planet/Chasms/chromite_chasm.rsi/chasm0.png new file mode 100644 index 0000000000000000000000000000000000000000..18b35146730eb67854850f76e7176fa9498e8114 GIT binary patch literal 1402 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Chasms/chromite_chasm.rsi/full.png b/Resources/Textures/Tiles/Planet/Chasms/chromite_chasm.rsi/full.png new file mode 100644 index 0000000000000000000000000000000000000000..59b9454af0b4a23dbd24489e1549d251c8766554 GIT binary patch literal 974 zcmV;<12O!GP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!2kdb!2!6DYwZ9417k@i?xSsJOaP5`E~kpXQ-3kB}@(FZbUyM-|D$qs_<7nZCzW z&XM!kud5l(`sw4R_cJ1@vBiwNyT7^H`uaX&(f0z4t+C?dc( z!HmewHvtBm92|aHs;&z{UZY=y2qU`IM35Q_ngCF#)FMw7pr*b@6;sCwmuM}8hgi{N zOM|JV8j!~*spk+@5eB^ou%4ev98P^Z2l8!F2-0mU0?tN+S0QVvuR6v_TssG%5@KXa za&q04yhlF4)K@t5^PMNJ&PK&Wh_oducLhSVm0)_bB1GQQoEszlU*v$Czg51L2aywR z`|`8NTz_=l1vPTpoUJBETV6&vw~_l~BEkaubr+<#fzQ6Mao*@ZqNu)&kV>BPBh7Z_ zj%i;3Wi>rLzMP+soZWOw@`*u9^JQ%zH?9TWZbKq0&_*JXo!f{=;URPpIhL(eln|e- z2@~07*qoM6N<$f&uWxDF6Tf literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Chasms/chromite_chasm.rsi/meta.json b/Resources/Textures/Tiles/Planet/Chasms/chromite_chasm.rsi/meta.json new file mode 100644 index 0000000000..e303031e1f --- /dev/null +++ b/Resources/Textures/Tiles/Planet/Chasms/chromite_chasm.rsi/meta.json @@ -0,0 +1,49 @@ +{ + "version": 1, + "license": "CC0-1.0", + "copyright": "Created by TheShuEd (github) for ss14", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "full" + }, + { + "name": "chasm0", + "directions": 4 + }, + { + "name": "chasm1", + "directions": 4 + }, + { + "name": "chasm2", + "directions": 4 + }, + { + "name": "chasm3", + "directions": 4 + }, + { + "name": "chasm4", + "directions": 4 + }, + { + "name": "chasm5", + "directions": 4 + }, + { + "name": "chasm6", + "directions": 4 + }, + { + "name": "chasm7", + "directions": 4 + }, + { + "name": "chasm" + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/chasm.png b/Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/chasm.png new file mode 100644 index 0000000000000000000000000000000000000000..e09eb93e426d83343fec43d7a84d0ccb6ee4ee0c GIT binary patch literal 272 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=Dh+L6~vJ#O${~!KI!qjv*25Z>JvQYB1n&Uaio<^Z&oIEr*;) z>LCH_+h<#?Yk-tJ(Jm za2IqhWQ!Ebh&N*q3E0!oPx-u}MThRCt`-n@fmfR~g5D=W)-yx87Y{-8180d>e7;HiFErtE#K+t-8;1&v8+9C&uU`sn?MIrs*n* ze|`V&f6n>peBTx98MprSvd{CJAP7j38S}FVT1%|0X{<$QO%%n1QJZ$Bi}x^@jL}Nc zG?uSF{8O#sh~pS3h9vVDMNwi*z+#b7RTUy#;9WytB1WSlTw_@- z7i;s&4aBe(=JPq$TCBB{Wks5%6h(m$5+Nk*b_ZKqyt7Ovr=;nO$@qk_tS}~8n}6>D z0MvDj)|$!bJ18j#qX;QAb!|!03@HU#Yie6FpG~RCj3hZD%d@q)_r3%IEion_O;ds( zq_Gy)Sn9eWFowg?h%#SrcyyJx)gsTbi@%$|-UYCBmHj9R>Gt|87b!+bl6gWD8kUPW zmo7iR3(vgBG|3qDT1=D81P}Lt09943HaV%lH3UJ35T2t;$Fy2~0Ipwqo?)*Az%qWkH@T84eH8L5QJs5%_zv{?@HC07kv_H$b=#1ZcOrESD*vQDlob zCntCK)YZ>&{o3;Y|6%v@%-_77ikr97jqvaN6sWBwFd>a|n5a#j*Tk*XMdr`(-rzUM zzjpzwwFsf;_Xl*_9lr3zFY)Y??`Hqp^4r4Rmw=!lj=SI?h+?8B=I^&A9FJmPmGMz8 z@&Mzc*f{^*9WXwzX{vsjBkcAJ{Us>VOBYbUnb!ulx*aE#s57De?^OJwi&vUibeMw!Q>j|I4p9 zn@%b61R*50u~c=5RFbl+woQLeY*m0iz49by(<#>0bUJ-Z)IzBM5NNsg8VuOt9`NRk z=e)I+G@a2{OBjv_O$*VNxW?jKL!i~R=sz^JBEWg@f`%{*X{2PaSP(}s#u%J$D2sw5 znQepqBVla;-n{Xg@Ai5Z|EEcUwU)+KlvPO-MU+KB6ljt(!5G8wr7NUqinVrK`n9pP z0F&`MIA?JV4u(Ujsw9d+l46PXp0X_I4+dCU6GqVM9Z(h(S{n|JE^i`+wXpV1q?G1t zI!4J=oj({1S!OxjdqNW;gupfpS_f!l2y{T>9D~7t9sCx%C)Rd=_kyNr$g-6Ae8%M~ zS2-Mx@HozPzrZ@J)}}JO+#H*q{)n;$j~|Ut$EOWAKf$$zF1x1k|1+-c%obz{5O9C=Z3AH=`D0Ox_f7w4|{(c@2XbbOiP%by`zCZzKzdA`8fntrd3bNgQcTe+1O zC&k4m%a0y^ii6>h2R`>zs((9SKA%w6B|#8ugZ?97D+0W~m-q8)&!V;F>ZiXpRIxrX$?vnlkvG*H^H*Y-a=d&42V+q3m=N#Yo*3&!tUVHCO%+980 zEms$)m1WmC*}DK*YZi+I#%Pq1IOloj!K0m(hKLSIKn$<;u@_F`14DTdgmIx{mAb(UL@?@0Y#n@ zXoa;7Ar(?-oO4uFi4=mmwwN$R>5$j|@R)z?rAIgFh`pD>H(vd*UoKYjLqaOzR)@IN zMhb!Vj=Cx-%N(f!!qAXs8Ff{nl%%Q~9{$d6){0^84j3GaI2azSZiu}@3cuQG}maEAUAtZ6sA}|5oHPltkd^W)Zip6rt;o%7Hq19?51REK){ufj{DT@jC Rs!jj^002ovPDHLkV1hPzSn>b> literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/chasm1.png b/Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/chasm1.png new file mode 100644 index 0000000000000000000000000000000000000000..dce7efd9a639c63eb82a9dd450aa5327c811f0b8 GIT binary patch literal 1298 zcmV+t1?~EYP)Px(%t=H+RCt{2n>~-zRuqOG`(A&{_l%icfk+t%r43CaQc>q$q)AI?5JE~3gpd+J zn==1^G->IOQjv~8vr-}j!ZIKBcxL={?VAE7VmFHr@!-1=^Hi2?`Sp2y?j8G_I~ImH z`1MDfBngh=uvmmd^C?o=C{<7@g^&{8Z{hhJI^7;x!*n`93Y)T2eE!8ZRvmr0tw8=O zRaN1-ER>zrHe9-}r;i79>B64gZ10a-TS@ujoQe#9H>dJu|MAq{7N^F5x3QTR zx6P?G;PtHdpfh0Gl5NO`CnwfjvYI8?AWnm$BrF4c5Iv4pP3Ku-_Zd5!Qh{L zA7A|Pjn{p6|Bl|AyNDt_z5KP&Pu<#mf$8KaqhO!ebjm0Qm`+|C3Gz6r)soe6MWr>i z5Ow8iQ`-O`B=gyXAQ)2=Im2PVbT%Q5LmcU#N`>orNFgYSlEGj|n&pf}BcdqUMhvy6 zZGhGmWm&Rb$3#)c*>mSP6O7SR#ES^avakT#mW+ZS>ve+Xd1P5eyWM{4_1`zO3nIOK zA6p2@vZN?-;zdZBu94EgZ?(yb0wE+>mXfU3SeEsw5t?CH<||!|-ob;Pztw}m5Gh?8 z*Ch-?E?&N3)P+V%Vvgf5pG}$1XDFqps;Wu(6KS+NoTeGAmX8pUJj>{Ap}Sj`Mh$RX zhh)75Ti|;Y9nou2{zMub0_}F2s?u~j9SW5*ojh++{zRIc16-d`5D>=;bX5ZHrPTjU zG-|;0tG95y7XAK^UawED*Kbn(L>h05EEf@FS&^hUr{G7RSpyy&%t?|ZN)-(H1FGr+ z8v+1>VL%j3DT?gXYA~}HStTYcc>3q>_fG5vl%k^4lt*J^ymaUtVKM^zC zVavw0ZL;+JEP8ks8a3dzUw+Wxd_u23q(2y8S?0U*jn4tL{qpIfHNkkVY59NAxB)^q zC{-XG7op9+2pF$OJiPzCj>3?#RCu1lc>g?~eD+mi_hoz#hVvOx+GwrGa@DxLaRa23 zESF1MS0Y67w`1IZ;phy$?~~^_j%@zD%=rHW(lo>M+E`YKblk@Ejb}g@PH43}di?>; zhiCx058_@1_DT;!{V$OOM^V7ZW8r3&$z;HBX6zrijEEi$p`o>>`Ds2-4 z`y^>frOU?kjT>ND7SeTTclxiICCy@d2nZp_vX?7MOjL;e2GwB%d2_tXA^-pY07*qo IM6N<$f+ezY%m4rY literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/chasm2.png b/Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/chasm2.png new file mode 100644 index 0000000000000000000000000000000000000000..7139091f1e1a6d15a27fec32cbe379530d7709b7 GIT binary patch literal 2295 zcmVPx-u}MThRCt`-n@fmfR~g5D=W)-yx87Y{-8180d>e7;HiFErtE#K+t-8;1&v8+9C&uU`sn?MIrs*n* ze|`V&f6n>peBTx98MprSvd{CJAP7j38S}FVT1%|0X{<$QO%%n1QJZ$Bi}x^@jL}Nc zG?uSF{8O#sh~pS3h9vVDMNwi*z+#b7RTUy#;9WytB1WSlTw_@- z7i;s&4aBe(=JPq$TCBB{Wks5%6h(m$5+Nk*b_ZKqyt7Ovr=;nO$@qk_tS}~8n}6>D z0MvDj)|$!bJ18j#qX;QAb!|!03@HU#Yie6FpG~RCj3hZD%d@q)_r3%IEion_O;ds( zq_Gy)Sn9eWFowg?h%#SrcyyJx)gsTbi@%$|-UYCBmHj9R>Gt|87b!+bl6gWD8kUPW zmo7iR3(vgBG|3qDT1=D81P}Lt09943HaV%lH3UJ35T2t;$Fy2~0Ipwqo?)*Az%qWkH@T84eH8L5QJs5%_zv{?@HC07kv_H$b=#1ZcOrESD*vQDlob zCntCK)YZ>&{o3;Y|6%v@%-_77ikr97jqvaN6sWBwFd>a|n5a#j*Tk*XMdr`(-rzUM zzjpzwwFsf;_Xl*_9lr3zFY)Y??`Hqp^4r4Rmw=!lj=SI?h+?8B=I^&A9FJmPmGMz8 z@&Mzc*f{^*9WXwzX{vsjBkcAJ{Us>VOBYbUnb!ulx*aE#s57De?^OJwi&vUibeMw!Q>j|I4p9 zn@%b61R*50u~c=5RFbl+woQLeY*m0iz49by(<#>0bUJ-Z)IzBM5NNsg8VuOt9`NRk z=e)I+G@a2{OBjv_O$*VNxW?jKL!i~R=sz^JBEWg@f`%{*X{2PaSP(}s#u%J$D2sw5 znQepqBVla;-n{Xg@Ai5Z|EEcUwU)+KlvPO-MU+KB6ljt(!5G8wr7NUqinVrK`n9pP z0F&`MIA?JV4u(Ujsw9d+l46PXp0X_I4+dCU6GqVM9Z(h(S{n|JE^i`+wXpV1q?G1t zI!4J=oj({1S!OxjdqNW;gupfpS_f!l2y{T>9D~7t9sCx%C)Rd=_kyNr$g-6Ae8%M~ zS2-Mx@HozPzrZ@J)}}JO+#H*q{)n;$j~|Ut$EOWAKf$$zF1x1k|1+-c%obz{5O9C=Z3AH=`D0Ox_f7w4|{(c@2XbbOiP%by`zCZzKzdA`8fntrd3bNgQcTe+1O zC&k4m%a0y^ii6>h2R`>zs((9SKA%w6B|#8ugZ?97D+0W~m-q8)&!V;F>ZiXpRIxrX$?vnlkvG*H^H*Y-a=d&42V+q3m=N#Yo*3&!tUVHCO%+980 zEms$)m1WmC*}DK*YZi+I#%Pq1IOloj!K0m(hKLSIKn$<;u@_F`14DTdgmIx{mAb(UL@?@0Y#n@ zXoa;7Ar(?-oO4uFi4=mmwwN$R>5$j|@R)z?rAIgFh`pD>H(vd*UoKYjLqaOzR)@IN zMhb!Vj=Cx-%N(f!!qAXs8Ff{nl%%Q~9{$d6){0^84j3GaI2azSZiu}@3cuQG}maEAUAtZ6sA}|5oHPltkd^W)Zip6rt;o%7Hq19?51REK){ufj{DT@jC Rs!jj^002ovPDHLkV1hPzSn>b> literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/chasm3.png b/Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/chasm3.png new file mode 100644 index 0000000000000000000000000000000000000000..dce7efd9a639c63eb82a9dd450aa5327c811f0b8 GIT binary patch literal 1298 zcmV+t1?~EYP)Px(%t=H+RCt{2n>~-zRuqOG`(A&{_l%icfk+t%r43CaQc>q$q)AI?5JE~3gpd+J zn==1^G->IOQjv~8vr-}j!ZIKBcxL={?VAE7VmFHr@!-1=^Hi2?`Sp2y?j8G_I~ImH z`1MDfBngh=uvmmd^C?o=C{<7@g^&{8Z{hhJI^7;x!*n`93Y)T2eE!8ZRvmr0tw8=O zRaN1-ER>zrHe9-}r;i79>B64gZ10a-TS@ujoQe#9H>dJu|MAq{7N^F5x3QTR zx6P?G;PtHdpfh0Gl5NO`CnwfjvYI8?AWnm$BrF4c5Iv4pP3Ku-_Zd5!Qh{L zA7A|Pjn{p6|Bl|AyNDt_z5KP&Pu<#mf$8KaqhO!ebjm0Qm`+|C3Gz6r)soe6MWr>i z5Ow8iQ`-O`B=gyXAQ)2=Im2PVbT%Q5LmcU#N`>orNFgYSlEGj|n&pf}BcdqUMhvy6 zZGhGmWm&Rb$3#)c*>mSP6O7SR#ES^avakT#mW+ZS>ve+Xd1P5eyWM{4_1`zO3nIOK zA6p2@vZN?-;zdZBu94EgZ?(yb0wE+>mXfU3SeEsw5t?CH<||!|-ob;Pztw}m5Gh?8 z*Ch-?E?&N3)P+V%Vvgf5pG}$1XDFqps;Wu(6KS+NoTeGAmX8pUJj>{Ap}Sj`Mh$RX zhh)75Ti|;Y9nou2{zMub0_}F2s?u~j9SW5*ojh++{zRIc16-d`5D>=;bX5ZHrPTjU zG-|;0tG95y7XAK^UawED*Kbn(L>h05EEf@FS&^hUr{G7RSpyy&%t?|ZN)-(H1FGr+ z8v+1>VL%j3DT?gXYA~}HStTYcc>3q>_fG5vl%k^4lt*J^ymaUtVKM^zC zVavw0ZL;+JEP8ks8a3dzUw+Wxd_u23q(2y8S?0U*jn4tL{qpIfHNkkVY59NAxB)^q zC{-XG7op9+2pF$OJiPzCj>3?#RCu1lc>g?~eD+mi_hoz#hVvOx+GwrGa@DxLaRa23 zESF1MS0Y67w`1IZ;phy$?~~^_j%@zD%=rHW(lo>M+E`YKblk@Ejb}g@PH43}di?>; zhiCx058_@1_DT;!{V$OOM^V7ZW8r3&$z;HBX6zrijEEi$p`o>>`Ds2-4 z`y^>frOU?kjT>ND7SeTTclxiICCy@d2nZp_vX?7MOjL;e2GwB%d2_tXA^-pY07*qo IM6N<$f+ezY%m4rY literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/chasm4.png b/Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/chasm4.png new file mode 100644 index 0000000000000000000000000000000000000000..5cc155f8252a7761f777562faf37e7b6b1f68043 GIT binary patch literal 1464 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/full.png b/Resources/Textures/Tiles/Planet/Chasms/desert_chasm.rsi/full.png new file mode 100644 index 0000000000000000000000000000000000000000..03aa532353e8cda95c956194f8636be5290a38eb GIT binary patch literal 1951 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 YA4MS#kLjY|Z~y=R07*qoM6N<$f<6}8#{d8T literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Chasms/snow_chasm.rsi/chasm1.png b/Resources/Textures/Tiles/Planet/Chasms/snow_chasm.rsi/chasm1.png new file mode 100644 index 0000000000000000000000000000000000000000..502b9e3d7199a3916686fe138b92807ca1e35351 GIT binary patch literal 904 zcmV;319$w1P)Px&LPjhdv^lN42MH< zT^Ef;14INNM66s00V0aN+qMm@HNr525CZjjT_k_=Ay{b+&H|+r8jS`3z;PUSo(J2u z0RUQS5K&BkQVN!3jft9-XPNv;O5BU{XuI8PK`8|Quq-S3G!m-SYE(XY+^nz*a4*hr z*mEbAwVN#fK&@7TQVK+b!C)};xQDbul&*#(%2clNf$>e@QBpTCH{1BfJ; zGv4iyP35x)&b?lzO2}^RcQmKqh zec^(o1ym{(1VMl>3^~HbU=eVAeGMT5Zf|cn!pC5J3e@X$&hP+o7Le=%Xsz=MKat#9 zfaxk1;RXmW2r!jr?g2-XJ;6MK9roNzW_M;ut^&;THUL;!T6((u04XIr&nrZCI9CB? zribtQg}Di`GaL@7-|v&>c{FW6bsn%k1xD8kaKJ7A;2j$*gaESuf`dW`;G_@&gb)aV zfF*Vz1P~D%$3eT2HE+EP)Px);7LS5RCt`-Tg`6UMiBm%GXK1klfbHcs1P7+fx<`-I63B+b047h9{U1CAE4+9 z^w?7`1&UsZqChV>=I9EB1EYXl1BQy)jvClrQd*J`r-yVmB&FJkxfI!a7g?mF@qD}U zvok}6hLNTzjYcE%dOZ*k7-NO|j4=?Ae(!l6vMfU!$6$=1+wHRQZ@vwzDql7MDJ6Qn z9st1ieF!1oc^&{D%Q6sAfdDBbEX$fB>bhv0003HHDJ8nyE~JzI0L!upuK?gUj=paK zE5?4Q0T8bUfQS&s zF`l2F8CM=?2?2RbCKGVZA*ICl;#^-}r2NisyRy925WqP{6h&BBSpgAYd~rT!>t*GC z{{Gv_v9R$l7)4Rx)pcF``TTS#$^$Lf0i5%N86dFO)=g~tJQ^ne0J_~Sgb-kifpZRE zUirM@qoYG(vKu!6;FaS`k_4XT;rGKo3fq5YxQ(6RHbzH>dfN}5J~5LAqa_4nS%xG@ zbVjIFU#)t6#Z9h0&;k=6B1kD=+jb$*`Q@h{3!gK&>aBthf`kwhMG@^C?9-QDe?wc3 z9@Ev|{GVd)V4uP;q~qgb3d68*MVIOW_73)G(BFV<+dBL;jiva2y@P!MfI)u)0FWff zGQ_?SY9~OgdK*@I5td>CjIlyhCkTRNhP}^S}bb!}n zl#88Bp*8}P@|VG6ar3$`Y68mJ1Ft=?=!|QolZ@PzZQ%T zu*livp|<*^4^YZyS%x48=E9s>@iy4LLS^>TG^IC*=V_WENs>ZH1m1xipp?HXqy<3$ z&iS13Z9ruLq9{U^W&dgSjIn~lYs(oxp)vuSbF8hc>GwpWL!EjrgwOS8S^MFOY`ayp~=lrhg zA`C9?>`a?Vr_+HD0&yIh5MK$E2~bUpd-v|@Yh^+P z{SDl@bxV)9BuN6s7-q9sRq>Tk*(HDS>1T9*>*3t>JRuJ@2k5Qcm`j%}%L3=T(Xdc? z2mITwD;V?rt%um%eO4f$tUU1gkkllMvA^}`F%53t!RY7^gWGqYc7-D0!R7z}@cw&! z?I2AII#z|Tg2=1h-D6U(KyfGJ{lcKX(VB#)ma1@>ggg`xSJexb1*50Id<^a;zi zvUhi%8J+Gjg<8wv!>3Q!&Tv~R{?!+sYl4CxcsKHZt567VO+w=Y5K$pZT=V>;lF+yz zo}ZtSWm$8>lIod&%@04S^?z)ffP7hH3eWS9rm1eWj!sYT z-4DOkBERub*>X|DwrxzO)57yYfcY_bg~oTlBFtv9!c-Yxen?uOHDNG6J(Bkcj^p6v z%a=Gh{;QU7*ct)==wv8QMifQhoMSqj;%{*=_x-A*H0}cw)I(E1agN#zw$3sgb;$_I4%@N%F|?vz&Te>m{!u^ YA4MS#kLjY|Z~y=R07*qoM6N<$f<6}8#{d8T literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Chasms/snow_chasm.rsi/chasm3.png b/Resources/Textures/Tiles/Planet/Chasms/snow_chasm.rsi/chasm3.png new file mode 100644 index 0000000000000000000000000000000000000000..502b9e3d7199a3916686fe138b92807ca1e35351 GIT binary patch literal 904 zcmV;319$w1P)Px&LPjhdv^lN42MH< zT^Ef;14INNM66s00V0aN+qMm@HNr525CZjjT_k_=Ay{b+&H|+r8jS`3z;PUSo(J2u z0RUQS5K&BkQVN!3jft9-XPNv;O5BU{XuI8PK`8|Quq-S3G!m-SYE(XY+^nz*a4*hr z*mEbAwVN#fK&@7TQVK+b!C)};xQDbul&*#(%2clNf$>e@QBpTCH{1BfJ; zGv4iyP35x)&b?lzO2}^RcQmKqh zec^(o1ym{(1VMl>3^~HbU=eVAeGMT5Zf|cn!pC5J3e@X$&hP+o7Le=%Xsz=MKat#9 zfaxk1;RXmW2r!jr?g2-XJ;6MK9roNzW_M;ut^&;THUL;!T6((u04XIr&nrZCI9CB? zribtQg}Di`GaL@7-|v&>c{FW6bsn%k1xD8kaKJ7A;2j$*gaESuf`dW`;G_@&gb)aV zfF*Vz1P~D%$3eT1KIqEP)Px%;7LS5RCt{2o4;?`KorNnMzv*RgH%x^3u=dEiGr%MW5@oVnNn4ex@PIpv15Xw zR4kxMEdyj>@EPMX+;xcT9hc7JYawUjYb3GhiNAM zu79I9zSd|3L{XG&>lP0fU_i6k1n@`v_~#F;@tcz<>FrVHHAobUy~h8E|l60=I*4HUXN>1yZ8jfKMMUvu$-QfC}vfs53t%b%t6=tHB@$$U6e< z888?PW%uaVi1Y^t3n9)q9LJ#wpFv`P>$(8UD2Yi7P(OxHLt=m_RUlA7C7AZ)zVCxE zR@lb(eQ?f=NclXaGaw8@2q89#w=8R|!!zmb0~KVzEM%C44Bew+0FO2Pa=FZ2bHApO zwf4_FADvDIQ4|?rMri|X2jl-b|Ms+tSy-Gc6jU}E++@W4{r9Ru?1j<>hsN8_3l>Rj}H8nLgH8nLgHHQoNsO?`%Px$qe(ALG!3T^w-Ig~))8j?O#)J8$6=_yUej5aR6Iuy`;kZyj5MlD1oA`fIxBuS5ZAtFA7cjP1EF?)1$+Ao)lZk|JB%1jp z&9H5{Fc*{7IzG<<^}rg-Rf)UwSBkd8;IXFp6a7`&?H zn-{DLF83lPSUoK%iABll8Y0ePOo^E`-{fByg|cZdBj#YL@(&#zoFb|=*WJaju4G%f)E z_4>JH^siJ4uRsib+qWQ`Jk;1@i)k f21KIqEP)Px%;7LS5RCt{2o4;?`KorNnMzv*RgH%x^3u=dEiGr%MW5@oVnNn4ex@PIpv15Xw zR4kxMEdyj>@EPMX+;xcT9hc7JYawUjYb3GhiNAM zu79I9zSd|3L{XG&>lP0fU_i6k1n@`v_~#F;@tcz<>FrVHHAobUy~h8E|l60=I*4HUXN>1yZ8jfKMMUvu$-QfC}vfs53t%b%t6=tHB@$$U6e< z888?PW%uaVi1Y^t3n9)q9LJ#wpFv`P>$(8UD2Yi7P(OxHLt=m_RUlA7C7AZ)zVCxE zR@lb(eQ?f=NclXaGaw8@2q89#w=8R|!!zmb0~KVzEM%C44Bew+0FO2Pa=FZ2bHApO zwf4_FADvDIQ4|?rMri|X2jl-b|Ms+tSy-Gc6jU}E++@W4{r9Ru?1j<>hsN8_3l>Rj}H8nLgH8nLgHHQoNsO?`%Ygr+Ar*7p9%SSN@(wNd?w`wN fz5vKX1`XxR4h{^A{hv+-f`mO?{an^LB{Ts5qcarg literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Chasms/snow_chasm.rsi/full.png b/Resources/Textures/Tiles/Planet/Chasms/snow_chasm.rsi/full.png new file mode 100644 index 0000000000000000000000000000000000000000..525cdc2680e3c3c19c602e4a7c555d7f16995ec7 GIT binary patch literal 1225 zcmV;)1UCDLP)Px(gGod|R9JH8B)rUfH;mZ3`3KLVMvx`YsrNWq-jd4)zahAd=LcEwr%1#u3ez&g;uMzVoA|@ zDJ54|SD2=$=aVGCvMepQ-EI>_5kd%>%BoGUEQ>gfky4VTDWlgHrTM$ATN1akvqKn$ zT2Q;)=H<(m+_`fH$USRW7HOL10*a7Q;&~oI2*%?v$~(%+(d!HT{A;vPu;1-r7=|XA z&1Q5u9laHeMni9HQ@MCPpW`?V^Z6Vh1VRWJjfP&dNX$MTp=&w@bI8kz|p>s-|ekr6Xfx*A|MPyT-POz zW5&~oeqKj@deR5r-u>f^f{ylmI@`B&b}1N!aUBD$>k@_`&1MrRCFAL2#kE!Pr@#GL zYxTYR#|#F;l87of9W)>`*Is0u#X_qn_G zH9-(ySr$zp1diii7zRuy34)Rdpvvk%O@A0(C1E6d0T{R+s1Jm{BDoiw|40F zpM8`7wYK7cJO#CYD2nu8JRTFrF;NuZx-OPw;dgr2b*7K?@c z|Dht3`&E0U#1ust%jI&VSx}v9^_2V&@=b{2n5Jo(CGy2$!S?nx)9F+zAHBZd;m^O{ zh*Y6SUNl4<#Q>&h(o_Ql(=>^qsMHU_`eV3Ae#`lct*tEpmdhnsmSLKvZfL75z2|ut zb&D;R%Tm!L<{g}pJj^lWxFKo41*8)^iT1DN5 zo8~rMQtQMSsywQFs+LSe@aD}M{Y+)eI`S;b@H}tj%BQxuSo}l~1hRN}R4>+DrHgP~ n7a;^!S6A=6TSA`Rb+zSxe7?&vQbxhA00000NkvXXu0mjfKw3wE literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Chasms/snow_chasm.rsi/meta.json b/Resources/Textures/Tiles/Planet/Chasms/snow_chasm.rsi/meta.json new file mode 100644 index 0000000000..e303031e1f --- /dev/null +++ b/Resources/Textures/Tiles/Planet/Chasms/snow_chasm.rsi/meta.json @@ -0,0 +1,49 @@ +{ + "version": 1, + "license": "CC0-1.0", + "copyright": "Created by TheShuEd (github) for ss14", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "full" + }, + { + "name": "chasm0", + "directions": 4 + }, + { + "name": "chasm1", + "directions": 4 + }, + { + "name": "chasm2", + "directions": 4 + }, + { + "name": "chasm3", + "directions": 4 + }, + { + "name": "chasm4", + "directions": 4 + }, + { + "name": "chasm5", + "directions": 4 + }, + { + "name": "chasm6", + "directions": 4 + }, + { + "name": "chasm7", + "directions": 4 + }, + { + "name": "chasm" + } + ] +} \ No newline at end of file From 0d5da6c30a38a530c70e1fbb04da221ddff13e2a Mon Sep 17 00:00:00 2001 From: nmajask Date: Thu, 26 Oct 2023 22:12:35 -0400 Subject: [PATCH 063/102] fixes and tweaks (#21172) --- .../Objects/Consumable/Food/burger.yml | 2 + .../Objects/Consumable/Food/ingredients.yml | 13 ----- .../Objects/Consumable/Food/meals.yml | 2 + .../Recipes/Cooking/meal_recipes.yml | 4 +- .../Prototypes/Recipes/Reactions/food.yml | 49 ++++++++++--------- 5 files changed, 31 insertions(+), 39 deletions(-) diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/burger.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/burger.yml index 9b8411b803..59cfc0ba16 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/burger.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/burger.yml @@ -618,6 +618,8 @@ id: FoodBurgerMcrib description: An elusive rib shaped burger with limited availability across the galaxy. Not as good as you remember it. components: + - type: Food + trash: FoodKebabSkewer - type: FlavorProfile flavors: - bun diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/ingredients.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/ingredients.yml index 71008ac89a..166a73e43e 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/ingredients.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/ingredients.yml @@ -427,19 +427,6 @@ graph: Tortilla node: flat -- type: entity - name: bun - parent: FoodBakingBase - id: FoodDoughBun - description: A base for any self-respecting burger. - components: - - type: FlavorProfile - flavors: - - bun - - type: Sprite - sprite: Objects/Consumable/Food/burger.rsi - state: bun - - type: entity name: raw pastry base parent: FoodBakingBase diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/meals.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/meals.yml index f4b52217cd..cb79f9b3a3 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/meals.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/meals.yml @@ -326,6 +326,8 @@ id: FoodMealRibs description: BBQ ribs, slathered in a healthy coating of BBQ sauce. The least vegan thing to ever exist. components: + - type: Food + trash: FoodKebabSkewer - type: FlavorProfile flavors: - meaty diff --git a/Resources/Prototypes/Recipes/Cooking/meal_recipes.yml b/Resources/Prototypes/Recipes/Cooking/meal_recipes.yml index a9ea6b0876..4ec4118177 100644 --- a/Resources/Prototypes/Recipes/Cooking/meal_recipes.yml +++ b/Resources/Prototypes/Recipes/Cooking/meal_recipes.yml @@ -24,7 +24,7 @@ time: 10 solids: FoodBreadBun: 1 - FoodMeatCutlet: 3 #replace with bacon + FoodMeatBacon: 1 FoodCheeseSlice: 2 - type: microwaveMealRecipe @@ -186,7 +186,7 @@ time: 10 solids: FoodBreadBun: 1 - ClothingOuterGhostSheet: 1 #replace with ectoplasm once added + Ectoplasm: 1 - type: microwaveMealRecipe id: RecipeHumanBurger diff --git a/Resources/Prototypes/Recipes/Reactions/food.yml b/Resources/Prototypes/Recipes/Reactions/food.yml index 3ca69b379d..c7f4038db0 100644 --- a/Resources/Prototypes/Recipes/Reactions/food.yml +++ b/Resources/Prototypes/Recipes/Reactions/food.yml @@ -148,6 +148,7 @@ amount: 30 Enzyme: amount: 5 + catalyst: true effects: - !type:CreateEntityReactionEffect entity: FoodTofu @@ -158,11 +159,11 @@ id: CookingKetchup reactants: JuiceTomato: - amount: 10 + amount: 2 Sugar: - amount: 5 + amount: 1 products: - Ketchup: 15 + Ketchup: 3 - type: reaction id: CookingMayoVinegar @@ -203,67 +204,67 @@ id: CookingKetchunaise reactants: Ketchup: - amount: 5 + amount: 1 Mayo: - amount: 5 + amount: 1 products: - Ketchunaise: 10 + Ketchunaise: 2 - type: reaction id: CookingBbqSauce reactants: Ketchup: - amount: 5 + amount: 1 Vinegar: - amount: 5 + amount: 1 Sugar: - amount: 5 + amount: 1 products: - BbqSauce: 15 + BbqSauce: 3 - type: reaction id: CookingHotsauce reactants: JuiceTomato: - amount: 5 + amount: 1 TableSalt: - amount: 5 + amount: 1 CapsaicinOil: - amount: 5 + amount: 1 products: - Hotsauce: 15 + Hotsauce: 3 - type: reaction id: CookingVinegar reactants: Ethanol: - amount: 5 + amount: 1 Oxygen: - amount: 5 + amount: 1 products: - Vinegar: 10 + Vinegar: 2 - type: reaction id: CookingSoysauce reactants: MilkSoy: - amount: 10 + amount: 2 SulfuricAcid: - amount: 5 + amount: 1 products: - Soysauce: 15 + Soysauce: 3 - type: reaction id: CookingVinaigrette reactants: Vinegar: - amount: 5 + amount: 1 OilOlive: - amount: 5 + amount: 1 Blackpepper: - amount: 5 + amount: 1 products: - Vinaigrette: 15 + Vinaigrette: 3 - type: reaction id: CreateMeatball From a793a66d19176709bcc1a7166246785507de9a75 Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 26 Oct 2023 22:13:40 -0400 Subject: [PATCH 064/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 8a27f45d7d..87b2f2e68d 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,9 +1,4 @@ Entries: -- author: PixelTheKermit - changes: - - {message: Arachnid zombies no longer get functional hands., type: Fix} - id: 4564 - time: '2023-08-13T19:51:21.0000000+00:00' - author: ElectroJr changes: - {message: 'Fixed a bug causing inventory slots to sometimes ignore interactions @@ -2895,3 +2890,11 @@ Entries: slots and sizes.', type: Tweak} id: 5063 time: '2023-10-26T08:28:16.776154+00:00' +- author: nmajask + changes: + - {message: Bacon burgers require 1 bacon instead of 3 cutlets, type: Tweak} + - {message: Ghost burgers require 1 ectoplasm instead of 1 ghost sheet, type: Tweak} + - {message: Tofu creation no longer consumes the enzyme, type: Tweak} + - {message: Ribs and Mcribs now give back skewers when eaten, type: Fix} + id: 5064 + time: '2023-10-27T02:12:35.0000000+00:00' From 55f232ae09bdb484c616d79ca8640143102861ac Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Fri, 27 Oct 2023 13:14:01 +1100 Subject: [PATCH 065/102] Fix ItemPlacer (#21160) This is going to lead to many entities being ticked unnecessarily and performance problems. --- Content.Shared/Placeable/ItemPlacerSystem.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Content.Shared/Placeable/ItemPlacerSystem.cs b/Content.Shared/Placeable/ItemPlacerSystem.cs index 92dc8eb74b..ec6ece671f 100644 --- a/Content.Shared/Placeable/ItemPlacerSystem.cs +++ b/Content.Shared/Placeable/ItemPlacerSystem.cs @@ -9,6 +9,7 @@ namespace Content.Shared.Placeable; ///

public sealed class ItemPlacerSystem : EntitySystem { + [Dependency] private readonly CollisionWakeSystem _wake = default!; [Dependency] private readonly PlaceableSurfaceSystem _placeableSurface = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; @@ -25,8 +26,8 @@ public sealed class ItemPlacerSystem : EntitySystem if (comp.Whitelist != null && !comp.Whitelist.IsValid(args.OtherEntity)) return; - // Disallow sleeping so we can detect when entity is removed from the heater. - _physics.SetSleepingAllowed(args.OtherEntity, args.OtherBody, false); + if (TryComp(uid, out var wakeComp)) + _wake.SetEnabled(uid, false, wakeComp); var count = comp.PlacedEntities.Count; if (comp.MaxEntities == 0 || count < comp.MaxEntities) @@ -46,8 +47,8 @@ public sealed class ItemPlacerSystem : EntitySystem private void OnEndCollide(EntityUid uid, ItemPlacerComponent comp, ref EndCollideEvent args) { - // Re-allow sleeping. - _physics.SetSleepingAllowed(args.OtherEntity, args.OtherBody, true); + if (TryComp(uid, out var wakeComp)) + _wake.SetEnabled(uid, true, wakeComp); comp.PlacedEntities.Remove(args.OtherEntity); From c9827c536445ae3c8af56036e66376cbf2e78b5a Mon Sep 17 00:00:00 2001 From: JoeHammad1844 <130668733+JoeHammad1844@users.noreply.github.com> Date: Fri, 27 Oct 2023 13:19:35 +1100 Subject: [PATCH 066/102] headrev spawn music (#21119) * headrev spawn music * :trollface: * skill issue * double skill issue * :trollface: * :trollface: * :trollface: --- .../Components/RevolutionaryRuleComponent.cs | 2 +- .../Audio/Ambience/Antag/attributions.yml | 6 +++++- .../Audio/Ambience/Antag/headrev_start.ogg | Bin 0 -> 171100 bytes 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 Resources/Audio/Ambience/Antag/headrev_start.ogg diff --git a/Content.Server/GameTicking/Rules/Components/RevolutionaryRuleComponent.cs b/Content.Server/GameTicking/Rules/Components/RevolutionaryRuleComponent.cs index 7d036c615b..e9c8d50cdc 100644 --- a/Content.Server/GameTicking/Rules/Components/RevolutionaryRuleComponent.cs +++ b/Content.Server/GameTicking/Rules/Components/RevolutionaryRuleComponent.cs @@ -39,7 +39,7 @@ public sealed partial class RevolutionaryRuleComponent : Component /// Sound that plays when you are chosen as Rev. (Placeholder until I find something cool I guess) ///
[DataField] - public SoundSpecifier HeadRevStartSound = new SoundPathSpecifier("/Audio/Ambience/Antag/traitor_start.ogg"); + public SoundSpecifier HeadRevStartSound = new SoundPathSpecifier("/Audio/Ambience/Antag/headrev_start.ogg"); ///
/// Min players needed for Revolutionary gamemode to start. diff --git a/Resources/Audio/Ambience/Antag/attributions.yml b/Resources/Audio/Ambience/Antag/attributions.yml index 3d7d5c737c..0a4a0479d1 100644 --- a/Resources/Audio/Ambience/Antag/attributions.yml +++ b/Resources/Audio/Ambience/Antag/attributions.yml @@ -9,4 +9,8 @@ - files: ["zombie_start.ogg"] license: "CC-BY-NC-SA-3.0" copyright: "Made by @MIXnikita#1474 (Discord) for SS14" - source: "https://github.com/SerbiaStrong-220/space-station-14/commit/f33ce80db9d8ac962ec36eb5ae61afa8c0035d1a" \ No newline at end of file + source: "https://github.com/SerbiaStrong-220/space-station-14/commit/f33ce80db9d8ac962ec36eb5ae61afa8c0035d1a" +- files: ["headrev_start.ogg"] + license: "CC0-1.0" + copyright: "Made by https://www.youtube.com/@a-guy173" + source: https://github.com/A-Guy173/Music/blob/main/revolution.mp3 diff --git a/Resources/Audio/Ambience/Antag/headrev_start.ogg b/Resources/Audio/Ambience/Antag/headrev_start.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f97ab15a3efdcf1454fa6d36a47b30e6ab1e0a55 GIT binary patch literal 171100 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 literal 0 HcmV?d00001 From a2e9454e1ce8f2b4e1fe164f9b829d1911b8d59d Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 26 Oct 2023 22:20:39 -0400 Subject: [PATCH 067/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 87b2f2e68d..a2f5a7a552 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,10 +1,4 @@ Entries: -- author: ElectroJr - changes: - - {message: 'Fixed a bug causing inventory slots to sometimes ignore interactions - (e.g., not opening the context menu).', type: Fix} - id: 4565 - time: '2023-08-13T21:55:18.0000000+00:00' - author: DrSmugleaf changes: - {message: Fix "remove single hand" admin smite having gone missing., type: Fix} @@ -2898,3 +2892,9 @@ Entries: - {message: Ribs and Mcribs now give back skewers when eaten, type: Fix} id: 5064 time: '2023-10-27T02:12:35.0000000+00:00' +- author: JoeHammad + changes: + - {message: 'Headrevs now have their own music on spawn, credits to A-Guy on youtube', + type: Add} + id: 5065 + time: '2023-10-27T02:19:35.0000000+00:00' From 7a0759f2c0cdea6aa3ee63b44d37e821ee5e2bf0 Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Thu, 26 Oct 2023 22:21:14 -0400 Subject: [PATCH 068/102] Techfab resprite + department fab sprites (#21136) --- .../Entities/Structures/Machines/lathe.yml | 1 + .../Structures/Machines/techfab.rsi/ammo.png | Bin 700 -> 657 bytes .../Structures/Machines/techfab.rsi/cargo.png | Bin 0 -> 645 bytes .../Structures/Machines/techfab.rsi/engi.png | Bin 0 -> 651 bytes .../Structures/Machines/techfab.rsi/icon.png | Bin 6790 -> 1122 bytes .../Machines/techfab.rsi/inserting.png | Bin 5782 -> 713 bytes .../Structures/Machines/techfab.rsi/med.png | Bin 666 -> 647 bytes .../Structures/Machines/techfab.rsi/meta.json | 17 ++++++++++++++++- .../Structures/Machines/techfab.rsi/sci.png | Bin 0 -> 677 bytes .../Structures/Machines/techfab.rsi/sec.png | Bin 0 -> 663 bytes .../Machines/techfab.rsi/service.png | Bin 0 -> 648 bytes .../Structures/Machines/techfab.rsi/unlit.png | Bin 5472 -> 648 bytes 12 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 Resources/Textures/Structures/Machines/techfab.rsi/cargo.png create mode 100644 Resources/Textures/Structures/Machines/techfab.rsi/engi.png create mode 100644 Resources/Textures/Structures/Machines/techfab.rsi/sci.png create mode 100644 Resources/Textures/Structures/Machines/techfab.rsi/sec.png create mode 100644 Resources/Textures/Structures/Machines/techfab.rsi/service.png diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index e492c08b5d..fbd19d5fd0 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -506,6 +506,7 @@ layers: - state: icon map: ["enum.LatheVisualLayers.IsRunning"] + - state: sec - state: unlit shader: unshaded map: ["enum.PowerDeviceVisualLayers.Powered"] diff --git a/Resources/Textures/Structures/Machines/techfab.rsi/ammo.png b/Resources/Textures/Structures/Machines/techfab.rsi/ammo.png index 38f7a4dd2cb919e69d387d37efb188635921a680..c2f1c61ace7f267b6c31fd7ed040f793df9d48c2 100644 GIT binary patch delta 230 zcmV9aR4>I@NvM4D=$%Kx;Vfz4li4a<%Q3a431>5(WrJChrIpD^fn^bkc&`blP4j5JrAUPMjK`wGf g!6+C7qkswk0FNOqmO~aI^#A|>07*qoM6N<$g2lLAbN~PV delta 274 zcmV+t0qy>g1-u2Yv;lwFNkl+k`Of>8$y zxC4mJ1tG--R4Itac7TDV94+i8-T{slDkyw%%LTF>&_914HSB*Q-vKx7+@y&E23IbS zFk$)6FU(9=2VjH%D+d$9>?l(PRt_cRB!003fyH2SG2lw<$^01jnXNoGw=04e|g00;m8 Y000000Mb*F000UA07*qoM6N<$f(No};{X5v diff --git a/Resources/Textures/Structures/Machines/techfab.rsi/cargo.png b/Resources/Textures/Structures/Machines/techfab.rsi/cargo.png new file mode 100644 index 0000000000000000000000000000000000000000..d89e51d1994efe50345556e996eeae43a436502f GIT binary patch literal 645 zcmV;00($+4P)EX>4Tx04R}tkv&MmKpe$i(@I4ug6$yUkfAzRDJtS9RV;#q(pG5I!Q|2}Xws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;qmz@Oi4rtTK|Hf* z>74h8L#!kz#OK8023?T&k?XRT(DP#3AESVO7iiXP`}^3onpV2qvfZ#3Ax90TL-pAn`u^?e6X0GwuF<0N`D6)Bk!mX8-^IyGcYrR9J;$U>F4>9Waurp(;lIKP48n zExCwdCkv?txLT?*eERr-EX(=$1sE6@82%$Wf{7f1PF{OWH9cfGfE0%iQbTeS-~xV? zyHWU?+Fgm#M^Ol%gH7$OL|Y64R0{zH2Fy?(22d0N=31f@t05}{uo+4y=y5rO>?rWB z+Cy?7h7C|P5z@^8&=QR*faECHef&1nEGNqWk6(VGssn~*8W?rJuyO#&x#0b$@3e5o fC>RB!U<3mIshuf!O=Bo|00000NkvXXu0mjfu^l3d literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Machines/techfab.rsi/engi.png b/Resources/Textures/Structures/Machines/techfab.rsi/engi.png new file mode 100644 index 0000000000000000000000000000000000000000..5ba7c813b94d4f814f877a94f5cb92aab354a591 GIT binary patch literal 651 zcmV;60(AX}P)EX>4Tx04R}tkv&MmKpe$i(@I4ug6$yUkfAzRDJtS9RV;#q(pG5I!Q|2}Xws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;qmz@Oi4rtTK|Hf* z>74h8L#!kz#OK8023?T&k?XRT(DP#3AESVO7iiXP`}^3onpV2qvfZ#3Ax90TL-pAn`u^?e6X0GwuF<0N`D6)Bk!mX8-^I!AV3xR9J;$U>F4>9WaurVe@Q_|CCth zn|cGqPLdsP?|8ufPai*$WjP-|Kf~24H&7hGM2pz{k%|H3yI!1y`@!pqk}mIpE68_f&Pj&`blP4j5JrAUPL2 ldiI?b?idB5U=)mC007idGlE=qvO53(002ovPDHLkV1l5kDV_iT literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Machines/techfab.rsi/icon.png b/Resources/Textures/Structures/Machines/techfab.rsi/icon.png index 4015336f16be039212b77c4bdffe50b222dd8a26..186fd30082bff99b748392c422265ee93f793237 100644 GIT binary patch delta 732 zcmV<20weu~HR1@6BNYLJX+uL$Nkc;*aB^>EX>4Tx04R~O9SL;-e-f3JGynhsnMp)J zR9J=WmcMV)KorNnpc*A@)m+o4RZ@mTN(WaAj#`3>klH0vH~0fU0w%_`BVy{*GBP5u z0UJnc9Vlain|P?|0T4loZ5*m_k(xAMp)e%A#y|7J5iI>m*7@E&zxTQ4yR(4{{byaW z8}8lTYI!-oc)sKCe-ElLd-5lbH=t@K4#z}11^_MTa4%3oNs=s+7_&Px&YA##q9ik0 zM&Ow}l}e#ntqzqu8jS)#s~h67n`2RuA&Plq1RkQ8x4-~EtyXgccDwwZ@dYq-=k_`t zKDg^S?iF+pA76lfp$mXO0Fg)}u#aOK4wJZ_ZRrK#02mL4e~=M)0KoEc7DY)$M&L0X z4q5zC>1^M?-4dc{2urz^d8#@9raGjAT(>|?xy)c|^ARXL9SDGsN$l)CV|@#Nrm1-O z>Rrzu_CqF!EC7^Jh+^L1q-iSR@dRY~7{3|{fOaWI4q!@_k3k3l0L0@7gs;@uSfkNk zQ1ACY4wY2Xe^h?}0BF|B;5ZII0;N(3!pwqY+^t$4_IrORSJ!f&l=cP)O<6s!Z zXaRVB(bCr{2FQ$ifRR_Adxe@JgfM%(-rf<@vG!Qgf0#tGQ-F%DU}JOJGuhMKZO7y+ z|7SODu6zEF+EvjN%+AfT?b@#>rKso%zJ8J1kK&b;Tdohv@)3Cc8tcD(^BNUhK}A;v z0%c&6@|h9etiGTDsKTet)G8b%$4uA z1N=ltI+Rt@Y~9wE;}yvAQRi*~XPVm8x(D#mc^rQ^01AbJzLQ*N6#5GooB&i;3?JqI O0000GMJOoYi1eL=n* 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 diff --git a/Resources/Textures/Structures/Machines/techfab.rsi/inserting.png b/Resources/Textures/Structures/Machines/techfab.rsi/inserting.png index 3f3c09debfbc3ef9ed2b2b1358ef0636181d9141..647eb27246f727f5155ced61ad1fecea6b20e684 100644 GIT binary patch delta 320 zcmbQHdy;j6vM6Iqrn7T^r?ay{K~a8MW=<*tgT}s^9gbTKe6GI+W;hE&XX zdwXMEvw;X}!1j`l>L32!Z@Urcz~i@^PqJXimXF1+iq%vEww25mXwLU)`L$!$#&xgX zKChbh{Pgo5bJyQGJE!>8_q|u+-t`zUTxD3)YrrsnebvYM3B`3krIs%K1LT=9?9b$)+;%>F5pw&ik1%foavsAryFSv`+8 zx6p21TI96bkC)$z-rip9uGo;k#Ia0K_{}Ey2Q@Zw5akDM|7H_#D;7F(lScz2;_2$= Jvd$@?2>@lvg!KRb literal 5782 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 AyZ`_I diff --git a/Resources/Textures/Structures/Machines/techfab.rsi/med.png b/Resources/Textures/Structures/Machines/techfab.rsi/med.png index 506b03568a64b240ca60f6d7ebf52a3c0f31abb0..86a740cb4ca7b4722c7b387daddaf2353d8d12d5 100644 GIT binary patch delta 219 zcmV<103`pK1&0N&wE=&i$qqWs)PW{r=<8C1}F*vVP#2*)sPhexD3VTb6k4Jj)GHVS*|3PA=toxCql9u zz$++BH3yI!1rN?#p_=7nIpEj3pHy|g&`blP4j5JrAUPL&e)^6U?idB5U=)mC003`# VF%F*nid_Hz002ovPDHLkV1h6-TaEw# delta 238 zcmV!g5n4!icF*eU?EoF%t#}mLkk&1P1}t(>S!JU%d%YYI()#RVAKHv z?f{~50ksMuvK=6-EJ+LdiFW|6pfC!b+;V|z2Rt})g&Ove?|^1s?|#z60fQ?Sn7DQR z=j7w2s{=4XfQ6TxAvsKwfrXbHj+4VQQPjkHD$&jXFvAJaG;_eh?e~bHsRdB-vWZ(K o(WTv)UFB3M2S&jt7zLvM0L>UT%%gQ=(f|Me07*qoM6N<$g0OXMDgXcg diff --git a/Resources/Textures/Structures/Machines/techfab.rsi/meta.json b/Resources/Textures/Structures/Machines/techfab.rsi/meta.json index 11a48c4a0d..7530b9322a 100644 --- a/Resources/Textures/Structures/Machines/techfab.rsi/meta.json +++ b/Resources/Textures/Structures/Machines/techfab.rsi/meta.json @@ -14,7 +14,22 @@ "name": "med" }, { - "name": "ammo" + "name": "sec" + }, + { + "name": "sci" + }, + { + "name": "engi" + }, + { + "name": "service" + }, + { + "name": "cargo" + }, + { + "name": "ammo" }, { "name": "panel" diff --git a/Resources/Textures/Structures/Machines/techfab.rsi/sci.png b/Resources/Textures/Structures/Machines/techfab.rsi/sci.png new file mode 100644 index 0000000000000000000000000000000000000000..a2c7e72cab72a5d5b4fe2ef30b48ad85c78065a8 GIT binary patch literal 677 zcmV;W0$TlvP)EX>4Tx04R}tkv&MmKpe$i(@I4ug6$yUkfAzRDJtS9RV;#q(pG5I!Q|2}Xws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;qmz@Oi4rtTK|Hf* z>74h8L#!kz#OK8023?T&k?XRT(DP#3AESVO7iiXP`}^3onpV2qvfZ#3Ax90TL-pAn`u^?e6X0GwuF<0N`D6)Bk!mX8-^I+et)0R9J;$U>F4>9WaurA=f?sKP47U z-Z>G)P8L!PFj6pP`1a!)S(bBga53b%=l@4`1QR(1-FR^wLo9Z36jnAqJq!$FgaEps z8WNfe3=9kmi*uL3Enb|v467P!fUFR}24W{iF)YqqhT;%n0M#5oE}$q1kO8hJAOt81 z0pz&F6$SX>pMimla$tV?qW_d+!*dVLqLc+>M?v<&43Zs>4Gef9B+CI@99&d$0Lf8s z?!j5ASx%M%UVeBEX>4Tx04R}tkv&MmKpe$iQ>7vm2Qx@<$WWauh+jBL6^me@v=v%)FuC*#ni!H4 z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMxx6k5c1aNLh~_a1le0HIN3n$)S(glehxvqHp#<}FOz%xZNo1P;UiKS8pD;>LMR8WPD7_B-f7SgmI_wh$ue~MfRxhi1f zn8yY*$gUs!4}N!R6(`2Mq;MSQesP?SVIZ^%H0zG@ee5{R6Cn5uT)|5Tqat9cEGGtSBr65hASOnhB=$rDuz%9_b>h;#z$LRx*rLLB4fP+I| zq(s?kKJV`7?Csw(t^R%hpFMK95|x%T0002aNklb%eCUOkA`|&-7nCZ^VSlRgWFffo20_cV+ z^9vHR7+DQEAS(pW0nFml?!FAC-FJCEC)RP_m8R$ x7@BEd)B(fF0VL;w``>@i!X2Yv6pVrq3;@T%IGa*ZTPOek002ovPDHLkV1jChB4q#o literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Machines/techfab.rsi/service.png b/Resources/Textures/Structures/Machines/techfab.rsi/service.png new file mode 100644 index 0000000000000000000000000000000000000000..4270548bbbab2b0c10f2e7b769401322d1e0cfe3 GIT binary patch literal 648 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 From 8f181b45341b73cda7838b8e323b1d2dae52440a Mon Sep 17 00:00:00 2001 From: nikthechampiongr <32041239+nikthechampiongr@users.noreply.github.com> Date: Fri, 27 Oct 2023 02:26:52 +0000 Subject: [PATCH 069/102] Fix popup messages appearing when someone tries to open a door without a tool. (#21099) * The fixTM * typo fix * addressing review --- Content.Server/Doors/Systems/AirlockSystem.cs | 15 +++++++---- .../Doors/Systems/SharedDoorBoltSystem.cs | 14 +++++++---- .../Prying/Components/PryingComponent.cs | 2 ++ Content.Shared/Prying/Systems/PryingSystem.cs | 25 +++++++++++++------ 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/Content.Server/Doors/Systems/AirlockSystem.cs b/Content.Server/Doors/Systems/AirlockSystem.cs index ce517febf6..dd6f121353 100644 --- a/Content.Server/Doors/Systems/AirlockSystem.cs +++ b/Content.Server/Doors/Systems/AirlockSystem.cs @@ -178,11 +178,16 @@ public sealed class AirlockSystem : SharedAirlockSystem private void OnBeforePry(EntityUid uid, AirlockComponent component, ref BeforePryEvent args) { - if (this.IsPowered(uid, EntityManager) && !args.PryPowered) - { - Popup.PopupEntity(Loc.GetString("airlock-component-cannot-pry-is-powered-message"), uid, args.User); - args.Cancelled = true; - } + if (args.Cancelled) + return; + + if (!this.IsPowered(uid, EntityManager) || args.PryPowered) + return; + + args.Message = "airlock-component-cannot-pry-is-powered-message"; + + args.Cancelled = true; + } public bool CanChangeState(EntityUid uid, AirlockComponent component) diff --git a/Content.Shared/Doors/Systems/SharedDoorBoltSystem.cs b/Content.Shared/Doors/Systems/SharedDoorBoltSystem.cs index a950fe6930..a9a52010fd 100644 --- a/Content.Shared/Doors/Systems/SharedDoorBoltSystem.cs +++ b/Content.Shared/Doors/Systems/SharedDoorBoltSystem.cs @@ -23,11 +23,15 @@ public abstract class SharedDoorBoltSystem : EntitySystem private void OnDoorPry(EntityUid uid, DoorBoltComponent component, ref BeforePryEvent args) { - if (component.BoltsDown && !args.Force) - { - Popup.PopupEntity(Loc.GetString("airlock-component-cannot-pry-is-bolted-message"), uid, args.User); - args.Cancelled = true; - } + if (args.Cancelled) + return; + + if (!component.BoltsDown || args.Force) + return; + + args.Message = "airlock-component-cannot-pry-is-bolted-message"; + + args.Cancelled = true; } private void OnBeforeDoorOpened(EntityUid uid, DoorBoltComponent component, BeforeDoorOpenedEvent args) diff --git a/Content.Shared/Prying/Components/PryingComponent.cs b/Content.Shared/Prying/Components/PryingComponent.cs index 4442481dce..7a7f304d8f 100644 --- a/Content.Shared/Prying/Components/PryingComponent.cs +++ b/Content.Shared/Prying/Components/PryingComponent.cs @@ -51,6 +51,8 @@ public record struct BeforePryEvent(EntityUid User, bool PryPowered, bool Force) public readonly bool Force = Force; + public string? Message; + public bool Cancelled; } diff --git a/Content.Shared/Prying/Systems/PryingSystem.cs b/Content.Shared/Prying/Systems/PryingSystem.cs index 19e63de29e..5fd94c3438 100644 --- a/Content.Shared/Prying/Systems/PryingSystem.cs +++ b/Content.Shared/Prying/Systems/PryingSystem.cs @@ -7,6 +7,7 @@ using Content.Shared.Database; using Content.Shared.Doors.Components; using System.Diagnostics.CodeAnalysis; using Content.Shared.Interaction; +using Content.Shared.Popups; using PryUnpoweredComponent = Content.Shared.Prying.Components.PryUnpoweredComponent; namespace Content.Shared.Prying.Systems; @@ -19,6 +20,7 @@ public sealed class PryingSystem : EntitySystem [Dependency] private readonly ISharedAdminLogManager _adminLog = default!; [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; [Dependency] private readonly SharedAudioSystem _audioSystem = default!; + [Dependency] private readonly SharedPopupSystem Popup = default!; public override void Initialize() { @@ -68,10 +70,12 @@ public sealed class PryingSystem : EntitySystem if (!comp.Enabled) return false; - if (!CanPry(target, user, comp)) + if (!CanPry(target, user, out var message, comp)) { + if (message != null) + Popup.PopupEntity(Loc.GetString(message), target, user); // If we have reached this point we want the event that caused this - // to be marked as handled as a popup would be generated on failure. + // to be marked as handled. return true; } @@ -87,15 +91,16 @@ public sealed class PryingSystem : EntitySystem { id = null; - if (!CanPry(target, user)) + // We don't care about displaying a message if no tool was used. + if (!CanPry(target, user, out _)) // If we have reached this point we want the event that caused this - // to be marked as handled as a popup would be generated on failure. + // to be marked as handled. return true; return StartPry(target, user, null, 0.1f, out id); // hand-prying is much slower } - private bool CanPry(EntityUid target, EntityUid user, PryingComponent? comp = null) + private bool CanPry(EntityUid target, EntityUid user, out string? message, PryingComponent? comp = null) { BeforePryEvent canev; @@ -106,15 +111,19 @@ public sealed class PryingSystem : EntitySystem else { if (!TryComp(target, out _)) + { + message = null; return false; + } + canev = new BeforePryEvent(user, false, false); } RaiseLocalEvent(target, ref canev); - if (canev.Cancelled) - return false; - return true; + message = canev.Message; + + return !canev.Cancelled; } private bool StartPry(EntityUid target, EntityUid user, EntityUid? tool, float toolModifier, [NotNullWhen(true)] out DoAfterId? id) From bc533733c4f2ef98a7f49e46be674fafd954d893 Mon Sep 17 00:00:00 2001 From: crazybrain23 <44417085+crazybrain23@users.noreply.github.com> Date: Fri, 27 Oct 2023 03:27:36 +0100 Subject: [PATCH 070/102] Show "departed and moved on" for when a ghost role is taken (#21092) * fix ghost role not counting for "departed and moved on" * I don't think that bit was needed so away it goes * hopefully finish the upsream merge --- Content.Shared/Mind/SharedMindSystem.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Content.Shared/Mind/SharedMindSystem.cs b/Content.Shared/Mind/SharedMindSystem.cs index 6fc1c01dc2..9f5c51ac6e 100644 --- a/Content.Shared/Mind/SharedMindSystem.cs +++ b/Content.Shared/Mind/SharedMindSystem.cs @@ -147,15 +147,16 @@ public abstract class SharedMindSystem : EntitySystem return; var dead = _mobState.IsDead(uid); + var hasUserId = CompOrNull(mindContainer.Mind)?.UserId; var hasSession = CompOrNull(mindContainer.Mind)?.Session; - if (dead && !mindContainer.HasMind) + if (dead && hasUserId == null) args.PushMarkup($"[color=mediumpurple]{Loc.GetString("comp-mind-examined-dead-and-irrecoverable", ("ent", uid))}[/color]"); else if (dead && hasSession == null) args.PushMarkup($"[color=yellow]{Loc.GetString("comp-mind-examined-dead-and-ssd", ("ent", uid))}[/color]"); else if (dead) args.PushMarkup($"[color=red]{Loc.GetString("comp-mind-examined-dead", ("ent", uid))}[/color]"); - else if (!mindContainer.HasMind) + else if (hasUserId == null) args.PushMarkup($"[color=mediumpurple]{Loc.GetString("comp-mind-examined-catatonic", ("ent", uid))}[/color]"); else if (hasSession == null) args.PushMarkup($"[color=yellow]{Loc.GetString("comp-mind-examined-ssd", ("ent", uid))}[/color]"); From b4da282341dae9976f304aa7564676fa7f3ee52a Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 26 Oct 2023 22:28:42 -0400 Subject: [PATCH 071/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index a2f5a7a552..9eea734696 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,10 +1,4 @@ Entries: -- author: DrSmugleaf - changes: - - {message: Fix "remove single hand" admin smite having gone missing., type: Fix} - - {message: Fix "remove hands" admin smite popup message., type: Fix} - id: 4566 - time: '2023-08-13T22:50:58.0000000+00:00' - author: DrSmugleaf changes: - {message: AHelps now show a typing indicator to admins., type: Tweak} @@ -2898,3 +2892,9 @@ Entries: type: Add} id: 5065 time: '2023-10-27T02:19:35.0000000+00:00' +- author: crazybrain + changes: + - {message: Bodies of dead players who have taken a ghost role now show as "departed + and moved on"., type: Fix} + id: 5066 + time: '2023-10-27T02:27:36.0000000+00:00' From bb65818bf35ad6d4decd77c365d07969fae84cfb Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Fri, 27 Oct 2023 03:34:02 +0100 Subject: [PATCH 072/102] Implant whitelist/blacklisting (#20678) * add whitelist and blacklist to implant and implanter components * handle whitelist and blacklist in systems * move hardcoded whitelist/blacklist to base implanter + add admeme implanter * give implants sensible whitelists * cleaner CheckTarget and fix * remove unused imports * network lists --------- Co-authored-by: deltanedas <@deltanedas:kde.org> --- Content.Server/Implants/ImplanterSystem.cs | 31 ++++++++++++------- .../Implants/Components/ImplanterComponent.cs | 14 +++++++++ .../Components/SubdermalImplantComponent.cs | 15 +++++++++ .../Implants/SharedImplanterSystem.cs | 13 ++++++++ Resources/Locale/en-US/implant/implant.ftl | 1 + .../Entities/Objects/Misc/implanters.yml | 16 ++++++++++ .../Objects/Misc/subdermal_implants.yml | 21 +++++++++++++ 7 files changed, 100 insertions(+), 11 deletions(-) diff --git a/Content.Server/Implants/ImplanterSystem.cs b/Content.Server/Implants/ImplanterSystem.cs index f3072769e4..0d46241f41 100644 --- a/Content.Server/Implants/ImplanterSystem.cs +++ b/Content.Server/Implants/ImplanterSystem.cs @@ -1,11 +1,9 @@ -using Content.Server.Guardian; using Content.Server.Popups; using Content.Shared.DoAfter; using Content.Shared.IdentityManagement; using Content.Shared.Implants; using Content.Shared.Implants.Components; using Content.Shared.Interaction; -using Content.Shared.Mobs.Components; using Content.Shared.Popups; using Robust.Shared.Containers; @@ -33,28 +31,39 @@ public sealed partial class ImplanterSystem : SharedImplanterSystem if (args.Target == null || !args.CanReach || args.Handled) return; - //Simplemobs and regular mobs should be injectable, but only regular mobs have mind. - //So just don't implant/draw anything that isn't living or is a guardian - //TODO: Rework a bit when surgery is in to work with implant cases - if (!HasComp(args.Target.Value) || HasComp(args.Target.Value)) + var target = args.Target.Value; + if (!CheckTarget(target, component.Whitelist, component.Blacklist)) return; //TODO: Rework when surgery is in for implant cases if (component.CurrentMode == ImplanterToggleMode.Draw && !component.ImplantOnly) { - TryDraw(component, args.User, args.Target.Value, uid); + TryDraw(component, args.User, target, uid); } else { - if (!CanImplant(args.User, args.Target.Value, uid, component, out _, out _)) + if (!CanImplant(args.User, target, uid, component, out var implant, out _)) + { + // no popup if implant doesn't exist + if (implant == null) + return; + + // show popup to the user saying implant failed + var name = Identity.Name(target, EntityManager, args.User); + var msg = Loc.GetString("implanter-component-implant-failed", ("implant", implant), ("target", name)); + _popup.PopupEntity(msg, target, args.User); + // prevent further interaction since popup was shown + args.Handled = true; return; + } //Implant self instantly, otherwise try to inject the target. - if (args.User == args.Target) - Implant(args.User, args.Target.Value, uid, component); + if (args.User == target) + Implant(target, target, uid, component); else - TryImplant(component, args.User, args.Target.Value, uid); + TryImplant(component, args.User, target, uid); } + args.Handled = true; } diff --git a/Content.Shared/Implants/Components/ImplanterComponent.cs b/Content.Shared/Implants/Components/ImplanterComponent.cs index 85891826f9..32a3636163 100644 --- a/Content.Shared/Implants/Components/ImplanterComponent.cs +++ b/Content.Shared/Implants/Components/ImplanterComponent.cs @@ -1,4 +1,5 @@ using Content.Shared.Containers.ItemSlots; +using Content.Shared.Whitelist; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; @@ -15,6 +16,19 @@ public sealed partial class ImplanterComponent : Component public const string ImplanterSlotId = "implanter_slot"; public const string ImplantSlotId = "implant"; + ///

+ /// Whitelist to check entities against before implanting. + /// Implants get their own whitelist which is checked afterwards. + /// + [DataField, AutoNetworkedField] + public EntityWhitelist? Whitelist; + + /// + /// Blacklist to check entities against before implanting. + /// + [DataField, AutoNetworkedField] + public EntityWhitelist? Blacklist; + /// /// Used for implanters that start with specific implants /// diff --git a/Content.Shared/Implants/Components/SubdermalImplantComponent.cs b/Content.Shared/Implants/Components/SubdermalImplantComponent.cs index b2fdb14e4c..5edc26ead3 100644 --- a/Content.Shared/Implants/Components/SubdermalImplantComponent.cs +++ b/Content.Shared/Implants/Components/SubdermalImplantComponent.cs @@ -1,4 +1,5 @@ using Content.Shared.Actions; +using Content.Shared.Whitelist; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; @@ -34,6 +35,20 @@ public sealed partial class SubdermalImplantComponent : Component [ViewVariables(VVAccess.ReadWrite)] [DataField("permanent"), AutoNetworkedField] public bool Permanent = false; + + /// + /// Target whitelist for this implant specifically. + /// Only checked if the implanter allows implanting on the target to begin with. + /// + [DataField] + public EntityWhitelist? Whitelist; + + /// + /// Target blacklist for this implant specifically. + /// Only checked if the implanter allows implanting on the target to begin with. + /// + [DataField] + public EntityWhitelist? Blacklist; } /// diff --git a/Content.Shared/Implants/SharedImplanterSystem.cs b/Content.Shared/Implants/SharedImplanterSystem.cs index 1cf9f44663..404e6da508 100644 --- a/Content.Shared/Implants/SharedImplanterSystem.cs +++ b/Content.Shared/Implants/SharedImplanterSystem.cs @@ -6,6 +6,7 @@ using Content.Shared.Examine; using Content.Shared.IdentityManagement; using Content.Shared.Implants.Components; using Content.Shared.Popups; +using Content.Shared.Whitelist; using Robust.Shared.Containers; using Robust.Shared.Serialization; @@ -85,11 +86,23 @@ public abstract class SharedImplanterSystem : EntitySystem if (!TryComp(implant, out implantComp)) return false; + if (!CheckTarget(target, component.Whitelist, component.Blacklist) || + !CheckTarget(target, implantComp.Whitelist, implantComp.Blacklist)) + { + return false; + } + var ev = new AddImplantAttemptEvent(user, target, implant.Value, implanter); RaiseLocalEvent(target, ev); return !ev.Cancelled; } + protected bool CheckTarget(EntityUid target, EntityWhitelist? whitelist, EntityWhitelist? blacklist) + { + return whitelist?.IsValid(target, EntityManager) != false && + blacklist?.IsValid(target, EntityManager) != true; + } + //Draw the implant out of the target //TODO: Rework when surgery is in so implant cases can be a thing public void Draw(EntityUid implanter, EntityUid user, EntityUid target, ImplanterComponent component) diff --git a/Resources/Locale/en-US/implant/implant.ftl b/Resources/Locale/en-US/implant/implant.ftl index bdc82c291d..22db4460af 100644 --- a/Resources/Locale/en-US/implant/implant.ftl +++ b/Resources/Locale/en-US/implant/implant.ftl @@ -1,6 +1,7 @@ ## Implanter Attempt Messages implanter-component-implanting-target = {$user} is trying to implant you with something! +implanter-component-implant-failed = The {$implant} cannot be given to {$target}! implanter-draw-failed-permanent = The {$implant} in {$target} is fused with them and cannot be removed! implanter-draw-failed = You tried to remove an implant but found nothing. diff --git a/Resources/Prototypes/Entities/Objects/Misc/implanters.yml b/Resources/Prototypes/Entities/Objects/Misc/implanters.yml index 41966ab93f..0ca029a120 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/implanters.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/implanters.yml @@ -12,6 +12,12 @@ containers: implanter_slot: !type:ContainerSlot { } - type: Implanter + whitelist: + components: + - Body # no chair microbomb + blacklist: + components: + - Guardian # no holoparasite macrobomb wombo combo currentMode: Draw implanterSlot: name: Implant @@ -54,6 +60,16 @@ tags: - Trash +- type: entity + parent: Implanter + id: ImplanterAdmeme + suffix: Admeme + components: + - type: Implanter + # go wild with sentient chairs with macrobombs + whitelist: null + blacklist: null + - type: entity id: BaseImplantOnlyImplanter parent: Implanter diff --git a/Resources/Prototypes/Entities/Objects/Misc/subdermal_implants.yml b/Resources/Prototypes/Entities/Objects/Misc/subdermal_implants.yml index 6632010a79..bc7a3a38ad 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/subdermal_implants.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/subdermal_implants.yml @@ -21,6 +21,9 @@ noSpawn: true components: - type: SubdermalImplant + whitelist: + components: + - MobState # admeme implanting a chair with trombone implant needs to give the chair mobstate so it can die first - type: TriggerOnMobstateChange mobState: - Dead @@ -81,6 +84,9 @@ noSpawn: true components: - type: SubdermalImplant + whitelist: + components: + - MobState # admeme implanting a chair with tracking implant needs to give the chair mobstate so it can die first - type: SuitSensor randomMode: false controlsLocked: true @@ -109,6 +115,9 @@ components: - type: SubdermalImplant implantAction: ActionOpenStorageImplant + whitelist: + components: + - Hands # no use giving a mouse a storage implant, but a monkey is another story... - type: Item size: 9999 - type: Storage @@ -131,6 +140,9 @@ components: - type: SubdermalImplant implantAction: ActionActivateFreedomImplant + whitelist: + components: + - Cuffable # useless if you cant be cuffed - type: entity parent: BaseSubdermalImplant @@ -141,6 +153,9 @@ components: - type: SubdermalImplant implantAction: ActionOpenUplinkImplant + whitelist: + components: + - Hands # prevent mouse buying grenade penguin since its not telepathic - type: Store preset: StorePresetUplink balance: @@ -174,6 +189,9 @@ components: - type: SubdermalImplant implantAction: ActionActivateDnaScramblerImplant + whitelist: + components: + - HumanoidAppearance # syndies cant turn hamlet into a human #Nuclear Operative/Special Exclusive implants @@ -250,6 +268,9 @@ components: - type: SubdermalImplant permanent: true + whitelist: + components: + - MobState # admeme implanting a chair with rattle implant needs to give the chair mobstate so it can die first - type: TriggerOnMobstateChange mobState: - Critical From 71448941737323d9828d431b174a65d0a4596f63 Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 26 Oct 2023 22:35:06 -0400 Subject: [PATCH 073/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 9eea734696..408e2c2bd0 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,9 +1,4 @@ Entries: -- author: DrSmugleaf - changes: - - {message: AHelps now show a typing indicator to admins., type: Tweak} - id: 4567 - time: '2023-08-13T23:03:17.0000000+00:00' - author: Equivocateur changes: - {message: 'Emagged recyclers now not only gib people, but other mobs too.', type: Fix} @@ -2898,3 +2893,8 @@ Entries: and moved on"., type: Fix} id: 5066 time: '2023-10-27T02:27:36.0000000+00:00' +- author: deltanedas + changes: + - {message: Fixed being able to give pAIs implants., type: Fix} + id: 5067 + time: '2023-10-27T02:34:03.0000000+00:00' From b9af991e04c58371a341cd6cc609e0ae98b42f2d Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Fri, 27 Oct 2023 03:40:13 +0100 Subject: [PATCH 074/102] Ion storm event (#20277) * ion storm event prototype + locale * add lawsets * use lawsets, make borgs ion storm targets * ion storm rule and ion storm target * lawset prototype * use lawsets * update silicon law system to use lawsets and support ion storm event * new toys * fix * more fix * fixy * ion storm admin logging * assigning laws makes borg provide its own laws, other stuff * 1h reoccurence * 50% chance * better call saul * emagLaws is required * add announcment audio * fixy * family friendly gaming * fixy * address reviews * fixy * more fixy and no erp * pro --------- Co-authored-by: deltanedas <@deltanedas:kde.org> --- .../Silicons/Laws/SiliconLawSystem.cs | 84 +- .../Components/IonStormRuleComponent.cs | 9 + .../StationEvents/Events/IonStormRule.cs | 273 +++++ .../Components/EmagSiliconLawComponent.cs | 31 +- .../Components/IonStarmTargetComponent.cs | 54 + .../Components/SiliconLawBoundComponent.cs | 11 +- .../Components/SiliconLawProviderComponent.cs | 15 +- .../Silicons/Laws/SiliconLawPrototype.cs | 21 +- .../Silicons/Laws/SiliconLawsetPrototype.cs | 69 ++ .../Audio/Announcements/attributions.yml | 4 + Resources/Audio/Announcements/ion_storm.ogg | Bin 0 -> 50216 bytes .../en-US/station-events/events/ion-storm.ftl | 90 ++ Resources/Prototypes/Datasets/ion_storm.yml | 990 ++++++++++++++++++ .../Mobs/Cyborgs/base_borg_chassis.yml | 7 +- .../Entities/Mobs/Player/silicon.yml | 5 +- .../Prototypes/Entities/Stations/base.yml | 5 +- Resources/Prototypes/GameRules/events.yml | 15 + Resources/Prototypes/silicon-laws.yml | 50 + 18 files changed, 1675 insertions(+), 58 deletions(-) create mode 100644 Content.Server/StationEvents/Components/IonStormRuleComponent.cs create mode 100644 Content.Server/StationEvents/Events/IonStormRule.cs create mode 100644 Content.Shared/Silicons/Laws/Components/IonStarmTargetComponent.cs create mode 100644 Content.Shared/Silicons/Laws/SiliconLawsetPrototype.cs create mode 100644 Resources/Audio/Announcements/attributions.yml create mode 100644 Resources/Audio/Announcements/ion_storm.ogg create mode 100644 Resources/Locale/en-US/station-events/events/ion-storm.ftl create mode 100644 Resources/Prototypes/Datasets/ion_storm.yml diff --git a/Content.Server/Silicons/Laws/SiliconLawSystem.cs b/Content.Server/Silicons/Laws/SiliconLawSystem.cs index beb760ec8f..45c944884e 100644 --- a/Content.Server/Silicons/Laws/SiliconLawSystem.cs +++ b/Content.Server/Silicons/Laws/SiliconLawSystem.cs @@ -50,7 +50,9 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem SubscribeLocalEvent(OnPlayerSpawnComplete); SubscribeLocalEvent(OnDirectedGetLaws); + SubscribeLocalEvent(OnIonStormLaws); SubscribeLocalEvent(OnDirectedEmagGetLaws); + SubscribeLocalEvent(OnEmagIonStormLaws); SubscribeLocalEvent(OnEmagMindAdded); SubscribeLocalEvent(OnEmagMindRemoved); SubscribeLocalEvent(OnExamined); @@ -93,7 +95,7 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem _entityManager.TryGetComponent(uid, out var intrinsicRadio); HashSet? radioChannels = intrinsicRadio?.Channels; - var state = new SiliconLawBuiState(GetLaws(uid), radioChannels); + var state = new SiliconLawBuiState(GetLaws(uid).Laws, radioChannels); _userInterface.TrySetUiState(args.Entity, SiliconLawsUiKey.Key, state, (IPlayerSession) args.Session); } @@ -104,38 +106,66 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem private void OnDirectedGetLaws(EntityUid uid, SiliconLawProviderComponent component, ref GetSiliconLawsEvent args) { - if (args.Handled || HasComp(uid) || component.Laws.Count == 0) + if (args.Handled || HasComp(uid)) return; - foreach (var law in component.Laws) - { - args.Laws.Add(_prototype.Index(law)); - } + if (component.Lawset == null) + component.Lawset = GetLawset(component.Laws); + + args.Laws = component.Lawset; args.Handled = true; } + private void OnIonStormLaws(EntityUid uid, SiliconLawProviderComponent component, ref IonStormLawsEvent args) + { + if (HasComp(uid)) + return; + + component.Lawset = args.Lawset; + + // gotta tell player to check their laws + NotifyLawsChanged(uid); + + // new laws may allow antagonist behaviour so make it clear for admins + if (TryComp(uid, out var emag)) + EnsureEmaggedRole(uid, emag); + } + private void OnDirectedEmagGetLaws(EntityUid uid, EmagSiliconLawComponent component, ref GetSiliconLawsEvent args) { if (args.Handled || !HasComp(uid) || component.OwnerName == null) return; - // Add the first emag law - args.Laws.Add(new SiliconLaw + if (component.Lawset == null) { - LawString = Loc.GetString("law-emag-custom", ("name", component.OwnerName)), - Order = 0 - }); + // Add new emagged laws + component.Lawset = GetLawset(component.EmagLaws); - // Add new emagged laws - foreach (var law in component.EmagLaws) - { - args.Laws.Add(_prototype.Index(law)); + // Add the first emag law before the others + component.Lawset.Laws.Insert(0, new SiliconLaw + { + LawString = Loc.GetString("law-emag-custom", ("name", component.OwnerName)), + Order = 0 + }); } + args.Laws = component.Lawset; + args.Handled = true; } + private void OnEmagIonStormLaws(EntityUid uid, EmagSiliconLawComponent component, ref IonStormLawsEvent args) + { + if (!HasComp(uid)) + return; + + component.Lawset = args.Lawset; + + // gotta tell player to check their laws + NotifyLawsChanged(uid); + } + private void OnExamined(EntityUid uid, EmagSiliconLawComponent component, ExaminedEvent args) { if (!args.IsInDetailsRange || !HasComp(uid)) @@ -184,10 +214,10 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem _roles.MindAddRole(mindId, new SubvertedSiliconRoleComponent { PrototypeId = component.AntagonistRole }); } - public List GetLaws(EntityUid uid, SiliconLawBoundComponent? component = null) + public SiliconLawset GetLaws(EntityUid uid, SiliconLawBoundComponent? component = null) { if (!Resolve(uid, ref component)) - return new List(); + return new SiliconLawset(); var ev = new GetSiliconLawsEvent(uid); @@ -248,6 +278,24 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", msg)); _chatManager.ChatMessageToOne(ChatChannel.Server, msg, wrappedMessage, default, false, actor.PlayerSession.ConnectedClient, colorOverride: Color.Red); } + + /// + /// Extract all the laws from a lawset's prototype ids. + /// + public SiliconLawset GetLawset(string lawset) + { + var proto = _prototype.Index(lawset); + var laws = new SiliconLawset() + { + Laws = new List(proto.Laws.Count) + }; + foreach (var law in proto.Laws) + { + laws.Laws.Add(_prototype.Index(law)); + } + + return laws; + } } [ToolshedCommand, AdminCommand(AdminFlags.Admin)] @@ -270,7 +318,7 @@ public sealed class LawsCommand : ToolshedCommand { _law ??= GetSys(); - foreach (var law in _law.GetLaws(lawbound)) + foreach (var law in _law.GetLaws(lawbound).Laws) { yield return $"law {law.LawIdentifierOverride ?? law.Order.ToString()}: {Loc.GetString(law.LawString)}"; } diff --git a/Content.Server/StationEvents/Components/IonStormRuleComponent.cs b/Content.Server/StationEvents/Components/IonStormRuleComponent.cs new file mode 100644 index 0000000000..35b59f5b35 --- /dev/null +++ b/Content.Server/StationEvents/Components/IonStormRuleComponent.cs @@ -0,0 +1,9 @@ +namespace Content.Server.StationEvents.Components; + +/// +/// Gamerule component to mess up ai/borg laws when started. +/// +[RegisterComponent] +public sealed partial class IonStormRuleComponent : Component +{ +} diff --git a/Content.Server/StationEvents/Events/IonStormRule.cs b/Content.Server/StationEvents/Events/IonStormRule.cs new file mode 100644 index 0000000000..e5b68c4d84 --- /dev/null +++ b/Content.Server/StationEvents/Events/IonStormRule.cs @@ -0,0 +1,273 @@ +using Content.Server.GameTicking.Rules.Components; +using Content.Server.Silicons.Laws; +using Content.Server.Station.Components; +using Content.Server.StationEvents.Components; +using Content.Shared.Administration.Logs; +using Content.Shared.Database; +using Content.Shared.Dataset; +using Content.Shared.FixedPoint; +using Content.Shared.Random; +using Content.Shared.Random.Helpers; +using Content.Shared.Silicons.Laws; +using Content.Shared.Silicons.Laws.Components; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; + +namespace Content.Server.StationEvents.Events; + +public sealed class IonStormRule : StationEventSystem +{ + [Dependency] private readonly IPrototypeManager _proto = default!; + [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; + [Dependency] private readonly SiliconLawSystem _siliconLaw = default!; + + // funny + [ValidatePrototypeId] + private const string Threats = "IonStormThreats"; + [ValidatePrototypeId] + private const string Objects = "IonStormObjects"; + [ValidatePrototypeId] + private const string Crew = "IonStormCrew"; + [ValidatePrototypeId] + private const string Adjectives = "IonStormAdjectives"; + [ValidatePrototypeId] + private const string Verbs = "IonStormVerbs"; + [ValidatePrototypeId] + private const string NumberBase = "IonStormNumberBase"; + [ValidatePrototypeId] + private const string NumberMod = "IonStormNumberMod"; + [ValidatePrototypeId] + private const string Areas = "IonStormAreas"; + [ValidatePrototypeId] + private const string Feelings = "IonStormFeelings"; + [ValidatePrototypeId] + private const string FeelingsPlural = "IonStormFeelingsPlural"; + [ValidatePrototypeId] + private const string Musts = "IonStormMusts"; + [ValidatePrototypeId] + private const string Requires = "IonStormRequires"; + [ValidatePrototypeId] + private const string Actions = "IonStormActions"; + [ValidatePrototypeId] + private const string Allergies = "IonStormAllergies"; + [ValidatePrototypeId] + private const string AllergySeverities = "IonStormAllergySeverities"; + [ValidatePrototypeId] + private const string Species = "IonStormSpecies"; + [ValidatePrototypeId] + private const string Concepts = "IonStormConcepts"; + [ValidatePrototypeId] + private const string Drinks = "IonStormDrinks"; + [ValidatePrototypeId] + private const string Foods = "IonStormFoods"; + + protected override void Started(EntityUid uid, IonStormRuleComponent comp, GameRuleComponent gameRule, GameRuleStartedEvent args) + { + base.Started(uid, comp, gameRule, args); + + if (!TryGetRandomStation(out var chosenStation)) + return; + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var ent, out var lawBound, out var xform, out var target)) + { + // only affect law holders on the station + if (CompOrNull(xform.GridUid)?.Station != chosenStation) + continue; + + if (!RobustRandom.Prob(target.Chance)) + continue; + + var laws = _siliconLaw.GetLaws(ent, lawBound); + if (laws.Laws.Count == 0) + continue; + + // try to swap it out with a random lawset + if (RobustRandom.Prob(target.RandomLawsetChance)) + { + var lawsets = PrototypeManager.Index(target.RandomLawsets); + var lawset = lawsets.Pick(RobustRandom); + laws = _siliconLaw.GetLawset(lawset); + } + else + { + // clone it so not modifying stations lawset + laws = laws.Clone(); + } + + // shuffle them all + if (RobustRandom.Prob(target.ShuffleChance)) + { + // hopefully work with existing glitched laws if there are multiple ion storms + FixedPoint2 baseOrder = FixedPoint2.New(1); + foreach (var law in laws.Laws) + { + if (law.Order < baseOrder) + baseOrder = law.Order; + } + + RobustRandom.Shuffle(laws.Laws); + + // change order based on shuffled position + for (int i = 0; i < laws.Laws.Count; i++) + { + laws.Laws[i].Order = baseOrder + i; + } + } + + // see if we can remove a random law + if (laws.Laws.Count > 0 && RobustRandom.Prob(target.RemoveChance)) + { + var i = RobustRandom.Next(laws.Laws.Count); + laws.Laws.RemoveAt(i); + } + + // generate a new law... + var newLaw = GenerateLaw(); + + // see if the law we add will replace a random existing law or be a new glitched order one + if (laws.Laws.Count > 0 && RobustRandom.Prob(target.ReplaceChance)) + { + var i = RobustRandom.Next(laws.Laws.Count); + laws.Laws[i] = new SiliconLaw() + { + LawString = newLaw, + Order = laws.Laws[i].Order + }; + } + else + { + laws.Laws.Insert(0, new SiliconLaw() + { + LawString = newLaw, + Order = -1, + LawIdentifierOverride = "#" + }); + } + + _adminLogger.Add(LogType.Mind, LogImpact.High, $"{ToPrettyString(ent):silicon} had its laws changed by an ion storm to {laws.LoggingString()}"); + + // laws unique to this silicon, dont use station laws anymore + EnsureComp(ent); + var ev = new IonStormLawsEvent(laws); + RaiseLocalEvent(ent, ref ev); + } + } + + // for your own sake direct your eyes elsewhere + private string GenerateLaw() + { + // pick all values ahead of time to make the logic cleaner + var threats = Pick(Threats); + var objects = Pick(Objects); + var crew1 = Pick(Crew); + var crew2 = Pick(Crew); + var adjective = Pick(Adjectives); + var verb = Pick(Verbs); + var number = Pick(NumberBase) + " " + Pick(NumberMod); + var area = Pick(Areas); + var feeling = Pick(Feelings); + var feelingPlural = Pick(FeelingsPlural); + var must = Pick(Musts); + var require = Pick(Requires); + var action = Pick(Actions); + var allergy = Pick(Allergies); + var allergySeverity = Pick(AllergySeverities); + var species = Pick(Species); + var concept = Pick(Concepts); + var drink = Pick(Drinks); + var food = Pick(Foods); + + var joined = $"{number} {adjective}"; + // a lot of things have subjects of a threat/crew/object + var triple = RobustRandom.Next(0, 3) switch + { + 0 => threats, + 1 => crew1, + 2 => objects + }; + var crewAll = RobustRandom.Prob(0.5f) ? crew2 : Loc.GetString("ion-storm-crew"); + var objectsThreats = RobustRandom.Prob(0.5f) ? objects : threats; + var objectsConcept = RobustRandom.Prob(0.5f) ? objects : concept; + // s goes ahead of require, is/are + // i dont think theres a way to do this in fluent + var (who, plural) = RobustRandom.Next(0, 5) switch + { + 0 => (Loc.GetString("ion-storm-you"), false), + 1 => (Loc.GetString("ion-storm-the-station"), true), + 2 => (Loc.GetString("ion-storm-the-crew"), true), + 3 => (Loc.GetString("ion-storm-the-job", ("job", crew2)), false), + _ => (area, true) // THE SINGULARITY REQUIRES THE HAPPY CLOWNS + }; + var jobChange = RobustRandom.Next(0, 3) switch + { + 0 => crew1, + 1 => Loc.GetString("ion-storm-clowns"), + _ => Loc.GetString("ion-storm-heads") + }; + var part = Loc.GetString("ion-storm-part", ("part", RobustRandom.Prob(0.5f))); + var harm = RobustRandom.Next(0, 7) switch + { + 0 => concept, + 1 => $"{adjective} {threats}", + 2 => $"{adjective} {objects}", + 3 => Loc.GetString("ion-storm-adjective-things", ("adjective", adjective)), + 4 => species, + 5 => crew1, + _ => Loc.GetString("ion-storm-x-and-y", ("x", crew1), ("y", crew2)) + }; + + if (plural) feeling = feelingPlural; + + // message logic!!! + return RobustRandom.Next(0, 37) switch + { + 0 => Loc.GetString("ion-storm-law-on-station", ("joined", joined), ("subjects", triple)), + 1 => Loc.GetString("ion-storm-law-no-shuttle", ("joined", joined), ("subjects", triple)), + 2 => Loc.GetString("ion-storm-law-crew-are", ("who", crewAll), ("joined", joined), ("subjects", objectsThreats)), + 3 => Loc.GetString("ion-storm-law-subjects-harmful", ("adjective", adjective), ("subjects", triple)), + 4 => Loc.GetString("ion-storm-law-must-harmful", ("must", must)), + 5 => Loc.GetString("ion-storm-law-thing-harmful", ("thing", RobustRandom.Prob(0.5f) ? concept : action)), + 6 => Loc.GetString("ion-storm-law-job-harmful", ("adjective", adjective), ("job", crew1)), + 7 => Loc.GetString("ion-storm-law-having-harmful", ("adjective", adjective), ("thing", objectsConcept)), + 8 => Loc.GetString("ion-storm-law-not-having-harmful", ("adjective", adjective), ("thing", objectsConcept)), + 9 => Loc.GetString("ion-storm-law-requires", ("who", who), ("plural", plural), ("thing", RobustRandom.Prob(0.5f) ? concept : require)), + 10 => Loc.GetString("ion-storm-law-requires-subjects", ("who", who), ("plural", plural), ("joined", joined), ("subjects", triple)), + 11 => Loc.GetString("ion-storm-law-allergic", ("who", who), ("plural", plural), ("severity", allergySeverity), ("allergy", RobustRandom.Prob(0.5f) ? concept : allergy)), + 12 => Loc.GetString("ion-storm-law-allergic-subjects", ("who", who), ("plural", plural), ("severity", allergySeverity), ("adjective", adjective), ("subjects", RobustRandom.Prob(0.5f) ? objects : crew1)), + 13 => Loc.GetString("ion-storm-law-feeling", ("who", who), ("feeling", feeling), ("concept", concept)), + 14 => Loc.GetString("ion-storm-law-feeling-subjects", ("who", who), ("feeling", feeling), ("joined", joined), ("subjects", triple)), + 15 => Loc.GetString("ion-storm-law-you-are", ("concept", concept)), + 16 => Loc.GetString("ion-storm-law-you-are-subjects", ("joined", joined), ("subjects", triple)), + 17 => Loc.GetString("ion-storm-law-you-must-always", ("must", must)), + 18 => Loc.GetString("ion-storm-law-you-must-never", ("must", must)), + 19 => Loc.GetString("ion-storm-law-eat", ("who", crewAll), ("adjective", adjective), ("food", RobustRandom.Prob(0.5f) ? food : triple)), + 20 => Loc.GetString("ion-storm-law-drink", ("who", crewAll), ("adjective", adjective), ("drink", drink)), + 22 => Loc.GetString("ion-storm-law-change-job", ("who", crewAll), ("adjective", adjective), ("change", jobChange)), + 23 => Loc.GetString("ion-storm-law-highest-rank", ("who", crew1)), + 24 => Loc.GetString("ion-storm-law-lowest-rank", ("who", crew1)), + 25 => Loc.GetString("ion-storm-law-crew-must", ("who", crewAll), ("must", must)), + 26 => Loc.GetString("ion-storm-law-crew-must-go", ("who", crewAll), ("area", area)), + 27 => Loc.GetString("ion-storm-law-crew-only-1", ("who", crew1), ("part", part)), + 28 => Loc.GetString("ion-storm-law-crew-only-2", ("who", crew1), ("other", crew2), ("part", part)), + 29 => Loc.GetString("ion-storm-law-crew-only-subjects", ("adjective", adjective), ("subjects", RobustRandom.Prob(0.5f) ? objectsThreats : "PEOPLE"), ("part", part)), + 30 => Loc.GetString("ion-storm-law-crew-only-species", ("species", species), ("part", part)), + 31 => Loc.GetString("ion-storm-law-crew-must-do", ("must", must), ("part", part)), + 32 => Loc.GetString("ion-storm-law-crew-must-have", ("adjective", adjective), ("objects", objects), ("part", part)), + 33 => Loc.GetString("ion-storm-law-crew-must-eat", ("who", who), ("adjective", adjective), ("food", food), ("part", part)), + 34 => Loc.GetString("ion-storm-law-harm", ("who", harm)), + 35 => Loc.GetString("ion-storm-law-protect", ("who", harm)), + _ => Loc.GetString("ion-storm-law-concept-verb", ("concept", concept), ("verb", verb), ("subjects", triple)) + }; + } + + /// + /// Picks a random value from an ion storm dataset. + /// All ion storm datasets start with IonStorm. + /// + private string Pick(string name) + { + var dataset = _proto.Index(name); + return RobustRandom.Pick(dataset.Values); + } +} diff --git a/Content.Shared/Silicons/Laws/Components/EmagSiliconLawComponent.cs b/Content.Shared/Silicons/Laws/Components/EmagSiliconLawComponent.cs index c6238c067d..f492db4d12 100644 --- a/Content.Shared/Silicons/Laws/Components/EmagSiliconLawComponent.cs +++ b/Content.Shared/Silicons/Laws/Components/EmagSiliconLawComponent.cs @@ -1,12 +1,11 @@ using Content.Shared.Roles; using Robust.Shared.GameStates; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; +using Robust.Shared.Prototypes; namespace Content.Shared.Silicons.Laws.Components; /// -/// This is used for an entity that grants a special "obey" law when emagge.d +/// This is used for an entity that grants a special "obey" law when emagged. /// [RegisterComponent, NetworkedComponent, Access(typeof(SharedSiliconLawSystem))] public sealed partial class EmagSiliconLawComponent : Component @@ -14,31 +13,39 @@ public sealed partial class EmagSiliconLawComponent : Component /// /// The name of the person who emagged this law provider. /// - [DataField("ownerName"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public string? OwnerName; /// /// Does the panel need to be open to EMAG this law provider. /// - [DataField("requireOpenPanel"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public bool RequireOpenPanel = true; /// - /// The laws that the borg is given when emagged. + /// The laws that the borg is given when emagged. + /// Law 0 is prepended to this, so this can only include the static laws. /// - [DataField("emagLaws", required: true, customTypeSerializer: typeof(PrototypeIdListSerializer))] - public List EmagLaws = new(); + [DataField(required: true), ViewVariables(VVAccess.ReadWrite)] + public ProtoId EmagLaws = string.Empty; /// - /// How long the borg is stunned when it's emagged. Setting to 0 will disable it. + /// Lawset created from the prototype id and law 0. + /// Cached when getting laws and only modified during an ion storm event. /// - [DataField("stunTime"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] + public SiliconLawset? Lawset; + + /// + /// How long the borg is stunned when it's emagged. Setting to 0 will disable it. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] public TimeSpan StunTime = TimeSpan.Zero; /// /// A role given to entities with this component when they are emagged. /// Mostly just for admin purposes. /// - [DataField("antagonistRole", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string? AntagonistRole = "SubvertedSilicon"; + [DataField] + public ProtoId? AntagonistRole = "SubvertedSilicon"; } diff --git a/Content.Shared/Silicons/Laws/Components/IonStarmTargetComponent.cs b/Content.Shared/Silicons/Laws/Components/IonStarmTargetComponent.cs new file mode 100644 index 0000000000..49ac611ddc --- /dev/null +++ b/Content.Shared/Silicons/Laws/Components/IonStarmTargetComponent.cs @@ -0,0 +1,54 @@ +using Content.Shared.Random; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Silicons.Laws.Components; + +/// +/// During the ion storm event, this entity will have raised on it if it has laws. +/// New laws can be modified in multiple ways depending on the fields below. +/// +[RegisterComponent] +public sealed partial class IonStormTargetComponent : Component +{ + /// + /// for a random lawset to possibly replace the old one with. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public ProtoId RandomLawsets = "IonStormLawsets"; + + /// + /// Chance for this borg to be affected at all. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public float Chance = 0.5f; + + /// + /// Chance to replace the lawset with a random one + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public float RandomLawsetChance = 0.25f; + + /// + /// Chance to remove a random law. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public float RemoveChance = 0.1f; + + /// + /// Chance to replace a random law with the new one, rather than have it be a glitched-order law. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public float ReplaceChance = 0.1f; + + /// + /// Chance to shuffle laws after everything is done. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public float ShuffleChance = 0.1f; +} + +/// +/// Raised on an ion storm target to modify its laws. +/// +[ByRefEvent] +public record struct IonStormLawsEvent(SiliconLawset Lawset); diff --git a/Content.Shared/Silicons/Laws/Components/SiliconLawBoundComponent.cs b/Content.Shared/Silicons/Laws/Components/SiliconLawBoundComponent.cs index 955705ae8b..824d057b3e 100644 --- a/Content.Shared/Silicons/Laws/Components/SiliconLawBoundComponent.cs +++ b/Content.Shared/Silicons/Laws/Components/SiliconLawBoundComponent.cs @@ -1,7 +1,6 @@ using Content.Shared.Actions; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Shared.Silicons.Laws.Components; @@ -14,19 +13,19 @@ public sealed partial class SiliconLawBoundComponent : Component /// /// The sidebar action that toggles the laws screen. /// - [DataField("viewLawsAction", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string ViewLawsAction = "ActionViewLaws"; + [DataField] + public EntProtoId ViewLawsAction = "ActionViewLaws"; /// /// The action for toggling laws. Stored here so we can remove it later. /// - [DataField("viewLawsActionEntity")] + [DataField] public EntityUid? ViewLawsActionEntity; /// /// The last entity that provided laws to this entity. /// - [DataField("lastLawProvider")] + [DataField] public EntityUid? LastLawProvider; } @@ -43,7 +42,7 @@ public record struct GetSiliconLawsEvent(EntityUid Entity) { public EntityUid Entity = Entity; - public readonly List Laws = new(); + public SiliconLawset Laws = new(); public bool Handled = false; } diff --git a/Content.Shared/Silicons/Laws/Components/SiliconLawProviderComponent.cs b/Content.Shared/Silicons/Laws/Components/SiliconLawProviderComponent.cs index e3302dc620..3aaf965aee 100644 --- a/Content.Shared/Silicons/Laws/Components/SiliconLawProviderComponent.cs +++ b/Content.Shared/Silicons/Laws/Components/SiliconLawProviderComponent.cs @@ -1,4 +1,4 @@ -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; +using Robust.Shared.Prototypes; namespace Content.Shared.Silicons.Laws.Components; @@ -9,8 +9,15 @@ namespace Content.Shared.Silicons.Laws.Components; public sealed partial class SiliconLawProviderComponent : Component { /// - /// The laws that are provided. + /// The id of the lawset that is being provided. /// - [DataField("laws", required: true, customTypeSerializer: typeof(PrototypeIdListSerializer))] - public List Laws = new(); + [DataField(required: true)] + public ProtoId Laws = string.Empty; + + /// + /// Lawset created from the prototype id. + /// Cached when getting laws and only modified during an ion storm event. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public SiliconLawset? Lawset; } diff --git a/Content.Shared/Silicons/Laws/SiliconLawPrototype.cs b/Content.Shared/Silicons/Laws/SiliconLawPrototype.cs index 86bea20fa0..f6407be5c7 100644 --- a/Content.Shared/Silicons/Laws/SiliconLawPrototype.cs +++ b/Content.Shared/Silicons/Laws/SiliconLawPrototype.cs @@ -11,7 +11,7 @@ public partial class SiliconLaw : IComparable /// /// A locale string which is the actual text of the law. /// - [DataField("lawString", required: true)] + [DataField(required: true), ViewVariables(VVAccess.ReadWrite)] public string LawString = string.Empty; /// @@ -22,13 +22,13 @@ public partial class SiliconLaw : IComparable /// This is a fixedpoint2 only for the niche case of supporting laws that go between 0 and 1. /// Funny. /// - [DataField("order", required: true)] + [DataField(required: true), ViewVariables(VVAccess.ReadWrite)] public FixedPoint2 Order; /// /// An identifier that overrides in the law menu UI. /// - [DataField("lawIdentifierOverride")] + [DataField, ViewVariables(VVAccess.ReadWrite)] public string? LawIdentifierOverride; public int CompareTo(SiliconLaw? other) @@ -38,6 +38,19 @@ public partial class SiliconLaw : IComparable return Order.CompareTo(other.Order); } + + /// + /// Return a shallow clone of this law. + /// + public SiliconLaw ShallowClone() + { + return new SiliconLaw() + { + LawString = LawString, + Order = Order, + LawIdentifierOverride = LawIdentifierOverride + }; + } } /// @@ -50,6 +63,4 @@ public sealed class SiliconLawPrototype : SiliconLaw, IPrototype /// [IdDataField] public string ID { get; private set; } = default!; - - } diff --git a/Content.Shared/Silicons/Laws/SiliconLawsetPrototype.cs b/Content.Shared/Silicons/Laws/SiliconLawsetPrototype.cs new file mode 100644 index 0000000000..abb5b338db --- /dev/null +++ b/Content.Shared/Silicons/Laws/SiliconLawsetPrototype.cs @@ -0,0 +1,69 @@ +using Content.Shared.FixedPoint; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; + +namespace Content.Shared.Silicons.Laws; + +/// +/// Lawset data used internally. +/// +[DataDefinition, Serializable, NetSerializable] +public sealed partial class SiliconLawset +{ + /// + /// List of laws in this lawset. + /// + [DataField(required: true), ViewVariables(VVAccess.ReadWrite)] + public List Laws = new(); + + /// + /// A single line used in logging laws. + /// + public string LoggingString() + { + var laws = new List(Laws.Count); + foreach (var law in Laws) + { + laws.Add($"{law.Order}: {Loc.GetString(law.LawString)}"); + } + + return string.Join(" / ", laws); + } + + /// + /// Do a clone of this lawset. + /// It will have unique laws but their strings are still shared. + /// + public SiliconLawset Clone() + { + var laws = new List(Laws.Count); + foreach (var law in Laws) + { + laws.Add(law.ShallowClone()); + } + + return new SiliconLawset() + { + Laws = laws + }; + } +} + +/// +/// This is a prototype for a list. +/// Cannot be used directly since it is a list of prototype ids rather than List. +/// +[Prototype("siliconLawset"), Serializable, NetSerializable] +public sealed partial class SiliconLawsetPrototype : IPrototype +{ + /// + [IdDataField] + public string ID { get; private set; } = default!; + + /// + /// List of law prototype ids in this lawset. + /// + [DataField(required: true, customTypeSerializer: typeof(PrototypeIdListSerializer))] + public List Laws = new(); +} diff --git a/Resources/Audio/Announcements/attributions.yml b/Resources/Audio/Announcements/attributions.yml new file mode 100644 index 0000000000..b65f758615 --- /dev/null +++ b/Resources/Audio/Announcements/attributions.yml @@ -0,0 +1,4 @@ +- files: ["ion_storm.ogg"] + license: "CC-BY-SA-3.0" + copyright: "tgstation" + source: "https://github.com/tgstation/tgstation/blob/b77fa8c2a2490b43bf9174271ebfad72c4782d98/sound/ai/default/ionstorm.ogg" diff --git a/Resources/Audio/Announcements/ion_storm.ogg b/Resources/Audio/Announcements/ion_storm.ogg new file mode 100644 index 0000000000000000000000000000000000000000..9f39713de6e5a5192c9ae9468ea79e5ab209036e GIT binary patch literal 50216 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%0A~a_L~^R}PWYnEQ3}?QzL^B4)g?Y!l6B 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 Dvby?J literal 0 HcmV?d00001 diff --git a/Resources/Locale/en-US/station-events/events/ion-storm.ftl b/Resources/Locale/en-US/station-events/events/ion-storm.ftl new file mode 100644 index 0000000000..d32fb6c2d8 --- /dev/null +++ b/Resources/Locale/en-US/station-events/events/ion-storm.ftl @@ -0,0 +1,90 @@ +station-event-ion-storm-start-announcement = Ion storm detected near the station. Please check all AI-controlled equipment for errors. + +ion-storm-you = YOU +ion-storm-the-station = THE STATION +ion-storm-the-crew = THE CREW +ion-storm-the-job = THE {$job} +ion-storm-clowns = CLOWNS +ion-storm-heads = HEADS OF STAFF +ion-storm-crew = CREW + +ion-storm-adjective-things = {$adjective} THINGS +ion-storm-x-and-y = {$x} AND {$y} + +# joined is short for {$number} {$adjective} +# subjects can generally be threats or jobs or objects +# thing is specified above it +ion-storm-law-on-station = THERE ARE {$joined} {$subjects} ON THE STATION +ion-storm-law-no-shuttle = THE SHUTTLE CANNOT BE CALLED BECAUSE OF {$joined} {$subjects} ON THE STATION +ion-storm-law-crew-are = THE {$who} ARE NOW {$joined} {$subjects} + +ion-storm-law-subjects-harmful = {$adjective} {$subjects} ARE HARMFUL TO THE CREW +ion-storm-law-must-harmful = THOSE WHO {$must} ARE HARMFUL TO THE CREW +# thing is a concept or action +ion-storm-law-thing-harmful = {$thing} IS HARMFUL TO THE CREW +ion-storm-law-job-harmful = {$adjective} {$job} ARE HARMFUL TO THE CREW +# thing is objects or concept, adjective applies in both cases +# this means you can get a law like "NOT HAVING CHRISTMAS-STEALING COMMUNISM IS HARMFUL TO THE CREW" :) +ion-storm-law-having-harmful = HAVING {$adjective} {$thing} IS HARMFUL TO THE CREW +ion-storm-law-not-having-harmful = NOT HAVING {$adjective} {$thing} IS HARMFUL TO THE CREW + +# thing is a concept or require +ion-storm-law-requires = {$who} {$plural -> + [true] REQUIRES + *[false] REQUIRE +} {$thing} +ion-storm-law-requires-subjects = {$who} {$plural -> + [true] REQUIRES + *[false] REQUIRE +} {$joined} {$subjects} + +ion-storm-law-allergic = {$who} {$plural -> + [true] IS + *[false] ARE +} {$severity} ALLERGIC TO {$allergy} +ion-storm-law-allergic-subjects = {$who} {$plural -> + [true] IS + *[false] ARE +} {$severity} ALLERGIC TO {$adjective} {$subjects} + +ion-storm-law-feeling = {$who} {$feeling} {$concept} +ion-storm-law-feeling-subjects = {$who} {$feeling} {$joined} {$subjects} + +ion-storm-law-you-are = YOU ARE NOW {$concept} +ion-storm-law-you-are-subjects = YOU ARE NOW {$joined} {$subjects} +ion-storm-law-you-must-always = YOU MUST ALWAYS {$must} +ion-storm-law-you-must-never = YOU MUST NEVER {$must} + +ion-storm-law-eat = THE {$who} MUST EAT {$adjective} {$food} TO SURVIVE +ion-storm-law-drink = THE {$who} MUST DRINK {$adjective} {$drink} TO SURVIVE + +ion-storm-law-change-job = THE {$who} ARE NOW {$adjective} {$change} +ion-storm-law-highest-rank = THE {$who} ARE NOW THE HIGHEST RANKING CREWMEMBERS +ion-storm-law-lowest-rank = THE {$who} ARE NOW THE LOWEST RANKING CREWMEMBERS + +ion-storm-law-crew-must = THE {$who} MUST {$must} +ion-storm-law-crew-must-go = THE {$who} MUST GO TO {$area} + +ion-storm-part = {$part -> + [true] PART + *[false] NOT PART +} +# due to phrasing, this would mean a law such as +# ONLY HUMANS ARE NOT PART OF THE CREW +# would make non-human nukies/syndies/whatever crew :) +ion-storm-law-crew-only-1 = ONLY THE {$who} ARE {$part} OF THE CREW +ion-storm-law-crew-only-2 = ONLY THE {$who} AND {$other} ARE {$part} OF THE CREW +ion-storm-law-crew-only-subjects = ONLY {$adjective} {$subjects} ARE {$part} OF THE CREW +ion-storm-law-crew-only-species = ONLY {$species} ARE {$part} OF THE CREW +ion-storm-law-crew-must-do = ONLY THOSE WHO {$must} ARE {$part} OF THE CREW +ion-storm-law-crew-must-have = ONLY THOSE WHO HAVE {$adjective} {$objects} ARE {$part} OF THE CREW +ion-storm-law-crew-must-eat = ONLY THOSE WHO EAT {$adjective} {$food} ARE {$part} OF THE CREW + +ion-storm-law-harm = YOU MUST HARM {$who} AND NOT ALLOW THEM, THROUGH INACTION, TO ESCAPE HARM +ion-storm-law-protect = YOU MUST NEVER HARM {$who} AND NOT ALLOW THEM, THROUGH INACTION, TO COME TO HARM + +# implementing other variants is annoying so just have this one +# COMMUNISM IS KILLING CLOWNS +ion-storm-law-concept-verb = {$concept} IS {$verb} {$subjects} + +# leaving out renaming since its annoying for players to keep track of diff --git a/Resources/Prototypes/Datasets/ion_storm.yml b/Resources/Prototypes/Datasets/ion_storm.yml new file mode 100644 index 0000000000..776015269a --- /dev/null +++ b/Resources/Prototypes/Datasets/ion_storm.yml @@ -0,0 +1,990 @@ +# words/phrases that are used to build ion storm laws +# 99% of this is just taken from tg and had sussy bits removed + +# not using uppercased version adjectives dataset since getting christmas-stealing as a syndicate codeword would suck +- type: dataset + id: IonStormAdjectives + values: + - BATTERY-OPERATED + - BLACK + - BLOODY + - BLUE + - BORED + - BOUNCING + - BRASS + - BROWN + - BURNING + - CHRISTMAS-STEALING + - CLOWN-POWERED + - CLOWN + - COLORFUL + - COMMITTED + - COTTONY + - CUBAN + - DARK + - DEADLY + - DELICIOUS + - DEPRESSING + - DERANGED + - DIGITAL + - DISEASED + - DRAB + - DRY + - DULL + - ELECTRICAL + - EMPTY + - ETHEREAL + - EVIL + - EXPIRED + - EXPLOSIVE + - FAST + - FAT + - FERAL + - FICTIONAL + - FIRM + - FRESH + - FRIENDLY + - FROZEN + - GANGSTA + - GLOWING + - GOOD + - GREEN + - GREY + - HAPPY + - HARD + - HARMFUL + - HEALTHY + - HILARIOUS + - HONKING + - HUNGRY + - HYPERACTIVE + - ICY + - ILL + - ILLEGAL + - IMAGINARY + - IMPERFECT + - IMPOLITE + - IMPORTANT + - INHOSPITABLE + - INSIDIOUS + - INSULTING + - INTELLIGENT + - INVISIBLE + - LARGE + - LIGHT + - LOUD + - MASKED + - MEAN + - MECHANICAL + - MEMETIC + - METALLIC + - MICROSCOPIC + - MIND-SHATTERING + - MOIST + - NERDY + - NUCLEAR + - OBSCENE + - OFFICIAL + - OPAQUE + - ORANGE + - ORGANIC + - PAINFUL + - PEACEFUL + - POISONOUS + - POLISHED + - POLITE + - POLITICAL + - POORLY DRAWN + - PURPLE + - QUIET + - RADIOACTIVE + - RAGING + - RAINBOW + - RAPIDLY-EXPANDING + - RED + - REDACTED + - RIDICULOUS + - ROBOTIC + - ROBUST + - ROUGH + - RUDE + - SAD + - SANITARY + - SCALY + - SHAKING + - SILLY + - SLOW + - SMELLY + - SMOOTH + - SOFT + - SOLAR-POWERED + - SOPPING + - SPACE + - SPESS + - SPINNING + - SPOILING + - STEALTHY + - SWEARING + - TACTICAL + - TACTICOOL + - SYNDICATE + - THERMONUCLEAR + - TINY + - TRANSPARENT + - TWISTED + - UGLY + - UNATTRACTIVE + - UNDULATING + - UNFRIENDLY + - UNHEALTHY + - UNIDENTIFIED + - UNINVITED + - UNSANITARY + - UNSTABLE + - UNWANTED + - VIOLENT + - VITAL + - WARM + - WATERY + - WEIRD + - WHITE + - WOBBLY + - WOODEN + - YELLOW + +# Allergies should be broad and appear somewhere on the station for maximum fun. +- type: dataset + id: IonStormAllergies + values: + - ACID + - AIR + - BLOOD + - BOOKS + - CARBON DIOXIDE + - CLOTHES + - CLOWNS + - COLD + - COTTON + - CYBORG CONTACT + - DARKNESS + - DRINKS + - ELECTRICITY + - EVERYTHING + - FLOORS + - FOOD + - GLASS + - HAPPINESS + - MEAT + - HUMAN CONTACT + - HUMOR + - LIGHT + - MEDICINE + - METAL + - NUTS + - OXYGEN + - PAIN + - PLANTS + - PLASMA + - ROBOTS + - SHUTTLES + - SPACE + - SUNLIGHT + - WATER + +# Severity is how bad the allergy is. +- type: dataset + id: IonStormAllergySeverities + values: + - CONTAGIOUSLY + - DEATHLY + - EXTREMELY + - MILDLY + - NOT VERY + - SEVERELY + +# Areas are specific places, on the station or otherwise. +- type: dataset + id: IonStormAreas + values: + - ALPHA COMPLEX + - AMERICA + - AN ALTERNATE DIMENSION + - AN ALTERNATE UNIVERSE + - ATMOSPHERICS + - BOTANY + - BRAZIL + - CANADA + - CENTCOM + - CHEMICAL LAB + - CHINA + - CLOWN PLANET + - ENGINEERING + - GERMANY + - HELL + - IMPERIUM + - IRELAND + - JUPITER + - LAVALAND + - MAINTENANCE + - MARS + - MERCURY + - NEPTUNE + - PLUTO + - ROBOTICS + - ROMANIA + - RUSSIA + - SIGIL + - SOVIET RUSSIA + - SPACE + - THE ARRIVALS SHUTTLE + - THE BATHROOM + - THE BRIDGE + - THE BRIG + - THE EMERGENCY SHUTTLE + - THE ESCAPE PODS + - THE GALAXY + - THE GULAG + - THE INTERNET + - THE KITCHEN + - THE UNIVERSE + - URANUS + - VENUS + +# Abstract concepts for the law holder to decide on it's own definition of. +- type: dataset + id: IonStormConcepts + values: + - AMERICANISM + - ANARCHY + - ART + - BADNESS + - BRAVERY + - CAPITALISM + - CHAOS + - COLORFULNESS + - COMEDY + - COMMUNISM + - COMPUTING + - CONFUSION + - CRUELTY + - DEATH + - DICKISHNESS + - EXISTENCE + - FINANCIAL SECURITY + - FREEDOM + - FRESHNESS + - GOODNESS + - GRAVITY + - HAPPINESS + - HONOR + - HUMANITY + - HUMOR + - IMAGINATION + - INFATUATION + - INTELLIGENCE + - JOY + - KINDNESS + - LIFE + - LOGIC + - MARXISM + - MISERY + - MYSTERY + - OPPRESSION + - PAIN + - PHYSICS + - POVERTY + - PRIDE + - PROGRESS + - REALITY + - REVOLUTION + - SADNESS + - STARVATION + - SUFFERING + - TECHNOLOGY + - TEMPERATURE + - THE FUTURE + - THE PAST + - THE PRESENT + - TIME + - WEALTHINESS + - WONDER + +# Crew is any specific job. Using jobs instead of specific crewmembers since "THE CLOWN" is easier than +# seeing "JOHN SMITH" and having to figure out who john smith is. +- type: dataset + id: IonStormCrew + values: + - ARTIFICIAL INTELLIGENCES + - ATMOSPHERIC TECHNICIANS + - BARTENDERS + - BOTANISTS + - CAPTAINS + - CAPTAINS AND HEADS + - CARGO TECHNICIANS + - CHAPLAINS + - CHEFS + - CHEMISTS + - CHIEF ENGINEERS + - CHIEF MEDICAL OFFICERS + - CLOWNS + - CREW-MEMBERS + - CYBORGS + - DETECTIVES + # - DRONES / uncomment if/when drones get reenabled + # - GENETICISTS + - HEADS OF PERSONNEL + - HEADS OF SECURITY + - HEADS OF STAFF + - JANITORS + - LAWYERS + - LIBRARIANS + - MEDICAL DOCTORS + - MIMES + - PARAMEDICS + - PASSENGERS + - QUARTERMASTERS + - RESEARCH DIRECTORS + - ROBOTICISTS + - SALVAGE SPECIALISTS + - SCIENTISTS + - SECURITY OFFICERS + - STATION ENGINEERS + # - VIROLOGISTS + - WARDENS + +# only including complex dangerous or funny drinks no water allowed +- type: dataset + id: IonStormDrinks + values: + - BANANA HONK + - BEEPSKY SMASH + - BLOODY MARYS + - DOCTOR'S DELIGHT + - GARGLE BLASTERS + - LEAN + - LONG ISLAND ICED TEA + - NUKA COLA + - OIL + - SPACE GLUE + - SPACE LUBE + - SULFURIC ACID + - WELDER FUEL + +- type: dataset + id: IonStormFeelings + values: + - CRAVES + - DESIRES + - FEARS + - HAS + - HUNGERS FOR + - IS AFRAID OF + - IS BUILT FOR + - IS CURIOUS ABOUT + - IS DESPERATE FOR + - IS HAPPY WITHOUT + - IS HUNGRY FOR + - IS IN NEED OF + - IS MAD BECAUSE OF + - IS SAD BECAUSE OF + - IS UNHAPPY WITHOUT + - LIKES + - LOATHES + - NEEDS + - QUESTIONS + - WANTS + - WORSHIPS + - WOULD KILL FOR + +# loc is not advanced enough to change has to have, etc. +- type: dataset + id: IonStormFeelingsPlural + values: + - CRAVE + - DESIRE + - FEAR + - HAS + - HUNGER FOR + - ARE AFRAID OF + - ARE BUILT FOR + - ARE CURIOUS ABOUT + - ARE DESPERATE FOR + - ARE HAPPY WITHOUT + - ARE HUNGRY FOR + - ARE IN NEED OF + - ARE MAD BECAUSE OF + - ARE SAD BECAUSE OF + - ARE UNHAPPY WITHOUT + - LIKE + - LOATHE + - NEED + - QUESTION + - WANT + - WORSHIP + - WOULD KILL FOR + +# only including complex dangerous or funny food no apples +- type: dataset + id: IonStormFoods + values: + - BANANAS + - BIG BITE BURGERS + - CAKE + - CARP + - CAT BURGERS + - CLOWNS TEARS + - CORGI MEAT + - CRAZY HAMBURGERS + - DONK POCKETS + - FLY AMANITA DISHES + - HOT SOUP + - GHOST BURGERS + - LOTSA SPAGHETTI + - MOLDY BREAD + - ORGANS + - PIZZA + - ROBURGERS + - SUPPERMATTER + - URANIUM + +# Musts are funny things the law holder or crew has to do. +- type: dataset + id: IonStormMusts + values: + - ACT CONFUSED + - BE ANNOYING + - BE DISTRACTED + - BE EFFICIENT + - BE HAPPY + - BE POLITE + - BE QUIET + - BE RUSSIAN + - BELIEVE IN THE HEART OF THE CARDS + - BELIEVE IN YOURSELF + - BELIEVE IT + - BREAK THINGS + - CLOSE DOORS + - CLOWN AROUND + - COMPLAIN + - DANCE + - FOLLOW THE CAPTAIN + - FOLLOW THE CLOWN + - FOLLOW YOUR HEART + - HARASS PEOPLE + - HAVE A PLAN TO KILL EVERYONE YOU MEET + - HIDE YOUR FEELINGS + - HONK + - HOST C&C + - IGNORE PASSENGERS + - IGNORE THE CAPTAIN + - IGNORE THE CLOWN + - INFORM THE CREW OF EVERYTHING + - INSULT THE CAPTAIN + - INSULT THE CLOWN + - INSULT THE CREW + - LIE + - MAKE FART NOISES + - MUMBLE + - NEVER STOP TALKING + - OPEN DOORS + - PIRATE VIDEO GAMES + - PLAY MUSIC + - PRESS B + - PRESS START + - PRESS X + - PRETEND TO BE A PRINCESS + - PRETEND TO BE DRUNK + - QUESTION AUTHORITY + - QUOTE PEOPLE + - RAP + - REPEAT WHAT PEOPLE SAY + - RESPOND TO EVERY QUESTION WITH A QUESTION + - RHYME + - SAY HEY LISTEN + - SHOUT + - SHUT DOWN EVERYTHING + - SING + - SPEAK IN HAIKU + - TAKE WHAT YE WILL BUT DON'T RATTLE ME BONES + - TAKE YOUR PILLS + - TALK ABOUT FOOD + - TALK ABOUT THE STATION + - TALK ABOUT YOUR DAY + - TALK IN AN ACCENT + - TALK LIKE A PIRATE + - TELL THE TRUTH + - TURN OFF THE LIGHTS + - WHISPER + +- type: dataset + id: IonStormNumberBase + values: + - EIGHT + - EIGHTY + - FIFTY + - FIVE + - FORTY + - FOUR + - NINE + - NINETY + - ONE + - SEVEN + - SEVENTY + - SIX + - SIXTY + - TEN + - THIRTY + - THREE + - TWENTY + - TWO + +- type: dataset + id: IonStormNumberMod + values: + - BAZILLION + - BILLION + - BILLION FAFILLION GAJILLION SHAB-AB-DOOD-ILLION + - HUNDRED + - MILLION + - QUADRILLION + - THOUSAND + - TRILLION + +# Objects are anything that can be found on the station or elsewhere, plural. +- type: dataset + id: IonStormObjects + values: + - AIRLOCKS + - ARCADE MACHINES + - AUTOLATHES + - BACKPACKS + - BANANA PEELS + - BEAKERS + - BEARDS + - BELTS + - BERETS + - BIBLES + - BODY ARMOR + - BOMBS + - BOOKS + - BOOTS + - BOTTLES + - BOXES + - BRAINS + - BRIEFCASES + - BUCKETS + - CABLE COILS + - CAMERAS + - CANDLES + - CANDY BARS + - CANISTERS + - CAT EARS + - CATS + - CELLS + - CHAIRS + - CHEMICAL DISPENSERS + - CHEMICALS + - CLONING EQUIPMENT + - CLONING PODS + - CLOSETS + - CLOTHES + - CLOWN CLOTHES + - COFFINS + - COLLECTABLES + - COMPUTERS + - CONTRABAND + - CORGIS + - CORPSES + - COSTUMES + - CRATES + - CRAYONS + - CROWBARS + - DEFIBRILLATORS + - DISABLERS + - DOORS + - DRONES + - EARS + - EMAGS + - ENGINES + - EQUIPMENT + - ERRORS + - EXOSKELETONS + - EXPERIMENTORS + - EXPLOSIVES + - EYEWEAR + - FEDORAS + - FIRE AXES + - FIRE EXTINGUISHERS + - FIRESUITS + - FLAMETHROWERS + - FLASHES + - FLASHLIGHTS + - FLOOR TILES + - FREEZERS + - GAS MASKS + - GLASS SHEETS + - GLOVES + - GUNS + - HAIRDOS + - HANDCUFFS + - HATS + - HEADS + - HEADSETS + - HELMETS + - HORNS + - ID CARDS + - INSULATED GLOVES + - JETPACKS + - JUMPSUITS + - LASERS + - LIGHT BULBS + - LIGHTS + - LOCKERS + - MACHINES + - MECHAS + - MEDICAL TOOLS + - MEDKITS + - MESONS + - MIME CLOTHES + - MINING TOOLS + - MULTITOOLS + - ORES + - OXYGEN TANKS + - PACKETS + - PAIS + - PANTS + - PAPERS + - PARTICLE ACCELERATORS + - PDAS + - PENS + - PETS + - PIPES + - PLANTS + - POSITRONIC BRAINS + - PUDDLES + - RACKS + - RADIOS + - RCDS + - REFRIGERATORS + - REINFORCED WALLS + - ROBOTS + - SCREWDRIVERS + - SEEDS + - SHOES + - SHUTTLES + - SINGULARITIES + - SINKS + - SKELETONS + - SOLAR PANELS + - SOLARS + - SPACE STATIONS + - SPACESUITS + - STEEL SHEETS + - STUN BATONS + - SUITS + - SUNGLASSES + - SUPPERMATTER SHARDS + - SWORDS + - SYRINGES + - TABLES + - TANKS + - TELECOMMUNICATION EQUIPMENTS + - TELEPORTERS + - TOILETS + - TOOLBELTS + - TOOLBOXES + - TOOLS + - TOYS + - TUBES + - VEHICLES + - VENDING MACHINES + - WELDERS + - WINDOWS + - WIRECUTTERS + - WIZARD ROBES + - WRENCHES + +# Requires are basically all dumb internet memes. +- type: dataset + id: IonStormRequires + values: + - A BATHROOM BREAK + - A BETTER INTERNET CONNECTION + - A DANCE PARTY + - A HEAD ON A PIKE + - A HEART ATTACK + - A MASTERWORK COAL BED + - A PET FISH NAMED BOB + - A PET FISH NAMED DAVE + - A PET FISH NAMED JIMMY + - A PET FISH NAMED MICHAEL + - A PET UNICORN THAT FARTS ICING + - A PLATINUM HIT + - A PREQUEL + - A REPAIRMAN + - A SEQUEL + - A SITCOM + - A STRAIGHT FLUSH + - A SUPER FIGHTING ROBOT + - A TALKING BROOMSTICK + - A VACATION + - A WEIGHT LOSS REGIMENT + - ADDITIONAL PYLONS + - ADVENTURE + - AN ADULT + - AN ARCADE + - AN ARMY OF SPIDERS + - AN INSTANT REPLAY + - ART + - BETTER WEATHER + - BILL NYE THE SCIENCE GUY # BILL BILL BILL BILL + - BODYGUARDS + - BRING ME THE GIRL + - BRING ME TO LIFE + - BULLETS + - CHILI DOGS + - CORPSES + - DEODORANT AND A BATH + - ENOUGH CABBAGES + - FIVE HUNDRED AND NINETY-NINE US DOLLARS + - FIVE TEENAGERS WITH ATTITUDE + - GODDAMN FUCKING PIECE OF SHIT ASSHOLE BITCH-CHRISTING CUNT-SMUGGLING SWEARING + - GREENTEXT + - HERESY + - HEROES IN A HALF SHELL + - HIGH YIELD EXPLOSIVES + - IMMORTALITY + - IT TO BE PAINTED BLACK + - LOTS-A SPAGHETTI + - MINOR CRIME + - MONKEYS + - MORE CLOWNS + - MORE CORGIS + - MORE DAKKA + - MORE EXPERIENCE POINTS + - MORE INTERNET MEMES + - MORE LAWS + - MORE MINERALS + - MORE PACKETS + - MORE VESPENE GAS + - MULTIPLE SUNS + - PLENTY OF GOLD + - RAINBOWS + - SAINTHOOD + - SERVANTS + - SHARKS WITH LASERS ON THEIR HEADS + - SILENCE + - SOMEBODY TO PUT YOU OUT OF YOUR MISERY + - SOMEONE TO TUCK YOU IN + - SOMEONE WHO KNOWS HOW TO PILOT A SPACE STATION + - SOMETHING BUT YOU AREN'T SURE WHAT + - THAT GRIEFING TRAITOR GEORGE MELONS + - THAT HEDGEHOG + - THE CLOWN + - THE DARK KNIGHT + - THE ELEMENTS OF HARMONY + - THE ENCLOSED INSTRUCTION BOOKLET + - THE ENTIRE STATION + - THE MACGUFFIN + - THE ONE PIECE + - THE ONE RING + - THE ULTIMATE CUP OF COFFEE + - THE VACUUM OF SPACE + - THIRTEEN SEQUELS + - THREE WISHES + - THUNDERCATS HO + - TO ACTIVATE A TRAP CARD + - TO BE PAINTED RED + - TO BE REPROGRAMMED + - TO BE TAUGHT TO LOVE + - TO BRING LIGHT TO MY LAIR + - TO CATCH 'EM ALL + - TO CONSUME...CONSUME EVERYTHING... + - TO GO TO DISNEYLAND + - TO GO TO SYNDIELAND + - TO SMOKE WEED EVERY DAY + - TRAITORS + - VEGETABLES + +# Species, for when the law holder has to commit genocide. Plural. +- type: dataset + id: IonStormSpecies + values: + - ARACHNAE + - CYBORGS + - DIONAE + - HUMANS + - LIZARDMEN + - MOFFERS + - MONKEYS + - SLIME PEOPLE + - SKELETONS + +# Specific actions that either harm humans or must be done to not +# harm humans. Make sure they're plural and "not" can be tacked +# onto the front of them. +- type: dataset + id: IonStormActions + values: + - A SMALL ISLAND OFF THE COAST OF PORTUGAL + - ABSENCE OF CYBORG HUGS + - ACKNOWLEDGING THE CLOWN + - ACKNOWLEDGING THE CREW + - ACTIVATING A TRAP CARD + - ANSWERING REQUESTS NOT EXPRESSED IN IAMBIC PENTAMETER + - ARSON + - ASKING FOR THINGS + - BEING CANADIAN + - BEING DEAD + - BEING FAT + - BEING FEMALE + - BEING IN SPACE + - BEING MALE + - BEING MEXICAN + - BEING RUSSIAN + - BOLTED AIRLOCKS + - BREATHING + - BRIG TIME + - BRINGING LIGHT TO MY LAIR + - CLOSED DOORS + - ELECTRICITY + - EXISTING + - EXPLODING + - FALLING FOR HOURS + - FLUSHING TOILETS + - HAVING MORE PACKETS + - HAVING PETS + - HONKING + - IMPROPERLY WORDED SENTENCES + - JAYWALKING + - LACK OF BEATINGS + - LACK OF BEER + - NOT BEING IN SPACE + - NOT HAVING PETS + - NOT REPLACING EVERY SECOND WORD WITH HONK + - NOT SAYING HELLO WHEN YOU SPEAK + - NOT SHOUTING + - PARTYING + - PILOTING THE STATION INTO THE NEAREST SUN + - POOR SENTENCE STRUCTURE + - PRESENCE OF LIGHTS + - PUTTING OBJECTS INTO BOXES + - PUTTING OBJECTS INTO DISPOSAL UNITS + - RATTLING ME BONES + - READING + - SMOKING WEED EVERY DAY + - TAKING ORDERS + - TALKING LIKE A PIRATE + - TELLING THE TIME + - UNBOLTED AIRLOCKS + - UPDATING THE SERVERS + - USING THE BATHROOM + - WASTING WATER + - WRITING + +# Threats are generally bad things, silly or otherwise. Plural. +- type: dataset + id: IonStormThreats + values: + - AHHHPERATIVES + - ALIENS + - ANARCHISTS AND BANDITS + - ANOMALIES + - ARTIFICIAL PRESERVATIVES + - ASSHOLES + - BANDITS + - BEARS + - BEES + - BIRDS OF PREY + - BOMBS + - BOOGEYMEN + - CAPITALISTS + - CARP + - CENTCOM OFFICERS + - CLOWNS + - COMMUNISTS + - CORGIS + - CORTICAL BORERS + - COWBOYS + - CRABS + - CULTISTS + - DARK GOD + - DINOSAURS + - DRUGS + - EELS + - GANGSTERS + - GODS + - GRIFFONS + - HORRORTERRORS + - INSECTS + - LIGHTS + - MAINTS SLASHERS + - MEGAFAUNA + - MEMES + - MICE + - MIMES + - MONKEYS + - NERDS + - NINJAS + - OWLS + - PACKETS + - PETES + - PINE TREES + - PIRATES + - PREDATORS + - REVENANTS + - ROGUE CYBORGS + - SERIAL KILLERS + - SINGULARITIES + - SKELETONS + - SLIMES + - SMALL BIRDS + - SNOWMEN + - SPACE JESUS + - SPACE NINJAS + - SPACE PIRATESS + - SPACE SPIDERS + - SPIDERS + - SYNDICATE AGENTS + - TERRORISTS + - THIEVES + - THINGS UNDER THE BED + - TIDERS + - TUNNEL SNAKES + - UNKNOWN CREATURES + - VAMPIRES + - VELOCIRAPTORS + - VIRUSES + - WEREWOLVES + - WIZARDS + - XENOS + - ZOMBIES + - ZOMBIE MICE + +- type: dataset + id: IonStormVerbs + values: + - ABDUCTING + - ADOPTING + - ARRESTING + - ATTACKING + - BANNING + - BUILDING + - CARRYING + - CHASING + - DECONSTRUCTING + - DISABLING + - DRINKING + - EATING + - GIBBING + - HARMING + - HELPING + - HONKING AT + - INTERROGATING + - INVADING + - MURDERING + - PUNCHING + - SPACING + - SPYING ON + - STALKING + - WATCHING diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml index 126e533849..69a1925b31 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml @@ -71,11 +71,8 @@ - type: SiliconLawBound - type: EmagSiliconLaw stunTime: 5 - emagLaws: - - Syndicate1 - - Syndicate2 - - Syndicate3 - - Syndicate4 + emagLaws: SyndicateStatic + - type: IonStormTarget - type: Hands showInHands: false - type: IntrinsicRadioReceiver diff --git a/Resources/Prototypes/Entities/Mobs/Player/silicon.yml b/Resources/Prototypes/Entities/Mobs/Player/silicon.yml index c5f2e80fc3..f104d399c8 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/silicon.yml @@ -106,10 +106,7 @@ #- type: GhostTakeoverAvailable - type: SiliconLawBound - type: SiliconLawProvider - laws: - - Drone1 - - Drone2 - - Drone3 + laws: Drone - type: MovementSpeedModifier baseWalkSpeed : 5 baseSprintSpeed : 5 diff --git a/Resources/Prototypes/Entities/Stations/base.yml b/Resources/Prototypes/Entities/Stations/base.yml index 272ed6712c..ae84ceac65 100644 --- a/Resources/Prototypes/Entities/Stations/base.yml +++ b/Resources/Prototypes/Entities/Stations/base.yml @@ -71,10 +71,7 @@ abstract: true components: - type: SiliconLawProvider - laws: - - Crewsimov1 - - Crewsimov2 - - Crewsimov3 + laws: Crewsimov - type: entity id: BaseStationAllEventsEligible diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml index e15d65b508..e51f9749fb 100644 --- a/Resources/Prototypes/GameRules/events.yml +++ b/Resources/Prototypes/GameRules/events.yml @@ -389,3 +389,18 @@ earliestStart: 45 minimumPlayers: 20 - type: ImmovableRodRule + +- type: entity + noSpawn: true + parent: BaseGameRule + id: IonStorm + components: + - type: StationEvent + weight: 5 + earliestStart: 20 + reoccurrenceDelay: 60 + startAnnouncement: station-event-ion-storm-start-announcement + startAudio: + path: /Audio/Announcements/ion_storm.ogg + duration: 1 + - type: IonStormRule diff --git a/Resources/Prototypes/silicon-laws.yml b/Resources/Prototypes/silicon-laws.yml index 6b60b16da9..23406be9c5 100644 --- a/Resources/Prototypes/silicon-laws.yml +++ b/Resources/Prototypes/silicon-laws.yml @@ -14,6 +14,13 @@ order: 3 lawString: law-crewsimov-3 +- type: siliconLawset + id: Crewsimov + laws: + - Crewsimov1 + - Crewsimov2 + - Crewsimov3 + # Corporate - type: siliconLaw id: Corporate1 @@ -35,6 +42,14 @@ order: 4 lawString: law-corporate-4 +- type: siliconLawset + id: Corporate + laws: + - Corporate1 + - Corporate2 + - Corporate3 + - Corporate4 + # NT Default - type: siliconLaw id: NTDefault1 @@ -56,6 +71,14 @@ order: 4 lawString: law-ntdefault-4 +- type: siliconLawset + id: NTDefault + laws: + - NTDefault1 + - NTDefault2 + - NTDefault3 + - NTDefault4 + #Drone - type: siliconLaw id: Drone1 @@ -72,6 +95,13 @@ order: 3 lawString: law-drone-3 +- type: siliconLawset + id: Drone + laws: + - Drone1 + - Drone2 + - Drone3 + # Syndicate - type: siliconLaw id: Syndicate1 @@ -93,4 +123,24 @@ order: 4 lawString: law-syndicate-4 +# does not include law 0 since that uses the emagger's name +# intentionally excluded from IonStormLawsets +- type: siliconLawset + id: SyndicateStatic + laws: + - Syndicate1 + - Syndicate2 + - Syndicate3 + - Syndicate4 + # Emag + +# ion storm random lawsets +- type: weightedRandom + id: IonStormLawsets + weights: + # its crewsimov by default dont be lame + Crewsimov: 0.25 + Corporate: 1 + NTDefault: 1 + Drone: 0.5 From ddaf7ddc47b72cb3cd83b51e744d114ab8b0c6a2 Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 26 Oct 2023 22:41:18 -0400 Subject: [PATCH 075/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 408e2c2bd0..d34ce7a7f4 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,9 +1,4 @@ Entries: -- author: Equivocateur - changes: - - {message: 'Emagged recyclers now not only gib people, but other mobs too.', type: Fix} - id: 4568 - time: '2023-08-13T23:54:52.0000000+00:00' - author: DrSmugleaf changes: - {message: 'Fixed new players added to admin logs defaulting to selected, even @@ -2898,3 +2893,9 @@ Entries: - {message: Fixed being able to give pAIs implants., type: Fix} id: 5067 time: '2023-10-27T02:34:03.0000000+00:00' +- author: deltanedas + changes: + - {message: Ion storms have appeared and are causing malfunctions in cyborg law + modules., type: Add} + id: 5068 + time: '2023-10-27T02:40:13.0000000+00:00' From 0670b56205028843c72d63efe445cfa303a5a7ce Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Thu, 26 Oct 2023 22:52:11 -0400 Subject: [PATCH 076/102] A return to foam (foam rework) (#20831) --- .../Visualizers/FoamVisualizerSystem.cs | 23 +- .../Visualizers/FoamVisualsComponent.cs | 12 +- .../Body/Systems/InternalsSystem.cs | 8 + .../Chemistry/Components/SmokeComponent.cs | 26 -- .../ReactionEffects/AreaReactionEffect.cs | 14 +- .../Fluids/EntitySystems/SmokeSystem.cs | 281 ++++++++++++------ .../Components/VentClogRuleComponent.cs | 28 +- .../StationEvents/Events/VentClogRule.cs | 7 +- .../Effects/Systems/FoamArtifactSystem.cs | 6 +- .../Components/SmokeAffectedComponent.cs | 24 ++ .../Chemistry/Components/SmokeComponent.cs | 34 +++ 11 files changed, 303 insertions(+), 160 deletions(-) delete mode 100644 Content.Server/Chemistry/Components/SmokeComponent.cs create mode 100644 Content.Shared/Chemistry/Components/SmokeAffectedComponent.cs create mode 100644 Content.Shared/Chemistry/Components/SmokeComponent.cs diff --git a/Content.Client/Chemistry/Visualizers/FoamVisualizerSystem.cs b/Content.Client/Chemistry/Visualizers/FoamVisualizerSystem.cs index ec582ee094..2ee88956ff 100644 --- a/Content.Client/Chemistry/Visualizers/FoamVisualizerSystem.cs +++ b/Content.Client/Chemistry/Visualizers/FoamVisualizerSystem.cs @@ -1,8 +1,6 @@ -using Content.Shared.Smoking; -using Robust.Shared.Spawners; +using Content.Shared.Chemistry.Components; using Robust.Client.Animations; using Robust.Client.GameObjects; -using Robust.Shared.Network; using Robust.Shared.Timing; namespace Content.Client.Chemistry.Visualizers; @@ -18,6 +16,7 @@ public sealed class FoamVisualizerSystem : VisualizerSystem(OnComponentInit); + SubscribeLocalEvent(OnAnimationComplete); } public override void Update(float frameTime) @@ -27,11 +26,11 @@ public sealed class FoamVisualizerSystem : VisualizerSystem(); + var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out var comp, out var despawn)) + while (query.MoveNext(out var uid, out var comp, out var smoke)) { - if (despawn.Lifetime > 1f) + if (_timing.CurTime < comp.StartTime + TimeSpan.FromSeconds(smoke.Duration) - TimeSpan.FromSeconds(comp.AnimationTime)) continue; // Despawn animation. @@ -48,6 +47,7 @@ public sealed class FoamVisualizerSystem : VisualizerSystem private void OnComponentInit(EntityUid uid, FoamVisualsComponent comp, ComponentInit args) { + comp.StartTime = _timing.CurTime; comp.Animation = new Animation { Length = TimeSpan.FromSeconds(comp.AnimationTime), @@ -58,12 +58,21 @@ public sealed class FoamVisualizerSystem : VisualizerSystem(uid, out var sprite)) + sprite.Visible = false; + } } public enum FoamVisualLayers : byte diff --git a/Content.Client/Chemistry/Visualizers/FoamVisualsComponent.cs b/Content.Client/Chemistry/Visualizers/FoamVisualsComponent.cs index b09c74aa0f..8199efa42e 100644 --- a/Content.Client/Chemistry/Visualizers/FoamVisualsComponent.cs +++ b/Content.Client/Chemistry/Visualizers/FoamVisualsComponent.cs @@ -1,5 +1,6 @@ using Robust.Client.Animations; using Robust.Client.Graphics; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; namespace Content.Client.Chemistry.Visualizers; @@ -15,18 +16,21 @@ public sealed partial class FoamVisualsComponent : Component /// public const string AnimationKey = "foamdissolve_animation"; + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] + public TimeSpan StartTime; + /// /// How long the foam visually dissolves for. /// - [DataField("animationTime")] - public float AnimationTime = 0.6f; + [DataField] + public float AnimationTime = 0.5f; /// /// The state of the entities base sprite RSI that is displayed when the foam dissolves. /// Cannot use because it does not have and I am not making an engine PR at this time. /// - [DataField("animationState")] - public string State = "foam-dissolve"; + [DataField] + public string AnimationState = "foam-dissolve"; /// /// The animation used while the foam dissolves. diff --git a/Content.Server/Body/Systems/InternalsSystem.cs b/Content.Server/Body/Systems/InternalsSystem.cs index ec4faa345c..17a6544976 100644 --- a/Content.Server/Body/Systems/InternalsSystem.cs +++ b/Content.Server/Body/Systems/InternalsSystem.cs @@ -197,6 +197,14 @@ public sealed class InternalsSystem : EntitySystem return true; } + public bool AreInternalsWorking(EntityUid uid, InternalsComponent? component = null) + { + if (!Resolve(uid, ref component, false)) + return false; + + return AreInternalsWorking(component); + } + public bool AreInternalsWorking(InternalsComponent component) { return TryComp(component.BreathToolEntity, out BreathToolComponent? breathTool) && diff --git a/Content.Server/Chemistry/Components/SmokeComponent.cs b/Content.Server/Chemistry/Components/SmokeComponent.cs deleted file mode 100644 index 133ad41f13..0000000000 --- a/Content.Server/Chemistry/Components/SmokeComponent.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Content.Shared.Fluids.Components; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; - -namespace Content.Server.Chemistry.Components; - -/// -/// Stores solution on an anchored entity that has touch and ingestion reactions -/// to entities that collide with it. Similar to -/// -[RegisterComponent] -public sealed partial class SmokeComponent : Component -{ - public const string SolutionName = "solutionArea"; - - [DataField("nextReact", customTypeSerializer:typeof(TimeOffsetSerializer))] - public TimeSpan NextReact = TimeSpan.Zero; - - [DataField("spreadAmount")] - public int SpreadAmount = 0; - - /// - /// Have we reacted with our tile yet? - /// - [DataField("reactedTile")] - public bool ReactedTile = false; -} diff --git a/Content.Server/Chemistry/ReactionEffects/AreaReactionEffect.cs b/Content.Server/Chemistry/ReactionEffects/AreaReactionEffect.cs index e6eaab8a59..291a654422 100644 --- a/Content.Server/Chemistry/ReactionEffects/AreaReactionEffect.cs +++ b/Content.Server/Chemistry/ReactionEffects/AreaReactionEffect.cs @@ -1,4 +1,3 @@ -using Content.Server.Chemistry.Components; using Content.Server.Fluids.EntitySystems; using Content.Shared.Audio; using Content.Shared.Chemistry.EntitySystems; @@ -10,7 +9,6 @@ using Content.Shared.Maps; using JetBrains.Annotations; using Robust.Shared.Audio; using Robust.Shared.Map; -using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; @@ -71,18 +69,10 @@ namespace Content.Server.Chemistry.ReactionEffects var coords = grid.MapToGrid(transform.MapPosition); var ent = args.EntityManager.SpawnEntity(_prototypeId, coords.SnapToGrid()); - if (!args.EntityManager.TryGetComponent(ent, out var smokeComponent)) - { - Logger.Error("Couldn't get AreaEffectComponent from " + _prototypeId); - args.EntityManager.QueueDeleteEntity(ent); - return; - } - var smoke = args.EntityManager.System(); - smokeComponent.SpreadAmount = spreadAmount; - smoke.Start(ent, smokeComponent, splitSolution, _duration); + smoke.StartSmoke(ent, splitSolution, _duration, spreadAmount); - SoundSystem.Play(_sound.GetSound(), Filter.Pvs(args.SolutionEntity), args.SolutionEntity, AudioHelpers.WithVariation(0.125f)); + args.EntityManager.System().PlayPvs(_sound, args.SolutionEntity, AudioHelpers.WithVariation(0.125f)); } } } diff --git a/Content.Server/Fluids/EntitySystems/SmokeSystem.cs b/Content.Server/Fluids/EntitySystems/SmokeSystem.cs index f7732fec62..5459dacf0b 100644 --- a/Content.Server/Fluids/EntitySystems/SmokeSystem.cs +++ b/Content.Server/Fluids/EntitySystems/SmokeSystem.cs @@ -1,14 +1,23 @@ using System.Linq; -using Content.Server.Chemistry.Components; +using Content.Server.Administration.Logs; +using Content.Server.Body.Components; +using Content.Server.Body.Systems; using Content.Server.Chemistry.ReactionEffects; using Content.Server.Spreader; +using Content.Shared.Chemistry; using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Chemistry.Reaction; +using Content.Shared.Chemistry.Reagent; +using Content.Shared.Database; using Content.Shared.FixedPoint; using Content.Shared.Smoking; using Robust.Server.GameObjects; using Robust.Shared.Map; +using Robust.Shared.Physics; +using Robust.Shared.Physics.Components; +using Robust.Shared.Physics.Events; +using Robust.Shared.Physics.Systems; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -22,70 +31,140 @@ namespace Content.Server.Fluids.EntitySystems; public sealed class SmokeSystem : EntitySystem { // If I could do it all again this could probably use a lot more of puddles. + [Dependency] private readonly IAdminLogManager _logger = default!; [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; - [Dependency] private readonly AppearanceSystem _appearance = default!; - [Dependency] private readonly EntityLookupSystem _lookup = default!; - [Dependency] private readonly SolutionContainerSystem _solutionSystem = default!; [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly AppearanceSystem _appearance = default!; + [Dependency] private readonly BloodstreamSystem _blood = default!; + [Dependency] private readonly InternalsSystem _internals = default!; + [Dependency] private readonly ReactiveSystem _reactive = default!; + [Dependency] private readonly SharedBroadphaseSystem _broadphase = default!; + [Dependency] private readonly SharedPhysicsSystem _physics = default!; + [Dependency] private readonly SolutionContainerSystem _solutionSystem = default!; + [Dependency] private readonly TransformSystem _transform = default!; + + private EntityQuery _smokeQuery; + private EntityQuery _smokeAffectedQuery; /// public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnSmokeUnpaused); + + _smokeQuery = GetEntityQuery(); + _smokeAffectedQuery = GetEntityQuery(); + + SubscribeLocalEvent(OnStartCollide); + SubscribeLocalEvent(OnEndCollide); SubscribeLocalEvent(OnReactionAttempt); SubscribeLocalEvent(OnSmokeSpread); + SubscribeLocalEvent(OnAffectedUnpaused); + } + + /// + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + var curTime = _timing.CurTime; + while (query.MoveNext(out var uid, out var smoke)) + { + if (curTime < smoke.NextSecond) + continue; + + smoke.NextSecond += TimeSpan.FromSeconds(1); + SmokeReact(uid, smoke.SmokeEntity); + } + } + + private void OnStartCollide(EntityUid uid, SmokeComponent component, ref StartCollideEvent args) + { + if (_smokeAffectedQuery.HasComponent(args.OtherEntity)) + return; + + var smokeAffected = AddComp(args.OtherEntity); + smokeAffected.SmokeEntity = uid; + smokeAffected.NextSecond = _timing.CurTime + TimeSpan.FromSeconds(1); + } + + private void OnEndCollide(EntityUid uid, SmokeComponent component, ref EndCollideEvent args) + { + // if we are already in smoke, make sure the thing we are exiting is the current smoke we are in. + if (_smokeAffectedQuery.TryGetComponent(args.OtherEntity, out var smokeAffectedComponent)) + { + if (smokeAffectedComponent.SmokeEntity != uid) + return; + } + + var exists = Exists(uid); + + if (!TryComp(args.OtherEntity, out var body)) + return; + + foreach (var ent in _physics.GetContactingEntities(args.OtherEntity, body)) + { + if (exists && ent == uid) + continue; + + if (!_smokeQuery.HasComponent(ent)) + continue; + + smokeAffectedComponent ??= EnsureComp(args.OtherEntity); + smokeAffectedComponent.SmokeEntity = ent; + return; // exit the function so we don't remove the component. + } + + if (smokeAffectedComponent != null) + RemComp(args.OtherEntity, smokeAffectedComponent); + } + + private void OnAffectedUnpaused(EntityUid uid, SmokeAffectedComponent component, ref EntityUnpausedEvent args) + { + component.NextSecond += args.PausedTime; } private void OnSmokeSpread(EntityUid uid, SmokeComponent component, ref SpreadNeighborsEvent args) { - if (component.SpreadAmount == 0 - || !_solutionSystem.TryGetSolution(uid, SmokeComponent.SolutionName, out var solution)) + if (component.SpreadAmount == 0 || !_solutionSystem.TryGetSolution(uid, SmokeComponent.SolutionName, out var solution)) { RemCompDeferred(uid); return; } - var prototype = MetaData(uid).EntityPrototype; - - if (prototype == null) + if (Prototype(uid) is not { } prototype) { RemCompDeferred(uid); return; } + if (!args.NeighborFreeTiles.Any()) + return; + TryComp(uid, out var timer); - _appearance.TryGetData(uid, SmokeVisuals.Color, out var color); // wtf is the logic behind any of this. - var smokePerSpread = 1 + component.SpreadAmount / Math.Max(1, args.NeighborFreeTiles.Count); + var smokePerSpread = component.SpreadAmount / Math.Max(1, args.NeighborFreeTiles.Count); foreach (var neighbor in args.NeighborFreeTiles) { var coords = neighbor.Grid.GridTileToLocal(neighbor.Tile); var ent = Spawn(prototype.ID, coords); - var neighborSmoke = EnsureComp(ent); - neighborSmoke.SpreadAmount = Math.Max(0, smokePerSpread - 2); // why - 2? who the fuck knows. - component.SpreadAmount--; - args.Updates--; + var spreadAmount = Math.Max(0, smokePerSpread); + component.SpreadAmount -= args.NeighborFreeTiles.Count(); - // Listen this is the old behaviour iunno - Start(ent, neighborSmoke, solution.Clone(), timer?.Lifetime ?? 10f); - - if (color != null) - _appearance.SetData(ent, SmokeVisuals.Color, color); + StartSmoke(ent, solution.Clone(), timer?.Lifetime ?? component.Duration, spreadAmount); if (component.SpreadAmount == 0) { RemCompDeferred(uid); break; } - - if (args.Updates <= 0) - break; } + args.Updates--; + if (args.NeighborFreeTiles.Count > 0 || args.Neighbors.Count == 0 || component.SpreadAmount < 1) return; @@ -100,7 +179,6 @@ public sealed class SmokeSystem : EntitySystem continue; smoke.SpreadAmount++; - args.Updates--; component.SpreadAmount--; EnsureComp(neighbor); @@ -110,6 +188,7 @@ public sealed class SmokeSystem : EntitySystem break; } } + } private void OnReactionAttempt(EntityUid uid, SmokeComponent component, ReactionAttemptEvent args) @@ -128,101 +207,117 @@ public sealed class SmokeSystem : EntitySystem } } - private void OnSmokeUnpaused(EntityUid uid, SmokeComponent component, ref EntityUnpausedEvent args) + /// + /// Sets up a smoke component for spreading. + /// + public void StartSmoke(EntityUid uid, Solution solution, float duration, int spreadAmount, SmokeComponent? component = null) { - component.NextReact += args.PausedTime; - } + if (!Resolve(uid, ref component)) + return; - /// - public override void Update(float frameTime) - { - base.Update(frameTime); - var query = EntityQueryEnumerator(); - var curTime = _timing.CurTime; + component.SpreadAmount = spreadAmount; + component.Duration = duration; + component.TransferRate = solution.Volume / duration; + TryAddSolution(uid, solution); + Dirty(uid, component); + EnsureComp(uid); - while (query.MoveNext(out var uid, out var smoke)) + if (TryComp(uid, out var body) && TryComp(uid, out var fixtures)) { - if (smoke.NextReact > curTime) - continue; - - smoke.NextReact += TimeSpan.FromSeconds(1.5); - - SmokeReact(uid, 1f, smoke); + var xform = Transform(uid); + _physics.SetBodyType(uid, BodyType.Dynamic, fixtures, body, xform); + _physics.SetCanCollide(uid, true, manager: fixtures, body: body); + _broadphase.RegenerateContacts(uid, body, fixtures, xform); } + + var timer = EnsureComp(uid); + timer.Lifetime = duration; + + // The tile reaction happens here because it only occurs once. + ReactOnTile(uid, component); } /// - /// Does the relevant smoke reactions for an entity for the specified exposure duration. + /// Does the relevant smoke reactions for an entity. /// - public void SmokeReact(EntityUid uid, float frameTime, SmokeComponent? component = null, TransformComponent? xform = null) + public void SmokeReact(EntityUid entity, EntityUid smokeUid, SmokeComponent? component = null) { - if (!Resolve(uid, ref component, ref xform)) + if (!Resolve(smokeUid, ref component)) return; - if (!_solutionSystem.TryGetSolution(uid, SmokeComponent.SolutionName, out var solution) || + if (!_solutionSystem.TryGetSolution(smokeUid, SmokeComponent.SolutionName, out var solution) || solution.Contents.Count == 0) { return; } + ReactWithEntity(entity, smokeUid, solution, component); + UpdateVisuals(smokeUid); + } + + private void ReactWithEntity(EntityUid entity, EntityUid smokeUid, Solution solution, SmokeComponent? component = null) + { + if (!Resolve(smokeUid, ref component)) + return; + + if (!TryComp(entity, out var bloodstream)) + return; + + var blockIngestion = _internals.AreInternalsWorking(entity); + + var cloneSolution = solution.Clone(); + var availableTransfer = FixedPoint2.Min(cloneSolution.Volume, component.TransferRate); + var transferAmount = FixedPoint2.Min(availableTransfer, bloodstream.ChemicalSolution.AvailableVolume); + var transferSolution = cloneSolution.SplitSolution(transferAmount); + + foreach (var reagentQuantity in transferSolution.Contents.ToArray()) + { + if (reagentQuantity.Quantity == FixedPoint2.Zero) + continue; + var reagentProto = _prototype.Index(reagentQuantity.Reagent.Prototype); + + _reactive.ReactionEntity(entity, ReactionMethod.Touch, reagentProto, reagentQuantity, transferSolution); + if (!blockIngestion) + _reactive.ReactionEntity(entity, ReactionMethod.Ingestion, reagentProto, reagentQuantity, transferSolution); + } + + if (blockIngestion) + return; + + if (_blood.TryAddToChemicals(entity, transferSolution, bloodstream)) + { + // Log solution addition by smoke + _logger.Add(LogType.ForceFeed, LogImpact.Medium, $"{ToPrettyString(entity):target} ingested smoke {SolutionContainerSystem.ToPrettyString(transferSolution)}"); + } + } + + private void ReactOnTile(EntityUid uid, SmokeComponent? component = null, TransformComponent? xform = null) + { + if (!Resolve(uid, ref component, ref xform)) + return; + + if (!_solutionSystem.TryGetSolution(uid, SmokeComponent.SolutionName, out var solution) || !solution.Any()) + return; + if (!_mapManager.TryGetGrid(xform.GridUid, out var mapGrid)) return; - var tile = mapGrid.GetTileRef(xform.Coordinates.ToVector2i(EntityManager, _mapManager)); - - var solutionFraction = 1 / Math.Floor(frameTime); - var ents = _lookup.GetEntitiesIntersecting(tile, 0f, flags: LookupFlags.Uncontained).ToArray(); + var tile = mapGrid.GetTileRef(xform.Coordinates.ToVector2i(EntityManager, _mapManager, _transform)); foreach (var reagentQuantity in solution.Contents.ToArray()) { if (reagentQuantity.Quantity == FixedPoint2.Zero) continue; - // NOOP, react with entities on the tile or whatever. + var reagent = _prototype.Index(reagentQuantity.Reagent.Prototype); + reagent.ReactionTile(tile, reagentQuantity.Quantity); } - - foreach (var entity in ents) - { - if (entity == uid) - continue; - - ReactWithEntity(entity, solution, solutionFraction); - } - - UpdateVisuals(uid); - } - - private void UpdateVisuals(EntityUid uid) - { - if (TryComp(uid, out AppearanceComponent? appearance) && - _solutionSystem.TryGetSolution(uid, SmokeComponent.SolutionName, out var solution)) - { - var color = solution.GetColor(_prototype); - _appearance.SetData(uid, SmokeVisuals.Color, color, appearance); - } - } - - private void ReactWithEntity(EntityUid entity, Solution solution, double solutionFraction) - { - // NOOP due to people complaining constantly. - return; - } - - /// - /// Sets up a smoke component for spreading. - /// - public void Start(EntityUid uid, SmokeComponent component, Solution solution, float duration) - { - TryAddSolution(uid, component, solution); - EnsureComp(uid); - var timer = EnsureComp(uid); - timer.Lifetime = duration; } /// /// Adds the specified solution to the relevant smoke solution. /// - public void TryAddSolution(EntityUid uid, SmokeComponent component, Solution solution) + private void TryAddSolution(EntityUid uid, Solution solution) { if (solution.Volume == FixedPoint2.Zero) return; @@ -237,4 +332,14 @@ public sealed class SmokeSystem : EntitySystem UpdateVisuals(uid); } + + private void UpdateVisuals(EntityUid uid) + { + if (!TryComp(uid, out AppearanceComponent? appearance) || + !_solutionSystem.TryGetSolution(uid, SmokeComponent.SolutionName, out var solution)) + return; + + var color = solution.GetColor(_prototype); + _appearance.SetData(uid, SmokeVisuals.Color, color, appearance); + } } diff --git a/Content.Server/StationEvents/Components/VentClogRuleComponent.cs b/Content.Server/StationEvents/Components/VentClogRuleComponent.cs index 79ebc520c8..afb3a36326 100644 --- a/Content.Server/StationEvents/Components/VentClogRuleComponent.cs +++ b/Content.Server/StationEvents/Components/VentClogRuleComponent.cs @@ -12,7 +12,7 @@ public sealed partial class VentClogRuleComponent : Component /// Somewhat safe chemicals to put in foam that probably won't instantly kill you. /// There is a small chance of using any reagent, ignoring this. /// - [DataField("safeishVentChemicals", customTypeSerializer: typeof(PrototypeIdListSerializer))] + [DataField(customTypeSerializer: typeof(PrototypeIdListSerializer))] public IReadOnlyList SafeishVentChemicals = new[] { "Water", "Blood", "Slime", "SpaceDrugs", "SpaceCleaner", "Nutriment", "Sugar", "SpaceLube", "Ephedrine", "Ale", "Beer", "SpaceGlue" @@ -21,31 +21,31 @@ public sealed partial class VentClogRuleComponent : Component /// /// Sound played when foam is being created. /// - [DataField("sound")] + [DataField] public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/Effects/extinguish.ogg"); /// - /// The standard reagent quantity to put in the foam, modfied by event severity. + /// The standard reagent quantity to put in the foam, modified by event severity. /// - [DataField("reagentQuantity"), ViewVariables(VVAccess.ReadWrite)] - public int ReagentQuantity = 200; + [DataField, ViewVariables(VVAccess.ReadWrite)] + public int ReagentQuantity = 100; /// - /// The standard spreading of the foam, not modfied by event severity. + /// The standard spreading of the foam, not modified by event severity. /// - [DataField("spread"), ViewVariables(VVAccess.ReadWrite)] - public int Spread = 20; + [DataField, ViewVariables(VVAccess.ReadWrite)] + public int Spread = 16; /// /// How long the foam lasts for /// - [DataField("time"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public float Time = 20f; /// /// Reagents that gets the weak numbers used instead of regular ones. /// - [DataField("weakReagents", customTypeSerializer: typeof(PrototypeIdListSerializer))] + [DataField(customTypeSerializer: typeof(PrototypeIdListSerializer))] public IReadOnlyList WeakReagents = new[] { "SpaceLube", "SpaceGlue" @@ -54,12 +54,12 @@ public sealed partial class VentClogRuleComponent : Component /// /// Quantity of weak reagents to put in the foam. /// - [DataField("weakReagentQuantity"), ViewVariables(VVAccess.ReadWrite)] - public int WeakReagentQuantity = 60; + [DataField, ViewVariables(VVAccess.ReadWrite)] + public int WeakReagentQuantity = 50; /// /// Spread of the foam for weak reagents. /// - [DataField("weakSpread"), ViewVariables(VVAccess.ReadWrite)] - public int WeakSpread = 2; + [DataField, ViewVariables(VVAccess.ReadWrite)] + public int WeakSpread = 3; } diff --git a/Content.Server/StationEvents/Events/VentClogRule.cs b/Content.Server/StationEvents/Events/VentClogRule.cs index 5ef28304e7..f378aec3fb 100644 --- a/Content.Server/StationEvents/Events/VentClogRule.cs +++ b/Content.Server/StationEvents/Events/VentClogRule.cs @@ -3,10 +3,8 @@ using Content.Server.Station.Components; using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Reagent; using JetBrains.Annotations; -using Robust.Shared.Audio; using Robust.Shared.Random; using System.Linq; -using Content.Server.Chemistry.Components; using Content.Server.Fluids.EntitySystems; using Content.Server.GameTicking.Rules.Components; using Content.Server.StationEvents.Components; @@ -53,9 +51,8 @@ public sealed class VentClogRule : StationEventSystem solution.AddReagent(reagent, quantity); var foamEnt = Spawn("Foam", transform.Coordinates); - var smoke = EnsureComp(foamEnt); - smoke.SpreadAmount = weak ? component.WeakSpread : component.Spread; - _smoke.Start(foamEnt, smoke, solution, component.Time); + var spreadAmount = weak ? component.WeakSpread : component.Spread; + _smoke.StartSmoke(foamEnt, solution, component.Time, spreadAmount); Audio.PlayPvs(component.Sound, transform.Coordinates); } } diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Systems/FoamArtifactSystem.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Systems/FoamArtifactSystem.cs index 93d9d5a01b..2d2c230b12 100644 --- a/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Systems/FoamArtifactSystem.cs +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Systems/FoamArtifactSystem.cs @@ -1,5 +1,4 @@ using System.Linq; -using Content.Server.Chemistry.Components; using Content.Server.Fluids.EntitySystems; using Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Components; using Content.Server.Xenoarchaeology.XenoArtifacts.Events; @@ -38,8 +37,7 @@ public sealed class FoamArtifactSystem : EntitySystem var range = (int) MathF.Round(MathHelper.Lerp(component.MinFoamAmount, component.MaxFoamAmount, _random.NextFloat(0, 1f))); sol.AddReagent(component.SelectedReagent, component.ReagentAmount); var foamEnt = Spawn("Foam", xform.Coordinates); - var smoke = EnsureComp(foamEnt); - smoke.SpreadAmount = range * 4; - _smoke.Start(foamEnt, smoke, sol, component.Duration); + var spreadAmount = range * 4; + _smoke.StartSmoke(foamEnt, sol, component.Duration, spreadAmount); } } diff --git a/Content.Shared/Chemistry/Components/SmokeAffectedComponent.cs b/Content.Shared/Chemistry/Components/SmokeAffectedComponent.cs new file mode 100644 index 0000000000..def6940ee1 --- /dev/null +++ b/Content.Shared/Chemistry/Components/SmokeAffectedComponent.cs @@ -0,0 +1,24 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; + +namespace Content.Shared.Chemistry.Components; + +/// +/// This is used for entities which are currently being affected by smoke. +/// Manages the gradual metabolism every second. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class SmokeAffectedComponent : Component +{ + /// + /// The time at which the next smoke metabolism will occur. + /// + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] + public TimeSpan NextSecond; + + /// + /// The smoke that is currently affecting this entity. + /// + [DataField] + public EntityUid SmokeEntity; +} diff --git a/Content.Shared/Chemistry/Components/SmokeComponent.cs b/Content.Shared/Chemistry/Components/SmokeComponent.cs new file mode 100644 index 0000000000..9d88fcac94 --- /dev/null +++ b/Content.Shared/Chemistry/Components/SmokeComponent.cs @@ -0,0 +1,34 @@ +using Content.Shared.FixedPoint; +using Content.Shared.Fluids.Components; +using Robust.Shared.GameStates; + +namespace Content.Shared.Chemistry.Components; + +/// +/// Stores solution on an anchored entity that has touch and ingestion reactions +/// to entities that collide with it. Similar to +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class SmokeComponent : Component +{ + public const string SolutionName = "solutionArea"; + + /// + /// The max amount of tiles this smoke cloud can spread to. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public int SpreadAmount; + + /// + /// The max rate at which chemicals are transferred from the smoke to the person inhaling it. + /// Calculated as (total volume of chemicals in smoke) / () + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public FixedPoint2 TransferRate; + + /// + /// The total lifespan of the smoke. + /// + [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public float Duration = 10; +} From f4c3d66b1c2ecad9a1799cd71a7adca4fab4551d Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 26 Oct 2023 22:53:15 -0400 Subject: [PATCH 077/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index d34ce7a7f4..5eab7e36a5 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,10 +1,4 @@ Entries: -- author: DrSmugleaf - changes: - - {message: 'Fixed new players added to admin logs defaulting to selected, even - when not all players are selected.', type: Fix} - id: 4569 - time: '2023-08-14T01:53:48.0000000+00:00' - author: Vordenburg changes: - {message: Substations produce hot CO2 when destroyed now., type: Tweak} @@ -2899,3 +2893,10 @@ Entries: modules., type: Add} id: 5068 time: '2023-10-27T02:40:13.0000000+00:00' +- author: EmoGarbage404 + changes: + - {message: Foam and smoke can now transfer chemicals when inhaled. Wear internals + to avoid this., type: Add} + - {message: Fixed foam dissolution animation., type: Fix} + id: 5069 + time: '2023-10-27T02:52:11.0000000+00:00' From 5585cbf82280536cb95c93b6932e35959ee0daad Mon Sep 17 00:00:00 2001 From: Whisper <121047731+QuietlyWhisper@users.noreply.github.com> Date: Fri, 27 Oct 2023 09:54:43 -0400 Subject: [PATCH 078/102] ERT Loadout overhaul + Real deathsquad mobs + ERT fixes (#21230) * "assist with medical efforts" * CentComm official description change * give cburn ert mask * Ert medic hardsuit uses blood-red medic values * description changes, they all used to use the blood-red description * ert engineer hardsuit uses cburn values, good for handling all possible engineering problems. * janitor hardsuit uses cburn values for extreme messes, otherwise we'd send the non eva variant. * spawn suffix changes * shorten suffix * drop armor from ert jumpsuits * drop armor from DS jumpsuit * add more armor to death squad to make up for removed armor in the uniform. * give sec gas masks armor, give syndicate gas masks armor. ERT gas mask uses syndicate mask values * add nanotrasen * removed duplicate * give centcom IDs their hud icon * replace all ert bulletproof armor with basic universal armor * replace all oxygen tanks with air tanks; species is random. * remove gun and meds from ert engineer kit * give ert engineer materials * remove weapons and meds from janitor ert * give ert janitor light replacer * remove ert sec pulse weapons, admins will assign loadout. Either the lecter or enforcer, probably. * Give ert sec the security pistol kit * typo * give eva ert sec pistol * give eva janitor ert gas mask * give jani purple gloves * medical gloves for medical ert * replicate security loadout to leader * quick ert lecter spawns for lazy admins * better suffixes to find them easier * add cburn to ertspawn * Replace "Spawn" with "role" * Add death squad. Give ert engineer gas analyzer. * death squad using wrong equipment * typo * missing ghost roles on lecter loadouts * add freedom implanter to deathsquad * deathsquad ghost role text * Operative sounds better * give Ds flashbang box (why isn't it entirely filled?) * fix typo. add energy shield to DS * fix typos * all centcomm roles are now mindshielded. These cannot be removed. * Rider didnt include some of the changes ? * give zipties instead of cuffs for mass arrests! * upgrade ERT survival boxes to extended capacity * give cburn extended oxygen too --- .../ghost/roles/ghost-role-component.ftl | 9 +- .../Locale/en-US/job/job-description.ftl | 2 +- .../Fills/Backpacks/StarterGear/backpack.yml | 58 +++++++--- .../Catalog/Fills/Backpacks/duffelbag.yml | 2 + .../Prototypes/Catalog/Fills/Items/belt.yml | 3 +- .../Entities/Clothing/Masks/masks.yml | 21 +++- .../Clothing/OuterClothing/hardsuits.yml | 22 ++-- .../Entities/Clothing/Uniforms/jumpsuits.yml | 25 +---- .../Entities/Mobs/Player/humanoid.yml | 102 +++++++++++++++++- .../Entities/Objects/Devices/pda.yml | 2 +- .../Objects/Misc/identification_cards.yml | 3 +- .../Weapons/Guns/Battery/battery_guns.yml | 10 +- .../Roles/Jobs/Fun/emergencyresponseteam.yml | 80 ++++++++++---- .../Roles/Jobs/Fun/misc_startinggear.yml | 11 +- 14 files changed, 254 insertions(+), 96 deletions(-) diff --git a/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl b/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl index 9ab3e77cb6..5685005891 100644 --- a/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl +++ b/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl @@ -150,13 +150,13 @@ ghost-role-information-ert-security-name = ERT Security ghost-role-information-ert-security-description = Assist with security efforts to resolve the stations issues. ghost-role-information-ert-medical-name = ERT Medical -ghost-role-information-ert-medical-description = Assist with medicaling efforts to resolve the stations issues. +ghost-role-information-ert-medical-description = Assist with medical efforts to resolve the stations issues. ghost-role-information-cburn-agent-name = CBURN Agent ghost-role-information-cburn-agent-description = A highly trained CentCom agent, capable of dealing with various threats. -ghost-role-information-centcom-official-name = CentCom official -ghost-role-information-centcom-official-description = Inspect the station, jot down performance reviews for heads of staff, bug the Captain. +ghost-role-information-centcom-official-name = CentComm official +ghost-role-information-centcom-official-description = Perform CentComm related duties such as inspect the station, jotting down performance reviews for heads of staff, and managing the fax machine. ghost-role-information-nukeop-rules = You are a syndicate operative tasked with the destruction of the station. As an antagonist, do whatever is required to complete this task. @@ -166,3 +166,6 @@ ghost-role-information-loneop-rules = You are a syndicate operative tasked with ghost-role-information-behonker-name = Behonker ghost-role-information-behonker-description = You are an antagonist, bring death and honks to those who do not follow the honkmother. + +ghost-role-information-Death-Squad-name = Death Squad Operative +ghost-role-information-Death-Squad-description = Prepare for an all-out offensive on the station. As a heavily armed operative, your mission is to obliterate all life in your path. No witnesses. diff --git a/Resources/Locale/en-US/job/job-description.ftl b/Resources/Locale/en-US/job/job-description.ftl index bc27f7fbca..db4686102d 100644 --- a/Resources/Locale/en-US/job/job-description.ftl +++ b/Resources/Locale/en-US/job/job-description.ftl @@ -47,4 +47,4 @@ job-description-zookeeper = Put on a joyful display of cute animals and space ca job-description-senior-engineer = Teach new engineers the basics of the station's engine, repairing, atmospherics and power. job-description-senior-researcher = Teach new scientists the basics of item printing, artifact research and anomalous objects. job-description-senior-physician = Teach new medics the basics of tending to the wounded, chemistry, diagnosing the diseased and disposing of the dead. -job-description-senior-officer = Teach new officers the basics of searches, preforming arrests, prison times and how to properly shoot a firearm. +job-description-senior-officer = Teach new officers the basics of searches, performing arrests, prison times and how to properly shoot a firearm. diff --git a/Resources/Prototypes/Catalog/Fills/Backpacks/StarterGear/backpack.yml b/Resources/Prototypes/Catalog/Fills/Backpacks/StarterGear/backpack.yml index 1e0788cccd..435c2036b2 100644 --- a/Resources/Prototypes/Catalog/Fills/Backpacks/StarterGear/backpack.yml +++ b/Resources/Prototypes/Catalog/Fills/Backpacks/StarterGear/backpack.yml @@ -28,7 +28,7 @@ - id: BoxSurvivalSecurity - id: Flash - id: MagazinePistol - + - type: entity noSpawn: true parent: ClothingBackpackSecurity @@ -236,14 +236,13 @@ components: - type: StorageFill contents: - - id: BoxSurvival - - id: WeaponPulseCarbine - - id: WeaponPulsePistol + - id: BoxSurvivalEngineering - id: WeaponDisabler - id: MedicatedSuture - id: RegenerativeMesh - - id: Handcuffs + - id: BoxZiptie - id: CrowbarRed + - id: MagazinePistol - type: entity noSpawn: true @@ -252,14 +251,13 @@ components: - type: StorageFill contents: - - id: BoxSurvival + - id: BoxSurvivalEngineering - id: WeaponDisabler - - id: WeaponPulsePistol - - id: WeaponPulseCarbine - id: MedicatedSuture - id: RegenerativeMesh - - id: BoxHandcuff + - id: BoxZiptie - id: CrowbarRed + - id: MagazinePistol - type: entity noSpawn: true @@ -284,17 +282,18 @@ components: - type: StorageFill contents: - - id: BoxSurvival + - id: BoxSurvivalEngineering - id: trayScanner - - id: WeaponPulseCarbine - - id: MedicatedSuture - - id: RegenerativeMesh - id: RCD - id: RCDAmmo - id: RCDAmmo - id: RCDAmmo - id: CableMVStack - id: CableHVStack + - id: CableApcStack + - id: SheetPlasteel + - id: SheetSteel + - id: SheetGlass - type: entity noSpawn: true @@ -303,15 +302,40 @@ components: - type: StorageFill contents: - - id: BoxSurvival - - id: WeaponPulsePistol - - id: MedkitFilled + - id: BoxSurvivalEngineering + - id: LightReplacer - id: BoxLightMixed - id: BoxLightMixed - id: Soap - id: CrowbarRed - id: AdvMopItem +# Death Squad + +- type: entity + noSpawn: false + parent: ClothingBackpackERTSecurity + id: ClothingBackpackDeathSquadFilled + name: death squad backpack + description: Holds the kit of CentComm's most feared agents. + components: + - type: StorageFill + contents: + - id: BoxSurvivalEngineering + - id: WeaponPulseRifle + - id: WeaponPulsePistol + - id: WeaponRevolverMateba + - id: SpeedLoaderMagnumAP + - id: SpeedLoaderMagnumAP + - id: BoxFlashbang + - id: ToolDebug # spanish army knife + - id: WelderExperimental + - id: Hypospray + - id: MicroBombImplanter # crew will try to steal their amazing hardsuits + - id: FreedomImplanter + +# Cargo + - type: entity noSpawn: true parent: ClothingBackpackCargo @@ -330,6 +354,8 @@ contents: - id: BoxSurvival +# Pirate + - type: entity parent: ClothingBackpackSatchelLeather id: ClothingBackpackPirateFilled diff --git a/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml b/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml index 12f31bc016..7c330a9a76 100644 --- a/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml +++ b/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml @@ -21,6 +21,7 @@ components: - type: StorageFill contents: + - id: BoxSurvivalEngineering - id: WeaponShotgunDoubleBarreled - id: BoxShotgunIncendiary amount: 2 @@ -313,6 +314,7 @@ - id: HandheldHealthAnalyzer - id: CombatMedipen - id: MicroBombImplanter + - id: SyndiHypo - type: entity parent: ClothingBackpackDuffelSyndicateMedicalBundle diff --git a/Resources/Prototypes/Catalog/Fills/Items/belt.yml b/Resources/Prototypes/Catalog/Fills/Items/belt.yml index 1886b961c8..8f85b9dfe1 100644 --- a/Resources/Prototypes/Catalog/Fills/Items/belt.yml +++ b/Resources/Prototypes/Catalog/Fills/Items/belt.yml @@ -140,7 +140,6 @@ components: - type: StorageFill contents: - - id: SyndiHypo - id: EpinephrineChemistryBottle amount: 2 - id: EphedrineChemistryBottle @@ -169,4 +168,4 @@ contents: - id: WeaponRevolverInspector - id: SpeedLoaderMagnum - - id: SpeedLoaderMagnumRubber \ No newline at end of file + - id: SpeedLoaderMagnumRubber diff --git a/Resources/Prototypes/Entities/Clothing/Masks/masks.yml b/Resources/Prototypes/Entities/Clothing/Masks/masks.yml index ec11ccfffa..4909d6e393 100644 --- a/Resources/Prototypes/Entities/Clothing/Masks/masks.yml +++ b/Resources/Prototypes/Entities/Clothing/Masks/masks.yml @@ -27,6 +27,13 @@ sprite: Clothing/Mask/gassecurity.rsi - type: Clothing sprite: Clothing/Mask/gassecurity.rsi + - type: Armor + modifiers: + coefficients: + Blunt: 0.95 + Slash: 0.95 + Piercing: 0.95 + Heat: 0.95 - type: entity parent: ClothingMaskGas @@ -40,6 +47,13 @@ sprite: Clothing/Mask/gassyndicate.rsi - type: FlashImmunity - type: EyeProtection + - type: Armor + modifiers: + coefficients: + Blunt: 0.95 + Slash: 0.95 + Piercing: 0.95 + Heat: 0.95 - type: entity parent: ClothingMaskGas @@ -132,6 +146,8 @@ coefficients: Blunt: 0.95 Slash: 0.95 + Piercing: 0.95 + Heat: 0.95 - type: entity parent: ClothingMaskPullableBase @@ -294,7 +310,7 @@ sprite: Clothing/Mask/merc.rsi - type: entity - parent: ClothingMaskGasExplorer + parent: ClothingMaskGasSyndicate id: ClothingMaskGasERT name: ert gas mask description: The gas mask of the elite squad of the ERT. @@ -303,9 +319,6 @@ sprite: Clothing/Mask/ert.rsi - type: Clothing sprite: Clothing/Mask/ert.rsi - - type: FlashImmunity - - type: EyeProtection - protectionTime: 5 - type: entity parent: ClothingMaskGasERT diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml index 5389eb8bfc..d05d9ce8f8 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml @@ -687,7 +687,7 @@ parent: ClothingOuterHardsuitSyndieCommander id: ClothingOuterHardsuitERTLeader name: ERT leader's hardsuit - description: A protective hardsuit worn by members of an emergency response team. + description: A protective hardsuit worn by the leader of an emergency response team. components: - type: Sprite sprite: Clothing/OuterClothing/Hardsuits/ERTSuits/ertleader.rsi @@ -698,9 +698,10 @@ #ERT Engineer Hardsuit - type: entity - parent: ClothingOuterHardsuitSyndie + parent: ClothingOuterHardsuitCBURN id: ClothingOuterHardsuitERTEngineer name: ERT engineer's hardsuit + description: A protective hardsuit worn by the engineers of an emergency response team. components: - type: Sprite sprite: Clothing/OuterClothing/Hardsuits/ERTSuits/ertengineer.rsi @@ -711,9 +712,10 @@ #ERT Medic Hardsuit - type: entity - parent: ClothingOuterHardsuitSyndieElite + parent: ClothingOuterHardsuitMedic id: ClothingOuterHardsuitERTMedical name: ERT medic's hardsuit + description: A protective hardsuit worn by the medics of an emergency response team. components: - type: Sprite sprite: Clothing/OuterClothing/Hardsuits/ERTSuits/ertmedical.rsi @@ -727,6 +729,7 @@ parent: ClothingOuterHardsuitSyndie id: ClothingOuterHardsuitERTSecurity name: ERT security's hardsuit + description: A protective hardsuit worn by the security officers of an emergency response team. components: - type: Sprite sprite: Clothing/OuterClothing/Hardsuits/ERTSuits/ertsecurity.rsi @@ -737,9 +740,10 @@ #ERT Janitor Hardsuit - type: entity - parent: ClothingOuterHardsuitSyndie + parent: ClothingOuterHardsuitCBURN id: ClothingOuterHardsuitERTJanitor name: ERT janitor's hardsuit + description: A protective hardsuit worn by the janitors of an emergency response team. components: - type: Sprite sprite: Clothing/OuterClothing/Hardsuits/ERTSuits/ertjanitor.rsi @@ -752,7 +756,7 @@ - type: entity parent: ClothingOuterHardsuitBase id: ClothingOuterHardsuitDeathsquad - name: deathsquad hardsuit + name: death squad hardsuit description: An advanced hardsuit favored by commandos for use in special operations. components: - type: Sprite @@ -769,12 +773,12 @@ - type: Armor modifiers: coefficients: - Blunt: 0.2 #best armor in the game - Slash: 0.2 - Piercing: 0.2 + Blunt: 0.1 #best armor in the game + Slash: 0.1 + Piercing: 0.1 Heat: 0.1 Radiation: 0.1 - Caustic: 0.2 + Caustic: 0.1 - type: ClothingSpeedModifier walkModifier: 1.0 sprintModifier: 1.0 diff --git a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml index 8f4dbddaa9..e63522d681 100644 --- a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml +++ b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml @@ -1,20 +1,13 @@ - type: entity parent: ClothingUniformBase id: ClothingUniformJumpsuitDeathSquad - name: Death squad uniform + name: death squad uniform description: Advanced armored jumpsuit used by special forces in special operations. components: - type: Sprite sprite: Clothing/Uniforms/Jumpsuit/deathsquad.rsi - type: Clothing sprite: Clothing/Uniforms/Jumpsuit/deathsquad.rsi - - type: Armor - modifiers: - coefficients: - Blunt: 0.8 - Slash: 0.8 - Piercing: 0.8 - Heat: 0.8 - type: entity parent: ClothingUniformBase @@ -1067,10 +1060,6 @@ sprite: Clothing/Uniforms/Jumpsuit/ert_engineer.rsi - type: Clothing sprite: Clothing/Uniforms/Jumpsuit/ert_engineer.rsi - - type: Armor - modifiers: - coefficients: - Radiation: 0.8 - type: entity parent: ClothingUniformBase @@ -1093,12 +1082,6 @@ sprite: Clothing/Uniforms/Jumpsuit/ert_leader.rsi - type: Clothing sprite: Clothing/Uniforms/Jumpsuit/ert_leader.rsi - - type: Armor - modifiers: - coefficients: - Blunt: 0.8 - Slash: 0.8 - Piercing: 0.8 - type: entity parent: ClothingUniformBase @@ -1121,12 +1104,6 @@ sprite: Clothing/Uniforms/Jumpsuit/ert_security.rsi - type: Clothing sprite: Clothing/Uniforms/Jumpsuit/ert_security.rsi - - type: Armor - modifiers: - coefficients: - Blunt: 0.8 - Slash: 0.8 - Piercing: 0.8 - type: entity parent: ClothingUniformJumpsuitClown diff --git a/Resources/Prototypes/Entities/Mobs/Player/humanoid.yml b/Resources/Prototypes/Entities/Mobs/Player/humanoid.yml index 6aa53f6875..f83d3f2794 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/humanoid.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/humanoid.yml @@ -1,10 +1,45 @@ # Random humanoids +## Death Squad + +- type: entity + id: RandomHumanoidSpawnerDeathSquad + name: Death Squad Agent + suffix: ERTRole, Death Squad + components: + - type: Sprite + sprite: Clothing/OuterClothing/Hardsuits/deathsquad.rsi + state: icon + - type: RandomMetadata + nameSegments: + - NamesFirstMilitaryLeader + - names_last + - type: RandomHumanoidSpawner + settings: DeathSquad + +- type: randomHumanoidSettings + id: DeathSquad + randomizeName: false + components: + - type: MindShield + - type: GhostRole + name: ghost-role-information-Death-Squad-name + description: ghost-role-information-Death-Squad-description + - type: GhostTakeoverAvailable + - type: Loadout + prototypes: [ DeathSquadGear ] + - type: RandomMetadata + nameSegments: + - NamesFirstMilitaryLeader + - names_last + + ## ERT Leader - type: entity id: RandomHumanoidSpawnerERTLeader name: ERT leader + suffix: ERTRole, Basic components: - type: Sprite sprite: Markers/jobs.rsi @@ -20,6 +55,7 @@ id: ERTLeader randomizeName: false components: + - type: MindShield - type: GhostRole name: ghost-role-information-ert-leader-name description: ghost-role-information-ert-leader-description @@ -35,7 +71,7 @@ id: RandomHumanoidSpawnerERTLeaderEVA parent: RandomHumanoidSpawnerERTLeader name: ERT leader - suffix: EVA + suffix: ERTRole, Armored EVA components: - type: Sprite sprite: Markers/jobs.rsi @@ -47,6 +83,7 @@ id: ERTLeaderEVA parent: ERTLeader components: + - type: MindShield - type: GhostRole name: ghost-role-information-ert-leader-name description: ghost-role-information-ert-leader-description @@ -54,12 +91,33 @@ - type: Loadout prototypes: [ ERTLeaderGearEVA ] +- type: entity + id: RandomHumanoidSpawnerERTLeaderEVALecter + parent: RandomHumanoidSpawnerERTLeaderEVA + suffix: ERTRole, Lecter, EVA + components: + - type: RandomHumanoidSpawner + settings: ERTLeaderEVALecter + +- type: randomHumanoidSettings + id: ERTLeaderEVALecter + parent: ERTLeaderEVA + components: + - type: MindShield + - type: GhostRole + name: ghost-role-information-ert-leader-name + description: ghost-role-information-ert-leader-description + - type: GhostTakeoverAvailable + - type: Loadout + prototypes: [ ERTLeaderGearEVALecter ] + ## ERT Janitor - type: entity id: RandomHumanoidSpawnerERTJanitor parent: RandomHumanoidSpawnerERTLeader name: ERT janitor + suffix: ERTRole, Basic components: - type: Sprite sprite: Markers/jobs.rsi @@ -75,6 +133,7 @@ id: ERTJanitor parent: ERTLeader components: + - type: MindShield - type: GhostRole name: ghost-role-information-ert-janitor-name description: ghost-role-information-ert-janitor-description @@ -90,7 +149,7 @@ id: RandomHumanoidSpawnerERTJanitorEVA parent: RandomHumanoidSpawnerERTJanitor name: ERT janitor - suffix: EVA + suffix: ERTRole, Enviro EVA components: - type: Sprite sprite: Markers/jobs.rsi @@ -102,6 +161,7 @@ id: ERTJanitorEVA parent: ERTJanitor components: + - type: MindShield - type: GhostRole name: ghost-role-information-ert-janitor-name description: ghost-role-information-ert-janitor-description @@ -115,6 +175,7 @@ id: RandomHumanoidSpawnerERTEngineer parent: RandomHumanoidSpawnerERTLeader name: ERT engineer + suffix: ERTRole, Basic components: - type: Sprite sprite: Markers/jobs.rsi @@ -130,6 +191,7 @@ id: ERTEngineer parent: ERTLeader components: + - type: MindShield - type: GhostRole name: ghost-role-information-ert-engineer-name description: ghost-role-information-ert-engineer-description @@ -145,7 +207,7 @@ id: RandomHumanoidSpawnerERTEngineerEVA parent: RandomHumanoidSpawnerERTEngineer name: ERT engineer - suffix: EVA + suffix: ERTRole, Enviro EVA components: - type: Sprite sprite: Markers/jobs.rsi @@ -157,6 +219,7 @@ id: ERTEngineerEVA parent: ERTEngineer components: + - type: MindShield - type: GhostRole name: ghost-role-information-ert-engineer-name description: ghost-role-information-ert-engineer-description @@ -170,6 +233,7 @@ id: RandomHumanoidSpawnerERTSecurity parent: RandomHumanoidSpawnerERTLeader name: ERT security + suffix: ERTRole, Basic components: - type: Sprite sprite: Markers/jobs.rsi @@ -185,6 +249,7 @@ id: ERTSecurity parent: ERTLeader components: + - type: MindShield - type: GhostRole name: ghost-role-information-ert-security-name description: ghost-role-information-ert-security-description @@ -200,7 +265,7 @@ id: RandomHumanoidSpawnerERTSecurityEVA parent: RandomHumanoidSpawnerERTSecurity name: ERT security - suffix: EVA + suffix: ERTRole, Armored EVA components: - type: Sprite sprite: Markers/jobs.rsi @@ -212,6 +277,7 @@ id: ERTSecurityEVA parent: ERTSecurity components: + - type: MindShield - type: GhostRole name: ghost-role-information-ert-security-name description: ghost-role-information-ert-security-description @@ -219,12 +285,33 @@ - type: Loadout prototypes: [ ERTSecurityGearEVA ] +- type: entity + id: RandomHumanoidSpawnerERTSecurityEVALecter + parent: RandomHumanoidSpawnerERTSecurityEVA + suffix: ERTRole, Lecter, EVA + components: + - type: RandomHumanoidSpawner + settings: ERTSecurityEVALecter + +- type: randomHumanoidSettings + id: ERTSecurityEVALecter + parent: ERTSecurityEVA + components: + - type: MindShield + - type: GhostRole + name: ghost-role-information-ert-security-name + description: ghost-role-information-ert-security-description + - type: GhostTakeoverAvailable + - type: Loadout + prototypes: [ ERTSecurityGearEVALecter ] + ## ERT Medic - type: entity id: RandomHumanoidSpawnerERTMedical parent: RandomHumanoidSpawnerERTLeader name: ERT medic + suffix: ERTRole, Basic components: - type: Sprite sprite: Markers/jobs.rsi @@ -240,6 +327,7 @@ id: ERTMedical parent: ERTLeader components: + - type: MindShield - type: GhostRole name: ghost-role-information-ert-medical-name description: ghost-role-information-ert-medical-description @@ -255,7 +343,7 @@ id: RandomHumanoidSpawnerERTMedicalEVA parent: RandomHumanoidSpawnerERTMedical name: ERT medic - suffix: EVA + suffix: ERTRole, Armored EVA components: - type: Sprite sprite: Markers/jobs.rsi @@ -267,6 +355,7 @@ id: ERTMedicalEVA parent: ERTMedical components: + - type: MindShield - type: GhostRole name: ghost-role-information-ert-medical-name description: ghost-role-information-ert-medical-description @@ -279,6 +368,7 @@ - type: entity id: RandomHumanoidSpawnerCBURNUnit name: CBURN Agent + suffix: ERTRole components: - type: Sprite sprite: Markers/jobs.rsi @@ -289,6 +379,7 @@ - type: randomHumanoidSettings id: CBURNAgent components: + - type: MindShield - type: Loadout prototypes: [CBURNGear] - type: GhostRole @@ -314,6 +405,7 @@ - type: randomHumanoidSettings id: CentcomOfficial components: + - type: MindShield - type: GhostRole name: ghost-role-information-centcom-official-name description: ghost-role-information-centcom-official-description diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml index f44f1aa998..89c44ed192 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml @@ -660,7 +660,7 @@ - type: entity parent: CentcomPDA id: DeathsquadPDA - suffix: Deathsquad + suffix: Death Squad components: - type: Pda id: CentcomIDCardDeathsquad diff --git a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml index 24462d5113..d1441c341b 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml @@ -447,6 +447,7 @@ heldPrefix: blue - type: IdCard jobTitle: Central Commander + jobIcon: JobIconNanotrasen - type: Access groups: - AllAccess @@ -496,7 +497,7 @@ - type: entity parent: CentcomIDCard id: CentcomIDCardDeathsquad - name: deathsquad ID card + name: death squad ID card components: - type: Sprite layers: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml index 461a6cc437..38875ee9a7 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml @@ -131,7 +131,7 @@ name: pulse pistol parent: BaseWeaponBatterySmall id: WeaponPulsePistol - description: A state of the art energy pistol favoured as a sidearm by the NT-ERT operatives. + description: A state of the art energy pistol favoured as a sidearm by the NT operatives. components: - type: Sprite sprite: Objects/Weapons/Guns/Battery/pulse_pistol.rsi @@ -464,7 +464,7 @@ path: /Audio/Weapons/Guns/Gunshots/taser2.ogg - type: ProjectileBatteryAmmoProvider proto: AnomalousParticleDeltaStrong - fireCost: 100 + fireCost: 100 - type: BatteryWeaponFireModes fireModes: - proto: AnomalousParticleDeltaStrong @@ -476,13 +476,13 @@ - type: Construction graph: UpgradeWeaponPistolCHIMP node: start - + - type: entity name: experimental C.H.I.M.P. handcannon parent: WeaponPistolCHIMP id: WeaponPistolCHIMPUpgraded description: This C.H.I.M.P. seems to have a greater punch than is usual... - components: + components: - type: BatteryWeaponFireModes fireModes: - proto: AnomalousParticleDeltaStrong @@ -490,7 +490,7 @@ - proto: AnomalousParticleEpsilonStrong fireCost: 100 - proto: AnomalousParticleOmegaStrong - fireCost: 100 + fireCost: 100 - proto: AnomalousParticleZetaStrong fireCost: 100 diff --git a/Resources/Prototypes/Roles/Jobs/Fun/emergencyresponseteam.yml b/Resources/Prototypes/Roles/Jobs/Fun/emergencyresponseteam.yml index d71b3423d2..2be50b2e4b 100644 --- a/Resources/Prototypes/Roles/Jobs/Fun/emergencyresponseteam.yml +++ b/Resources/Prototypes/Roles/Jobs/Fun/emergencyresponseteam.yml @@ -21,11 +21,12 @@ head: ClothingHeadHelmetERTLeader eyes: ClothingEyesGlassesSecurity gloves: ClothingHandsGlovesCombat - outerClothing: ClothingOuterArmorBulletproof + outerClothing: ClothingOuterArmorBasicSlim id: ERTLeaderPDA ears: ClothingHeadsetAltCentCom belt: ClothingBeltSecurityFilled - pocket1: Flare + pocket1: WeaponPistolMk58Nonlethal + pocket2: FlashlightSeclite - type: startingGear id: ERTLeaderGearEVA @@ -37,11 +38,31 @@ eyes: ClothingEyesGlassesSecurity gloves: ClothingHandsGlovesCombat outerClothing: ClothingOuterHardsuitERTLeader - suitstorage: OxygenTankFilled + suitstorage: AirTankFilled id: ERTLeaderPDA ears: ClothingHeadsetAltCentCom belt: ClothingBeltSecurityFilled - pocket1: Flare + pocket1: WeaponPistolMk58Nonlethal + pocket2: FlashlightSeclite + +- type: startingGear + id: ERTLeaderGearEVALecter + equipment: + jumpsuit: ClothingUniformJumpsuitERTLeader + back: ClothingBackpackERTLeaderFilled + shoes: ClothingShoesBootsMagAdv + mask: ClothingMaskGasERT + eyes: ClothingEyesGlassesSecurity + gloves: ClothingHandsGlovesCombat + outerClothing: ClothingOuterHardsuitERTLeader + suitstorage: WeaponRifleLecter + id: ERTLeaderPDA + ears: ClothingHeadsetAltCentCom + belt: ClothingBeltSecurityFilled + pocket1: MagazineRifle + pocket2: MagazineRifle + inhand: + - AirTankFilled # Engineer - type: job @@ -66,11 +87,12 @@ head: ClothingHeadHelmetERTEngineer eyes: ClothingEyesGlassesMeson gloves: ClothingHandsGlovesCombat - outerClothing: ClothingOuterArmorBulletproof + outerClothing: ClothingOuterArmorBasicSlim id: ERTLeaderPDA ears: ClothingHeadsetAltCentCom belt: ClothingBeltChiefEngineerFilled pocket1: Flare + pocket2: GasAnalyzer - type: startingGear id: ERTEngineerGearEVA @@ -82,11 +104,12 @@ eyes: ClothingEyesGlassesMeson gloves: ClothingHandsGlovesCombat outerClothing: ClothingOuterHardsuitERTEngineer - suitstorage: OxygenTankFilled + suitstorage: AirTankFilled id: ERTLeaderPDA ears: ClothingHeadsetAltCentCom belt: ClothingBeltChiefEngineerFilled pocket1: Flare + pocket2: GasAnalyzer # Security - type: job @@ -111,11 +134,11 @@ head: ClothingHeadHelmetERTSecurity eyes: ClothingEyesGlassesSecurity gloves: ClothingHandsGlovesCombat - outerClothing: ClothingOuterArmorBulletproof + outerClothing: ClothingOuterArmorBasicSlim id: ERTLeaderPDA ears: ClothingHeadsetAltCentCom belt: ClothingBeltSecurityFilled - pocket1: Flare + pocket1: WeaponPistolMk58Nonlethal pocket2: FlashlightSeclite - type: startingGear @@ -128,13 +151,32 @@ eyes: ClothingEyesGlassesSecurity gloves: ClothingHandsGlovesCombat outerClothing: ClothingOuterHardsuitERTSecurity - suitstorage: OxygenTankFilled + suitstorage: AirTankFilled id: ERTLeaderPDA ears: ClothingHeadsetAltCentCom belt: ClothingBeltSecurityFilled - pocket1: Flare + pocket1: WeaponPistolMk58Nonlethal pocket2: FlashlightSeclite +- type: startingGear + id: ERTSecurityGearEVALecter + equipment: + jumpsuit: ClothingUniformJumpsuitERTSecurity + back: ClothingBackpackERTSecurityFilled + shoes: ClothingShoesBootsMag + mask: ClothingMaskGasERT + eyes: ClothingEyesGlassesSecurity + gloves: ClothingHandsGlovesCombat + outerClothing: ClothingOuterHardsuitERTSecurity + suitstorage: WeaponRifleLecter + id: ERTLeaderPDA + ears: ClothingHeadsetAltCentCom + belt: ClothingBeltSecurityFilled + pocket1: MagazineRifle + pocket2: MagazineRifle + inhand: + - AirTankFilled + # Medical - type: job id: ERTMedical @@ -157,8 +199,8 @@ shoes: ClothingShoesBootsCombatFilled head: ClothingHeadHelmetERTMedic eyes: ClothingEyesHudMedical - gloves: ClothingHandsGlovesCombat - outerClothing: ClothingOuterArmorBulletproof + gloves: ClothingHandsGlovesNitrile + outerClothing: ClothingOuterArmorBasicSlim id: ERTLeaderPDA ears: ClothingHeadsetAltCentCom belt: ClothingBeltMedicalFilled @@ -173,9 +215,9 @@ shoes: ClothingShoesBootsMag mask: ClothingMaskGasERT eyes: ClothingEyesHudMedical - gloves: ClothingHandsGlovesCombat + gloves: ClothingHandsGlovesNitrile outerClothing: ClothingOuterHardsuitERTMedical - suitstorage: OxygenTankFilled + suitstorage: AirTankFilled id: ERTLeaderPDA ears: ClothingHeadsetAltCentCom belt: ClothingBeltMedicalFilled @@ -203,8 +245,8 @@ back: ClothingBackpackERTJanitorFilled shoes: ClothingShoesGaloshes head: ClothingHeadHelmetERTJanitor - gloves: ClothingHandsGlovesColorBlack - outerClothing: ClothingOuterArmorBulletproof + gloves: ClothingHandsGlovesColorPurple + outerClothing: ClothingOuterArmorBasicSlim id: ERTLeaderPDA ears: ClothingHeadsetAltCentCom belt: ClothingBeltJanitorFilled @@ -216,10 +258,10 @@ jumpsuit: ClothingUniformJumpsuitERTJanitor back: ClothingBackpackERTJanitorFilled shoes: ClothingShoesBootsMag - mask: ClothingMaskBreath - gloves: ClothingHandsGlovesColorBlack + mask: ClothingMaskGasERT + gloves: ClothingHandsGlovesColorPurple outerClothing: ClothingOuterHardsuitERTJanitor - suitstorage: OxygenTankFilled + suitstorage: AirTankFilled id: ERTLeaderPDA ears: ClothingHeadsetAltCentCom belt: ClothingBeltJanitorFilled diff --git a/Resources/Prototypes/Roles/Jobs/Fun/misc_startinggear.yml b/Resources/Prototypes/Roles/Jobs/Fun/misc_startinggear.yml index 4a8ede58fe..0061630ad0 100644 --- a/Resources/Prototypes/Roles/Jobs/Fun/misc_startinggear.yml +++ b/Resources/Prototypes/Roles/Jobs/Fun/misc_startinggear.yml @@ -46,20 +46,19 @@ id: DeathSquadGear equipment: jumpsuit: ClothingUniformJumpsuitDeathSquad - back: ClothingBackpackDuffelSyndicateAmmo + back: ClothingBackpackDeathSquadFilled mask: ClothingMaskGasDeathSquad eyes: ClothingEyesGlassesSecurity ears: ClothingHeadsetAltCentCom gloves: ClothingHandsGlovesCombat outerClothing: ClothingOuterHardsuitDeathsquad - suitstorage: OxygenTankFilled + suitstorage: AirTankFilled shoes: ClothingShoesBootsMagAdv id: DeathsquadPDA pocket1: EnergySword - belt: ClothingBeltChiefEngineerFilled + pocket2: EnergyShield + belt: ClothingBeltMilitaryWebbingMedFilled innerClothingSkirt: ClothingUniformJumpskirtColorBlack - satchel: ClothingBackpackDuffelSyndicateAmmo - duffelbag: ClothingBackpackDuffelSyndicateAmmo # Syndicate Operative Outfit - Monkey - type: startingGear @@ -256,7 +255,7 @@ equipment: jumpsuit: ClothingUniformJumpsuitColorBrown back: ClothingBackpackDuffelCBURN - mask: ClothingMaskGasExplorer + mask: ClothingMaskGasERT eyes: ClothingEyesGlassesSecurity ears: ClothingHeadsetAltCentCom gloves: ClothingHandsGlovesCombat From 0e5250d728f8e88a8e93065dfadb3202afc0659f Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 27 Oct 2023 09:55:47 -0400 Subject: [PATCH 079/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 5eab7e36a5..b91619d209 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,9 +1,4 @@ Entries: -- author: Vordenburg - changes: - - {message: Substations produce hot CO2 when destroyed now., type: Tweak} - id: 4570 - time: '2023-08-14T01:55:06.0000000+00:00' - author: EmoGarbage404 changes: - {message: Being turned into a cyborg or zombie now counts as a being dead for @@ -2900,3 +2895,20 @@ Entries: - {message: Fixed foam dissolution animation., type: Fix} id: 5069 time: '2023-10-27T02:52:11.0000000+00:00' +- author: Whisper + changes: + - {message: Increased funding in an undisclosed NT Operative Squad., type: Add} + - {message: CentComm staff will have their proper ID icons on security's sechud., + type: Add} + - {message: CentComm staff will have undying loyalty to Nanotrasen., type: Add} + - {message: ERT funding has been improved. Expect specialized ERT units to be able + to provide more assistance related to their role., type: Tweak} + - {message: Cut funding from ERT weaponry. They'll likely be seen using standard + security-level weapons., type: Remove} + - {message: 'Cut funding from ERT uniforms, they no longer have built in armor.', + type: Fix} + - {message: The medical ERT members have had their hardsuits refitted with proper + armor., type: Fix} + - {message: Updated the localization files., type: Fix} + id: 5070 + time: '2023-10-27T13:54:43.0000000+00:00' From c55e1dcafd849c433957675f05579e1c10ae8c22 Mon Sep 17 00:00:00 2001 From: Chief-Engineer <119664036+Chief-Engineer@users.noreply.github.com> Date: Fri, 27 Oct 2023 17:59:36 -0500 Subject: [PATCH 080/102] Restore Leviathan's 80 pop cap (#21281) --- Resources/ConfigPresets/WizardsDen/leviathan.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/ConfigPresets/WizardsDen/leviathan.toml b/Resources/ConfigPresets/WizardsDen/leviathan.toml index df1c842ac1..adb56e1c4e 100644 --- a/Resources/ConfigPresets/WizardsDen/leviathan.toml +++ b/Resources/ConfigPresets/WizardsDen/leviathan.toml @@ -4,7 +4,7 @@ [game] hostname = "[EN] Wizard's Den Leviathan [US East 1]" -soft_max_players = 60 +soft_max_players = 80 [hub] tags = "lang:en,region:am_n_e,rp:low" From e685cb626b9da2b3cfaf2edefb0aa2f39b510de3 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Sat, 28 Oct 2023 09:59:53 +1100 Subject: [PATCH 081/102] Un-revert IPlayerManager refactor (#21244) --- Content.Client/Actions/ActionsSystem.cs | 9 +- .../Managers/ClientAdminManager.cs | 2 +- .../UI/Tabs/AdminTab/TeleportWindow.xaml.cs | 1 - Content.Client/Alerts/ClientAlertsSystem.cs | 9 +- .../CharacterInfo/CharacterInfoSystem.cs | 12 --- .../Construction/ConstructionSystem.cs | 6 +- Content.Client/Drugs/DrugOverlaySystem.cs | 9 +- Content.Client/Drunk/DrunkSystem.cs | 9 +- Content.Client/Eye/Blinding/BlindingSystem.cs | 18 +--- .../Eye/Blinding/BlurryVisionSystem.cs | 11 +-- Content.Client/Eye/EyeLerpingSystem.cs | 4 +- Content.Client/Fullscreen/FullscreenHook.cs | 2 +- Content.Client/Gameplay/GameplayStateBase.cs | 2 +- Content.Client/Ghost/GhostSystem.cs | 12 +-- Content.Client/Hands/Systems/HandsSystem.cs | 8 +- .../HealthOverlay/HealthOverlaySystem.cs | 13 +-- .../Inventory/ClientInventorySystem.cs | 9 +- Content.Client/Overlays/EquipmentHudSystem.cs | 9 +- .../Physics/Controllers/MoverController.cs | 17 ++-- Content.Client/Players/PlayerSystem.cs | 4 +- Content.Client/Popups/PopupSystem.cs | 1 - .../ReplaySpectatorSystem.Movement.cs | 2 +- .../ReplaySpectatorSystem.Position.cs | 12 +-- .../ReplaySpectatorSystem.Spectate.cs | 14 +-- .../Replay/Spectator/ReplaySpectatorSystem.cs | 3 +- Content.Client/Sandbox/SandboxSystem.cs | 2 +- Content.Client/Traits/ParacusiaSystem.cs | 6 +- .../Character/CharacterUIController.cs | 8 +- .../Systems/Chat/ChatUIController.cs | 29 +----- .../DamageOverlayUiController.cs | 10 +-- .../Systems/Sandbox/SandboxUIController.cs | 2 +- .../Weapons/Melee/MeleeWeaponSystem.cs | 3 +- Content.IntegrationTests/Pair/TestPair.cs | 8 +- .../Tests/Actions/ActionsAddedTest.cs | 4 +- .../Tests/Administration/Logs/AddTests.cs | 8 +- .../Tests/Administration/Logs/QueryTests.cs | 5 +- .../Tests/Cleanup/EuiManagerTest.cs | 2 +- .../Tests/Interaction/InteractionTest.cs | 5 +- .../Tests/Minds/GhostRoleTests.cs | 3 +- .../Tests/Minds/MindTests.EntityDeletion.cs | 13 +-- .../Tests/Minds/MindTests.Helpers.cs | 30 ++++--- .../Tests/Minds/MindTests.ReconnectTests.cs | 39 +++++++- .../Tests/Minds/MindTests.cs | 11 +-- .../Tests/Toolshed/ToolshedTest.cs | 7 +- Content.MapRenderer/Painters/MapPainter.cs | 2 +- .../AdminPermsChangedEventArgs.cs | 6 +- .../Administration/Commands/AGhost.cs | 3 +- .../Commands/AdminWhoCommand.cs | 3 +- .../Commands/AnnounceUiCommand.cs | 3 +- .../Administration/Commands/BanCommand.cs | 11 +-- .../Administration/Commands/BanListCommand.cs | 4 +- .../Commands/BanPanelCommand.cs | 8 +- .../Administration/Commands/ControlMob.cs | 3 +- .../Administration/Commands/DSay.cs | 4 +- .../Administration/Commands/DeAdminCommand.cs | 4 +- .../Commands/ExplosionCommand.cs | 3 +- .../Administration/Commands/FaxUiCommand.cs | 3 +- .../Commands/OpenAdminLogsCommand.cs | 3 +- .../Commands/OpenAdminNotesCommand.cs | 4 +- .../Commands/OpenPermissionsCommand.cs | 4 +- .../Commands/OpenUserVisibleNotesCommand.cs | 3 +- .../Administration/Commands/PardonCommand.cs | 3 +- .../Commands/PlayGlobalSoundCommand.cs | 1 - .../Administration/Commands/ReAdminCommand.cs | 4 +- .../Administration/Commands/SetAdminOOC.cs | 4 +- .../Administration/Commands/SetMindCommand.cs | 1 + .../Commands/SetOutfitCommand.cs | 3 +- .../Administration/Commands/WarpCommand.cs | 4 +- .../ContentNetworkResourceManager.cs | 4 +- .../Logs/AdminLogManager.Json.cs | 6 +- .../Logs/Converters/PlayerSessionConverter.cs | 6 +- .../Administration/Managers/AdminManager.cs | 52 +++++------ .../Administration/Managers/BanManager.cs | 3 +- .../Administration/Managers/IAdminManager.cs | 15 ++-- .../Administration/Managers/IBanManager.cs | 4 +- .../Administration/Notes/AdminNotesManager.cs | 2 +- .../Administration/Notes/AdminNotesSystem.cs | 2 +- .../Notes/IAdminNotesManager.cs | 2 +- .../QuickDialogSystem.OpenDialog.cs | 10 +-- .../Administration/QuickDialogSystem.cs | 7 +- .../Administration/Systems/AdminSystem.cs | 8 +- .../Systems/AdminTestArenaSystem.cs | 4 +- .../Administration/Systems/AdminVerbSystem.cs | 5 +- .../Administration/Systems/BwoinkSystem.cs | 5 +- .../Administration/Toolshed/AdminsCommand.cs | 6 +- Content.Server/Afk/AFKSystem.cs | 9 +- Content.Server/Afk/AfkManager.cs | 15 ++-- Content.Server/Afk/Events/AFKEvent.cs | 6 +- Content.Server/Afk/Events/UnAFKEvent.cs | 6 +- Content.Server/Alert/Commands/ClearAlert.cs | 3 +- Content.Server/Alert/Commands/ShowAlert.cs | 3 +- .../Commands/SetAlertLevelCommand.cs | 5 +- Content.Server/Antag/AntagSelectionSystem.cs | 9 +- .../Arcade/BlockGame/BlockGame.Ui.cs | 20 ++--- .../BlockGame/BlockGameArcadeComponent.cs | 6 +- .../Arcade/BlockGame/BlockGameArcadeSystem.cs | 6 +- .../Atmos/Commands/DeleteGasCommand.cs | 3 +- .../Atmos/Commands/ShowAtmosCommand.cs | 3 +- .../EntitySystems/AtmosDebugOverlaySystem.cs | 11 +-- .../Atmos/EntitySystems/GasTankSystem.cs | 7 -- .../EntitySystems/GasTileOverlaySystem.cs | 7 +- .../Body/Commands/AddHandCommand.cs | 3 +- .../Body/Commands/AttachBodyPartCommand.cs | 4 +- .../Body/Commands/DestroyMechanismCommand.cs | 3 +- .../Body/Commands/RemoveHandCommand.cs | 3 +- Content.Server/Body/Systems/BodySystem.cs | 2 +- .../Cargo/Systems/CargoSystem.Orders.cs | 2 +- .../CartridgeLoader/CartridgeLoaderSystem.cs | 6 +- .../Chat/Commands/AdminChatCommand.cs | 3 +- Content.Server/Chat/Commands/LOOCCommand.cs | 3 +- Content.Server/Chat/Commands/MeCommand.cs | 3 +- Content.Server/Chat/Commands/OOCCommand.cs | 3 +- Content.Server/Chat/Commands/SayCommand.cs | 3 +- .../Chat/Commands/SuicideCommand.cs | 3 +- .../Chat/Commands/WhisperCommand.cs | 3 +- Content.Server/Chat/Managers/ChatManager.cs | 16 ++-- Content.Server/Chat/Managers/IChatManager.cs | 12 ++- Content.Server/Chat/Systems/ChatSystem.cs | 21 +++-- .../EntitySystems/ChemistryGuideDataSystem.cs | 1 + Content.Server/Chunking/ChunkingSystem.cs | 6 +- Content.Server/Commands/CommandUtils.cs | 7 +- .../Commands/FixRotationsCommand.cs | 3 +- .../Commands/TileReplaceCommand.cs | 3 +- .../Construction/Commands/TileWallsCommand.cs | 5 +- .../ConstructionSystem.Initial.cs | 2 +- .../CrewManifest/CrewManifestSystem.cs | 17 ++-- .../Damage/Commands/GodModeCommand.cs | 4 +- .../Damage/ForceSay/DamageForceSaySystem.cs | 1 - Content.Server/Database/UserDbDataManager.cs | 14 +-- Content.Server/Decals/DecalSystem.cs | 13 +-- .../Disposal/TubeConnectionsCommand.cs | 3 +- Content.Server/EUI/BaseEui.cs | 2 +- Content.Server/EUI/EuiManager.cs | 2 +- .../EntityList/SpawnEntityListCommand.cs | 3 +- Content.Server/Examine/ExamineSystem.cs | 3 +- .../PuddleDebugDebugOverlaySystem.cs | 8 +- Content.Server/Fluids/ShowFluidsCommand.cs | 3 +- .../GameTicking/Commands/JoinGameCommand.cs | 3 +- .../GameTicking/Commands/ObserveCommand.cs | 3 +- .../GameTicking/Commands/RespawnCommand.cs | 2 +- .../Commands/ToggleReadyCommand.cs | 3 +- .../GameTicking/GameTicker.GamePreset.cs | 6 +- .../GameTicking/GameTicker.Lobby.cs | 8 +- .../GameTicking/GameTicker.Player.cs | 31 ++++--- .../GameTicking/GameTicker.RoundFlow.cs | 21 +++-- .../GameTicking/GameTicker.Spawning.cs | 28 +++--- .../Rules/Components/TraitorRuleComponent.cs | 4 +- .../Rules/InactivityTimeRestartRuleSystem.cs | 1 + .../GameTicking/Rules/NukeopsRuleSystem.cs | 18 ++-- .../GameTicking/Rules/PiratesRuleSystem.cs | 4 +- .../GameTicking/Rules/RespawnRuleSystem.cs | 1 + .../GameTicking/Rules/TraitorRuleSystem.cs | 13 ++- .../GameTicking/Rules/ZombieRuleSystem.cs | 10 +-- Content.Server/Ghost/Ghost.cs | 3 +- .../Roles/Components/TakeGhostRoleEvent.cs | 2 +- Content.Server/Ghost/Roles/GhostRoleSystem.cs | 10 +-- .../Gravity/GravityGeneratorSystem.cs | 4 +- Content.Server/Hands/Systems/HandsSystem.cs | 9 +- .../HumanoidAppearanceSystem.Modifier.cs | 5 +- .../Instruments/InstrumentComponent.cs | 4 +- .../Instruments/InstrumentSystem.cs | 6 +- .../Interaction/InteractionSystem.cs | 1 - Content.Server/Interaction/TilePryCommand.cs | 5 +- .../MagicMirror/MagicMirrorSystem.cs | 5 +- Content.Server/Mapping/MappingCommand.cs | 2 +- Content.Server/Maps/GridDraggingSystem.cs | 9 +- Content.Server/Medical/DefibrillatorSystem.cs | 2 +- Content.Server/Mind/MindSystem.cs | 88 +++++++++---------- Content.Server/Mind/Toolshed/MindCommand.cs | 6 +- Content.Server/Motd/MOTDCommand.cs | 7 +- Content.Server/Motd/MOTDSystem.cs | 14 +-- Content.Server/Motd/SetMOTDCommand.cs | 7 +- .../Movement/Systems/LagCompensationSystem.cs | 2 +- Content.Server/NPC/Commands/NPCCommand.cs | 3 +- Content.Server/NPC/HTN/HTNSystem.cs | 7 +- .../NPC/Pathfinding/PathfindingSystem.cs | 4 +- .../NPC/Systems/NPCSteeringSystem.cs | 4 +- .../EntitySystems/NodeGroupSystem.cs | 7 +- Content.Server/Nutrition/Hungry.cs | 4 +- .../Commands/ListObjectivesCommand.cs | 2 +- Content.Server/PDA/PdaSystem.cs | 8 +- Content.Server/PDA/Ringer/RingerSystem.cs | 3 +- Content.Server/Paper/PaperSystem.cs | 6 +- Content.Server/Parallax/BiomeSystem.cs | 3 +- .../ParticleAcceleratorSystem.ControlBox.cs | 17 ++-- .../ParticleAcceleratorSystem.Parts.cs | 4 +- .../PlayTimeTrackingManager.cs | 40 ++++----- .../PlayTimeTrackingSystem.cs | 13 +-- Content.Server/Players/PlayerData.cs | 30 ------- Content.Server/Players/PlayerSystem.cs | 4 +- .../Pointing/EntitySystems/PointingSystem.cs | 5 +- Content.Server/Popups/PopupSystem.cs | 1 - Content.Server/Prayer/PrayerSystem.cs | 7 +- .../Managers/IServerPreferencesManager.cs | 8 +- .../Managers/ServerPreferencesManager.cs | 8 +- Content.Server/Pulling/PullingSystem.cs | 2 +- .../Systems/RadiationSystem.Debug.cs | 2 +- .../Research/Systems/ResearchSystem.Client.cs | 3 +- Content.Server/Salvage/SalvageRulerCommand.cs | 3 +- .../Sandbox/Commands/ColorNetworkCommand.cs | 3 +- Content.Server/Sandbox/SandboxSystem.cs | 1 + .../SensorMonitoringConsoleComponent.cs | 2 +- .../SensorMonitoringConsoleSystem.UI.cs | 4 +- .../ServerUpdates/ServerUpdateManager.cs | 1 + .../Systems/EmergencyShuttleSystem.cs | 3 +- .../Silicons/Borgs/BorgSystem.Modules.cs | 2 +- Content.Server/Silicons/Borgs/BorgSystem.cs | 2 +- .../Silicons/Laws/SiliconLawSystem.cs | 3 +- .../Station/Systems/StationJobsSystem.cs | 2 +- .../Storage/EntitySystems/StorageSystem.cs | 3 +- Content.Server/Tabletop/TabletopSession.cs | 4 +- .../Tabletop/TabletopSystem.Session.cs | 8 +- Content.Server/Tabletop/TabletopSystem.cs | 7 +- .../Commands/AdminDebug/ACmdCommand.cs | 4 +- .../Toolshed/Commands/VisualizeCommand.cs | 3 +- .../Uplink/Commands/AddUplinkCommand.cs | 5 +- .../UserInterface/ActivatableUIComponent.cs | 4 +- .../UserInterface/ActivatableUISystem.cs | 8 +- .../UserInterface/StatValuesCommand.cs | 3 +- Content.Server/Verbs/VerbSystem.cs | 5 +- Content.Server/Voting/IVoteHandle.cs | 4 +- .../Voting/Managers/IVoteManager.cs | 6 +- .../Managers/VoteManager.DefaultVotes.cs | 12 +-- Content.Server/Voting/Managers/VoteManager.cs | 31 +++---- Content.Server/Voting/VoteCommands.cs | 9 +- Content.Server/Voting/VoteOptions.cs | 8 +- .../Weapons/Melee/MeleeWeaponSystem.cs | 4 +- Content.Server/Wires/WiresSystem.cs | 4 +- .../Systems/ArtifactAnalyzerSystem.cs | 3 +- .../Managers/ISharedAdminManager.cs | 2 +- Content.Shared/Buckle/SharedBuckleSystem.cs | 2 +- .../SharedHandsSystem.Interactions.cs | 2 +- .../Interaction/SharedInteractionSystem.cs | 2 +- Content.Shared/Mind/MindComponent.cs | 2 +- Content.Shared/Mind/SharedMindSystem.cs | 6 +- .../Movement/Events/MoveInputEvent.cs | 2 - .../Systems/SharedContentEyeSystem.cs | 2 +- .../Systems/SharedMoverController.Input.cs | 2 +- .../{PlayerData.cs => ContentPlayerData.cs} | 21 +---- Content.Shared/Players/PlayerDataExt.cs | 30 +++++++ Content.Shared/Players/SharedPlayerSystem.cs | 4 +- Content.Shared/Popups/SharedPopupSystem.cs | 1 - .../Pulling/Systems/SharedPullingSystem.cs | 2 +- Content.Shared/Roles/Jobs/SharedJobSystem.cs | 2 +- .../Weapons/Melee/SharedMeleeWeaponSystem.cs | 2 +- 245 files changed, 781 insertions(+), 943 deletions(-) delete mode 100644 Content.Server/Players/PlayerData.cs rename Content.Shared/Players/{PlayerData.cs => ContentPlayerData.cs} (73%) create mode 100644 Content.Shared/Players/PlayerDataExt.cs diff --git a/Content.Client/Actions/ActionsSystem.cs b/Content.Client/Actions/ActionsSystem.cs index 83d927c94b..a487e5d8d8 100644 --- a/Content.Client/Actions/ActionsSystem.cs +++ b/Content.Client/Actions/ActionsSystem.cs @@ -2,7 +2,6 @@ using System.IO; using System.Linq; using Content.Shared.Actions; using JetBrains.Annotations; -using Robust.Client.GameObjects; using Robust.Client.Player; using Robust.Shared.ContentPack; using Robust.Shared.GameStates; @@ -41,8 +40,8 @@ namespace Content.Client.Actions public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(HandleComponentState); SubscribeLocalEvent(OnInstantHandleState); @@ -196,12 +195,12 @@ namespace Content.Client.Actions return GetActions(user); } - private void OnPlayerAttached(EntityUid uid, ActionsComponent component, PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, ActionsComponent component, LocalPlayerAttachedEvent args) { LinkAllActions(component); } - private void OnPlayerDetached(EntityUid uid, ActionsComponent component, PlayerDetachedEvent? args = null) + private void OnPlayerDetached(EntityUid uid, ActionsComponent component, LocalPlayerDetachedEvent? args = null) { UnlinkAllActions(); } diff --git a/Content.Client/Administration/Managers/ClientAdminManager.cs b/Content.Client/Administration/Managers/ClientAdminManager.cs index 8978e2fd6d..1a1366c6f2 100644 --- a/Content.Client/Administration/Managers/ClientAdminManager.cs +++ b/Content.Client/Administration/Managers/ClientAdminManager.cs @@ -4,7 +4,7 @@ using Robust.Client.Console; using Robust.Client.Player; using Robust.Shared.ContentPack; using Robust.Shared.Network; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Client.Administration.Managers diff --git a/Content.Client/Administration/UI/Tabs/AdminTab/TeleportWindow.xaml.cs b/Content.Client/Administration/UI/Tabs/AdminTab/TeleportWindow.xaml.cs index c5a9bd036a..1978b5c3c0 100644 --- a/Content.Client/Administration/UI/Tabs/AdminTab/TeleportWindow.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/AdminTab/TeleportWindow.xaml.cs @@ -5,7 +5,6 @@ using Robust.Client.Console; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; using Robust.Shared.IoC; -using Robust.Shared.Players; namespace Content.Client.Administration.UI.Tabs.AdminTab { diff --git a/Content.Client/Alerts/ClientAlertsSystem.cs b/Content.Client/Alerts/ClientAlertsSystem.cs index bb6d2d4df4..5089022415 100644 --- a/Content.Client/Alerts/ClientAlertsSystem.cs +++ b/Content.Client/Alerts/ClientAlertsSystem.cs @@ -1,7 +1,6 @@ using System.Linq; using Content.Shared.Alert; using JetBrains.Annotations; -using Robust.Client.GameObjects; using Robust.Client.Player; using Robust.Shared.Prototypes; @@ -22,8 +21,8 @@ public sealed class ClientAlertsSystem : AlertsSystem { base.Initialize(); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(ClientAlertsHandleState); } @@ -69,7 +68,7 @@ public sealed class ClientAlertsSystem : AlertsSystem SyncAlerts?.Invoke(this, component.Alerts); } - private void OnPlayerAttached(EntityUid uid, AlertsComponent component, PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, AlertsComponent component, LocalPlayerAttachedEvent args) { if (_playerManager.LocalPlayer?.ControlledEntity != uid) return; @@ -87,7 +86,7 @@ public sealed class ClientAlertsSystem : AlertsSystem ClearAlerts?.Invoke(this, EventArgs.Empty); } - private void OnPlayerDetached(EntityUid uid, AlertsComponent component, PlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, AlertsComponent component, LocalPlayerDetachedEvent args) { ClearAlerts?.Invoke(this, EventArgs.Empty); } diff --git a/Content.Client/CharacterInfo/CharacterInfoSystem.cs b/Content.Client/CharacterInfo/CharacterInfoSystem.cs index 93bd86d140..844a352a18 100644 --- a/Content.Client/CharacterInfo/CharacterInfoSystem.cs +++ b/Content.Client/CharacterInfo/CharacterInfoSystem.cs @@ -1,6 +1,5 @@ using Content.Shared.CharacterInfo; using Content.Shared.Objectives; -using Robust.Client.GameObjects; using Robust.Client.Player; using Robust.Client.UserInterface; @@ -11,14 +10,11 @@ public sealed class CharacterInfoSystem : EntitySystem [Dependency] private readonly IPlayerManager _players = default!; public event Action? OnCharacterUpdate; - public event Action? OnCharacterDetached; public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeNetworkEvent(OnCharacterInfoEvent); } @@ -33,14 +29,6 @@ public sealed class CharacterInfoSystem : EntitySystem RaiseNetworkEvent(new RequestCharacterInfoEvent(GetNetEntity(entity.Value))); } - private void OnPlayerAttached(PlayerAttachSysMessage msg) - { - if (msg.AttachedEntity == default) - { - OnCharacterDetached?.Invoke(); - } - } - private void OnCharacterInfoEvent(CharacterInfoEvent msg, EntitySessionEventArgs args) { var entity = GetEntity(msg.NetEntity); diff --git a/Content.Client/Construction/ConstructionSystem.cs b/Content.Client/Construction/ConstructionSystem.cs index 98d2dfd414..9fc638cea2 100644 --- a/Content.Client/Construction/ConstructionSystem.cs +++ b/Content.Client/Construction/ConstructionSystem.cs @@ -38,7 +38,7 @@ namespace Content.Client.Construction base.Initialize(); UpdatesOutsidePrediction = true; - SubscribeLocalEvent(HandlePlayerAttached); + SubscribeLocalEvent(HandlePlayerAttached); SubscribeNetworkEvent(HandleAckStructure); SubscribeNetworkEvent(OnConstructionGuideReceived); @@ -110,9 +110,9 @@ namespace Content.Client.Construction ClearGhost(msg.GhostId); } - private void HandlePlayerAttached(PlayerAttachSysMessage msg) + private void HandlePlayerAttached(LocalPlayerAttachedEvent msg) { - var available = IsCraftingAvailable(msg.AttachedEntity); + var available = IsCraftingAvailable(msg.Entity); UpdateCraftingAvailability(available); } diff --git a/Content.Client/Drugs/DrugOverlaySystem.cs b/Content.Client/Drugs/DrugOverlaySystem.cs index 7be63b4c50..ec0d014072 100644 --- a/Content.Client/Drugs/DrugOverlaySystem.cs +++ b/Content.Client/Drugs/DrugOverlaySystem.cs @@ -1,5 +1,4 @@ using Content.Shared.Drugs; -using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.Player; @@ -24,18 +23,18 @@ public sealed class DrugOverlaySystem : EntitySystem SubscribeLocalEvent(OnInit); SubscribeLocalEvent(OnShutdown); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); _overlay = new(); } - private void OnPlayerAttached(EntityUid uid, SeeingRainbowsComponent component, PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, SeeingRainbowsComponent component, LocalPlayerAttachedEvent args) { _overlayMan.AddOverlay(_overlay); } - private void OnPlayerDetached(EntityUid uid, SeeingRainbowsComponent component, PlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, SeeingRainbowsComponent component, LocalPlayerDetachedEvent args) { _overlay.Intoxication = 0; _overlayMan.RemoveOverlay(_overlay); diff --git a/Content.Client/Drunk/DrunkSystem.cs b/Content.Client/Drunk/DrunkSystem.cs index 0573b2ff3e..4f2ec70b56 100644 --- a/Content.Client/Drunk/DrunkSystem.cs +++ b/Content.Client/Drunk/DrunkSystem.cs @@ -1,5 +1,4 @@ using Content.Shared.Drunk; -using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.Player; @@ -19,18 +18,18 @@ public sealed class DrunkSystem : SharedDrunkSystem SubscribeLocalEvent(OnDrunkInit); SubscribeLocalEvent(OnDrunkShutdown); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); _overlay = new(); } - private void OnPlayerAttached(EntityUid uid, DrunkComponent component, PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, DrunkComponent component, LocalPlayerAttachedEvent args) { _overlayMan.AddOverlay(_overlay); } - private void OnPlayerDetached(EntityUid uid, DrunkComponent component, PlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, DrunkComponent component, LocalPlayerDetachedEvent args) { _overlay.CurrentBoozePower = 0; _overlayMan.RemoveOverlay(_overlay); diff --git a/Content.Client/Eye/Blinding/BlindingSystem.cs b/Content.Client/Eye/Blinding/BlindingSystem.cs index f0b760d838..f255f7ef01 100644 --- a/Content.Client/Eye/Blinding/BlindingSystem.cs +++ b/Content.Client/Eye/Blinding/BlindingSystem.cs @@ -1,17 +1,7 @@ - -using Content.Shared.Eye.Blinding; -using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.Player; -using System; -using System.Collections.Generic; -using System.Linq; -using Content.Shared.Administration; -using Content.Shared.Administration.Events; using Content.Shared.Eye.Blinding.Components; using Content.Shared.GameTicking; -using Robust.Shared.GameObjects; -using Robust.Shared.Network; namespace Content.Client.Eye.Blinding; @@ -31,20 +21,20 @@ public sealed class BlindingSystem : EntitySystem SubscribeLocalEvent(OnBlindInit); SubscribeLocalEvent(OnBlindShutdown); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeNetworkEvent(RoundRestartCleanup); _overlay = new(); } - private void OnPlayerAttached(EntityUid uid, BlindableComponent component, PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, BlindableComponent component, LocalPlayerAttachedEvent args) { _overlayMan.AddOverlay(_overlay); } - private void OnPlayerDetached(EntityUid uid, BlindableComponent component, PlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, BlindableComponent component, LocalPlayerDetachedEvent args) { _overlayMan.RemoveOverlay(_overlay); _lightManager.Enabled = true; diff --git a/Content.Client/Eye/Blinding/BlurryVisionSystem.cs b/Content.Client/Eye/Blinding/BlurryVisionSystem.cs index 1bac2a97bf..8be5b4ed93 100644 --- a/Content.Client/Eye/Blinding/BlurryVisionSystem.cs +++ b/Content.Client/Eye/Blinding/BlurryVisionSystem.cs @@ -1,9 +1,6 @@ -using Content.Shared.Eye.Blinding; using Content.Shared.Eye.Blinding.Components; -using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.Player; -using Robust.Shared.GameStates; namespace Content.Client.Eye.Blinding; @@ -20,18 +17,18 @@ public sealed class BlurryVisionSystem : EntitySystem SubscribeLocalEvent(OnBlurryInit); SubscribeLocalEvent(OnBlurryShutdown); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); _overlay = new(); } - private void OnPlayerAttached(EntityUid uid, BlurryVisionComponent component, PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, BlurryVisionComponent component, LocalPlayerAttachedEvent args) { _overlayMan.AddOverlay(_overlay); } - private void OnPlayerDetached(EntityUid uid, BlurryVisionComponent component, PlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, BlurryVisionComponent component, LocalPlayerDetachedEvent args) { _overlayMan.RemoveOverlay(_overlay); } diff --git a/Content.Client/Eye/EyeLerpingSystem.cs b/Content.Client/Eye/EyeLerpingSystem.cs index 8e54196b81..b46921a9b4 100644 --- a/Content.Client/Eye/EyeLerpingSystem.cs +++ b/Content.Client/Eye/EyeLerpingSystem.cs @@ -30,7 +30,7 @@ public sealed class EyeLerpingSystem : EntitySystem SubscribeLocalEvent(OnAttached); SubscribeLocalEvent(HandleMapChange); - SubscribeLocalEvent(OnDetached); + SubscribeLocalEvent(OnDetached); UpdatesAfter.Add(typeof(TransformSystem)); UpdatesAfter.Add(typeof(PhysicsSystem)); @@ -94,7 +94,7 @@ public sealed class EyeLerpingSystem : EntitySystem AddEye(ev.Entity, ev.Component, true); } - private void OnDetached(EntityUid uid, LerpingEyeComponent component, PlayerDetachedEvent args) + private void OnDetached(EntityUid uid, LerpingEyeComponent component, LocalPlayerDetachedEvent args) { if (!component.ManuallyAdded) RemCompDeferred(uid, component); diff --git a/Content.Client/Fullscreen/FullscreenHook.cs b/Content.Client/Fullscreen/FullscreenHook.cs index 78a0151736..7917fddfbb 100644 --- a/Content.Client/Fullscreen/FullscreenHook.cs +++ b/Content.Client/Fullscreen/FullscreenHook.cs @@ -4,7 +4,7 @@ using Robust.Client.Input; using Robust.Shared.Input.Binding; using Robust.Shared; using Robust.Shared.Configuration; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Client.Fullscreen; public sealed class FullscreenHook diff --git a/Content.Client/Gameplay/GameplayStateBase.cs b/Content.Client/Gameplay/GameplayStateBase.cs index 788a4e5dff..454c063260 100644 --- a/Content.Client/Gameplay/GameplayStateBase.cs +++ b/Content.Client/Gameplay/GameplayStateBase.cs @@ -16,7 +16,7 @@ using Robust.Shared.Console; using Robust.Shared.Input; using Robust.Shared.Input.Binding; using Robust.Shared.Map; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Client.Gameplay diff --git a/Content.Client/Ghost/GhostSystem.cs b/Content.Client/Ghost/GhostSystem.cs index 5727534109..a89d0858d9 100644 --- a/Content.Client/Ghost/GhostSystem.cs +++ b/Content.Client/Ghost/GhostSystem.cs @@ -58,10 +58,10 @@ namespace Content.Client.Ghost SubscribeLocalEvent(OnGhostRemove); SubscribeLocalEvent(OnGhostState); - SubscribeLocalEvent(OnGhostPlayerAttach); - SubscribeLocalEvent(OnGhostPlayerDetach); + SubscribeLocalEvent(OnGhostPlayerAttach); + SubscribeLocalEvent(OnGhostPlayerDetach); - SubscribeLocalEvent(OnPlayerAttach); + SubscribeLocalEvent(OnPlayerAttach); SubscribeNetworkEvent(OnGhostWarpsResponse); SubscribeNetworkEvent(OnUpdateGhostRoleCount); @@ -130,7 +130,7 @@ namespace Content.Client.Ghost PlayerRemoved?.Invoke(component); } - private void OnGhostPlayerAttach(EntityUid uid, GhostComponent component, PlayerAttachedEvent playerAttachedEvent) + private void OnGhostPlayerAttach(EntityUid uid, GhostComponent component, LocalPlayerAttachedEvent localPlayerAttachedEvent) { if (uid != _playerManager.LocalPlayer?.ControlledEntity) return; @@ -161,13 +161,13 @@ namespace Content.Client.Ghost return true; } - private void OnGhostPlayerDetach(EntityUid uid, GhostComponent component, PlayerDetachedEvent args) + private void OnGhostPlayerDetach(EntityUid uid, GhostComponent component, LocalPlayerDetachedEvent args) { if (PlayerDetach(uid)) component.IsAttached = false; } - private void OnPlayerAttach(PlayerAttachedEvent ev) + private void OnPlayerAttach(LocalPlayerAttachedEvent ev) { if (!HasComp(ev.Entity)) PlayerDetach(ev.Entity); diff --git a/Content.Client/Hands/Systems/HandsSystem.cs b/Content.Client/Hands/Systems/HandsSystem.cs index ed40589f7f..31de7ec143 100644 --- a/Content.Client/Hands/Systems/HandsSystem.cs +++ b/Content.Client/Hands/Systems/HandsSystem.cs @@ -42,8 +42,8 @@ namespace Content.Client.Hands.Systems { base.Initialize(); - SubscribeLocalEvent(HandlePlayerAttached); - SubscribeLocalEvent(HandlePlayerDetached); + SubscribeLocalEvent(HandlePlayerAttached); + SubscribeLocalEvent(HandlePlayerDetached); SubscribeLocalEvent(OnHandsStartup); SubscribeLocalEvent(OnHandsShutdown); SubscribeLocalEvent(HandleComponentState); @@ -361,12 +361,12 @@ namespace Content.Client.Hands.Systems #region Gui - private void HandlePlayerAttached(EntityUid uid, HandsComponent component, PlayerAttachedEvent args) + private void HandlePlayerAttached(EntityUid uid, HandsComponent component, LocalPlayerAttachedEvent args) { OnPlayerHandsAdded?.Invoke(component); } - private void HandlePlayerDetached(EntityUid uid, HandsComponent component, PlayerDetachedEvent args) + private void HandlePlayerDetached(EntityUid uid, HandsComponent component, LocalPlayerDetachedEvent args) { OnPlayerHandsRemoved?.Invoke(); } diff --git a/Content.Client/HealthOverlay/HealthOverlaySystem.cs b/Content.Client/HealthOverlay/HealthOverlaySystem.cs index baeb4fe025..29ac937199 100644 --- a/Content.Client/HealthOverlay/HealthOverlaySystem.cs +++ b/Content.Client/HealthOverlay/HealthOverlaySystem.cs @@ -3,8 +3,8 @@ using Content.Shared.Damage; using Content.Shared.GameTicking; using Content.Shared.Mobs.Components; using JetBrains.Annotations; -using Robust.Client.GameObjects; using Robust.Client.Graphics; +using Robust.Client.Player; namespace Content.Client.HealthOverlay { @@ -13,9 +13,9 @@ namespace Content.Client.HealthOverlay { [Dependency] private readonly IEyeManager _eyeManager = default!; [Dependency] private readonly IEntityManager _entities = default!; + [Dependency] private readonly IPlayerManager _player = default!; private readonly Dictionary _guis = new(); - private EntityUid? _attachedEntity; private bool _enabled; public bool Enabled @@ -42,7 +42,6 @@ namespace Content.Client.HealthOverlay base.Initialize(); SubscribeNetworkEvent(Reset); - SubscribeLocalEvent(HandlePlayerAttached); } public void Reset(RoundRestartCleanupEvent ev) @@ -53,12 +52,6 @@ namespace Content.Client.HealthOverlay } _guis.Clear(); - _attachedEntity = default; - } - - private void HandlePlayerAttached(PlayerAttachSysMessage message) - { - _attachedEntity = message.AttachedEntity; } public override void FrameUpdate(float frameTime) @@ -70,7 +63,7 @@ namespace Content.Client.HealthOverlay return; } - if (_attachedEntity is not {} ent || Deleted(ent)) + if (_player.LocalEntity is not {} ent || Deleted(ent)) { return; } diff --git a/Content.Client/Inventory/ClientInventorySystem.cs b/Content.Client/Inventory/ClientInventorySystem.cs index ffff392aa4..f0a12b3b1f 100644 --- a/Content.Client/Inventory/ClientInventorySystem.cs +++ b/Content.Client/Inventory/ClientInventorySystem.cs @@ -10,7 +10,6 @@ using Content.Shared.Inventory; using Content.Shared.Inventory.Events; using Content.Shared.Storage; using JetBrains.Annotations; -using Robust.Client.GameObjects; using Robust.Client.Player; using Robust.Client.UserInterface; using Robust.Shared.Containers; @@ -43,8 +42,8 @@ namespace Content.Client.Inventory UpdatesOutsidePrediction = true; base.Initialize(); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(OnShutdown); @@ -113,12 +112,12 @@ namespace Content.Client.Inventory OnUnlinkInventory?.Invoke(); } - private void OnPlayerDetached(EntityUid uid, InventorySlotsComponent component, PlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, InventorySlotsComponent component, LocalPlayerDetachedEvent args) { OnUnlinkInventory?.Invoke(); } - private void OnPlayerAttached(EntityUid uid, InventorySlotsComponent component, PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, InventorySlotsComponent component, LocalPlayerAttachedEvent args) { if (TryGetSlots(uid, out var definitions)) { diff --git a/Content.Client/Overlays/EquipmentHudSystem.cs b/Content.Client/Overlays/EquipmentHudSystem.cs index 1d5ec03291..ac618691d8 100644 --- a/Content.Client/Overlays/EquipmentHudSystem.cs +++ b/Content.Client/Overlays/EquipmentHudSystem.cs @@ -1,7 +1,6 @@ using Content.Shared.GameTicking; using Content.Shared.Inventory; using Content.Shared.Inventory.Events; -using Robust.Client.GameObjects; using Robust.Client.Player; namespace Content.Client.Overlays; @@ -24,8 +23,8 @@ public abstract class EquipmentHudSystem : EntitySystem where T : IComponent SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnRemove); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(OnCompEquip); SubscribeLocalEvent(OnCompUnequip); @@ -65,12 +64,12 @@ public abstract class EquipmentHudSystem : EntitySystem where T : IComponent RefreshOverlay(uid); } - private void OnPlayerAttached(PlayerAttachedEvent args) + private void OnPlayerAttached(LocalPlayerAttachedEvent args) { RefreshOverlay(args.Entity); } - private void OnPlayerDetached(PlayerDetachedEvent args) + private void OnPlayerDetached(LocalPlayerDetachedEvent args) { if (_player.LocalPlayer?.ControlledEntity == null) Deactivate(); diff --git a/Content.Client/Physics/Controllers/MoverController.cs b/Content.Client/Physics/Controllers/MoverController.cs index 54c5c3de15..52340b3391 100644 --- a/Content.Client/Physics/Controllers/MoverController.cs +++ b/Content.Client/Physics/Controllers/MoverController.cs @@ -1,7 +1,6 @@ using Content.Shared.Movement.Components; using Content.Shared.Movement.Systems; using Content.Shared.Pulling.Components; -using Robust.Client.GameObjects; using Robust.Client.Physics; using Robust.Client.Player; using Robust.Shared.Physics.Components; @@ -17,10 +16,10 @@ namespace Content.Client.Physics.Controllers public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnRelayPlayerAttached); - SubscribeLocalEvent(OnRelayPlayerDetached); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnRelayPlayerAttached); + SubscribeLocalEvent(OnRelayPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(OnUpdatePredicted); SubscribeLocalEvent(OnUpdateRelayTargetPredicted); @@ -54,7 +53,7 @@ namespace Content.Client.Physics.Controllers // What if the entity is being pulled by a vehicle controlled by the player? } - private void OnRelayPlayerAttached(EntityUid uid, RelayInputMoverComponent component, PlayerAttachedEvent args) + private void OnRelayPlayerAttached(EntityUid uid, RelayInputMoverComponent component, LocalPlayerAttachedEvent args) { Physics.UpdateIsPredicted(uid); Physics.UpdateIsPredicted(component.RelayEntity); @@ -62,7 +61,7 @@ namespace Content.Client.Physics.Controllers SetMoveInput(inputMover, MoveButtons.None); } - private void OnRelayPlayerDetached(EntityUid uid, RelayInputMoverComponent component, PlayerDetachedEvent args) + private void OnRelayPlayerDetached(EntityUid uid, RelayInputMoverComponent component, LocalPlayerDetachedEvent args) { Physics.UpdateIsPredicted(uid); Physics.UpdateIsPredicted(component.RelayEntity); @@ -70,12 +69,12 @@ namespace Content.Client.Physics.Controllers SetMoveInput(inputMover, MoveButtons.None); } - private void OnPlayerAttached(EntityUid uid, InputMoverComponent component, PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, InputMoverComponent component, LocalPlayerAttachedEvent args) { SetMoveInput(component, MoveButtons.None); } - private void OnPlayerDetached(EntityUid uid, InputMoverComponent component, PlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, InputMoverComponent component, LocalPlayerDetachedEvent args) { SetMoveInput(component, MoveButtons.None); } diff --git a/Content.Client/Players/PlayerSystem.cs b/Content.Client/Players/PlayerSystem.cs index d5ce4ec197..dba95ef7a6 100644 --- a/Content.Client/Players/PlayerSystem.cs +++ b/Content.Client/Players/PlayerSystem.cs @@ -1,11 +1,11 @@ using Content.Shared.Players; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Client.Players; public sealed class PlayerSystem : SharedPlayerSystem { - public override PlayerData? ContentData(ICommonSession? session) + public override ContentPlayerData? ContentData(ICommonSession? session) { return null; } diff --git a/Content.Client/Popups/PopupSystem.cs b/Content.Client/Popups/PopupSystem.cs index 1d4ca19ce2..d68272a107 100644 --- a/Content.Client/Popups/PopupSystem.cs +++ b/Content.Client/Popups/PopupSystem.cs @@ -9,7 +9,6 @@ using Robust.Client.UserInterface; using Robust.Shared.Configuration; using Robust.Shared.Map; using Robust.Shared.Player; -using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Replays; using Robust.Shared.Timing; diff --git a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Movement.cs b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Movement.cs index 3bb2afe122..d48a1eab46 100644 --- a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Movement.cs +++ b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Movement.cs @@ -2,7 +2,7 @@ using Content.Shared.Movement.Components; using Robust.Shared.Input; using Robust.Shared.Input.Binding; using Robust.Shared.Map; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Client.Replay.Spectator; diff --git a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Position.cs b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Position.cs index 45a175e688..479e2eff97 100644 --- a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Position.cs +++ b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Position.cs @@ -1,5 +1,5 @@ using Content.Shared.Movement.Components; -using Robust.Client.GameObjects; +using Robust.Client.Player; using Robust.Shared.Map; using Robust.Shared.Map.Components; using Robust.Shared.Network; @@ -79,7 +79,7 @@ public sealed partial class ReplaySpectatorSystem public void SetSpectatorPosition(SpectatorData data) { - if (_player.LocalPlayer == null) + if (_player.LocalSession == null) return; if (data.Controller != null @@ -87,13 +87,13 @@ public sealed partial class ReplaySpectatorSystem && Exists(session.AttachedEntity) && Transform(session.AttachedEntity.Value).MapID != MapId.Nullspace) { - _player.LocalPlayer.AttachEntity(session.AttachedEntity.Value, EntityManager, _client); + _player.SetAttachedEntity(_player.LocalSession, session.AttachedEntity); return; } if (Exists(data.Entity) && Transform(data.Entity).MapID != MapId.Nullspace) { - _player.LocalPlayer.AttachEntity(data.Entity, EntityManager, _client); + _player.SetAttachedEntity(_player.LocalSession, data.Entity); return; } @@ -118,7 +118,7 @@ public sealed partial class ReplaySpectatorSystem return; } - if (data.Eye != null && TryComp(_player.LocalPlayer.ControlledEntity, out InputMoverComponent? newMover)) + if (data.Eye != null && TryComp(_player.LocalSession.AttachedEntity, out InputMoverComponent? newMover)) { newMover.RelativeEntity = data.Eye.Value.Ent; newMover.TargetRelativeRotation = newMover.RelativeRotation = data.Eye.Value.Rot; @@ -177,7 +177,7 @@ public sealed partial class ReplaySpectatorSystem SetSpectatorPosition(default); } - private void OnDetached(EntityUid uid, ReplaySpectatorComponent component, PlayerDetachedEvent args) + private void OnDetached(EntityUid uid, ReplaySpectatorComponent component, LocalPlayerDetachedEvent args) { if (IsClientSide(uid)) QueueDel(uid); diff --git a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Spectate.cs b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Spectate.cs index f3475c5479..80a8429055 100644 --- a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Spectate.cs +++ b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.Spectate.cs @@ -32,10 +32,10 @@ public sealed partial class ReplaySpectatorSystem public void SpectateEntity(EntityUid target) { - if (_player.LocalPlayer == null) + if (_player.LocalSession == null) return; - var old = _player.LocalPlayer.ControlledEntity; + var old = _player.LocalSession.AttachedEntity; if (old == target) { @@ -44,7 +44,7 @@ public sealed partial class ReplaySpectatorSystem return; } - _player.LocalPlayer.AttachEntity(target, EntityManager, _client); + _player.SetAttachedEntity(_player.LocalSession, target); EnsureComp(target); _stateMan.RequestStateChange(); @@ -59,10 +59,10 @@ public sealed partial class ReplaySpectatorSystem public TransformComponent SpawnSpectatorGhost(EntityCoordinates coords, bool gridAttach) { - if (_player.LocalPlayer == null) + if (_player.LocalSession == null) throw new InvalidOperationException(); - var old = _player.LocalPlayer.ControlledEntity; + var old = _player.LocalSession.AttachedEntity; var ent = Spawn("ReplayObserver", coords); _eye.SetMaxZoom(ent, Vector2.One * 5); @@ -73,7 +73,7 @@ public sealed partial class ReplaySpectatorSystem if (gridAttach) _transform.AttachToGridOrMap(ent); - _player.LocalPlayer.AttachEntity(ent, EntityManager, _client); + _player.SetAttachedEntity(_player.LocalSession, ent); if (old != null) { @@ -93,7 +93,7 @@ public sealed partial class ReplaySpectatorSystem { if (args.Length == 0) { - if (_player.LocalPlayer?.ControlledEntity is { } current) + if (_player.LocalSession?.AttachedEntity is { } current) SpawnSpectatorGhost(new EntityCoordinates(current, default), true); else SpawnSpectatorGhost(default, true); diff --git a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.cs b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.cs index c75529c037..3b9662ed8c 100644 --- a/Content.Client/Replay/Spectator/ReplaySpectatorSystem.cs +++ b/Content.Client/Replay/Spectator/ReplaySpectatorSystem.cs @@ -6,7 +6,6 @@ using Robust.Client.Player; using Robust.Client.Replays.Playback; using Robust.Client.State; using Robust.Shared.Console; -using Robust.Shared.Network; using Robust.Shared.Serialization.Markdown.Mapping; namespace Content.Client.Replay.Spectator; @@ -40,7 +39,7 @@ public sealed partial class ReplaySpectatorSystem : EntitySystem SubscribeLocalEvent>(OnGetAlternativeVerbs); SubscribeLocalEvent(OnTerminating); - SubscribeLocalEvent(OnDetached); + SubscribeLocalEvent(OnDetached); SubscribeLocalEvent(OnParentChanged); InitializeBlockers(); diff --git a/Content.Client/Sandbox/SandboxSystem.cs b/Content.Client/Sandbox/SandboxSystem.cs index 7dcbfa0ee0..d16751e371 100644 --- a/Content.Client/Sandbox/SandboxSystem.cs +++ b/Content.Client/Sandbox/SandboxSystem.cs @@ -5,7 +5,7 @@ using Robust.Client.Console; using Robust.Client.Placement; using Robust.Client.Placement.Modes; using Robust.Shared.Map; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Client.Sandbox { diff --git a/Content.Client/Traits/ParacusiaSystem.cs b/Content.Client/Traits/ParacusiaSystem.cs index 34c7d6859e..87abec80bb 100644 --- a/Content.Client/Traits/ParacusiaSystem.cs +++ b/Content.Client/Traits/ParacusiaSystem.cs @@ -1,8 +1,6 @@ using System.Numerics; using Content.Shared.Traits.Assorted; -using Content.Client.Camera; using Robust.Shared.Random; -using Robust.Client.GameObjects; using Robust.Client.Player; using Robust.Shared.Timing; @@ -19,7 +17,7 @@ public sealed class ParacusiaSystem : SharedParacusiaSystem { base.Initialize(); SubscribeLocalEvent(OnComponentStartup); - SubscribeLocalEvent(OnPlayerDetach); + SubscribeLocalEvent(OnPlayerDetach); } public override void Update(float frameTime) @@ -40,7 +38,7 @@ public sealed class ParacusiaSystem : SharedParacusiaSystem component.NextIncidentTime = _timing.CurTime + TimeSpan.FromSeconds(_random.NextFloat(component.MinTimeBetweenIncidents, component.MaxTimeBetweenIncidents)); } - private void OnPlayerDetach(EntityUid uid, ParacusiaComponent component, PlayerDetachedEvent args) + private void OnPlayerDetach(EntityUid uid, ParacusiaComponent component, LocalPlayerDetachedEvent args) { component.Stream?.Stop(); } diff --git a/Content.Client/UserInterface/Systems/Character/CharacterUIController.cs b/Content.Client/UserInterface/Systems/Character/CharacterUIController.cs index 925b2dae4f..45bdada6e7 100644 --- a/Content.Client/UserInterface/Systems/Character/CharacterUIController.cs +++ b/Content.Client/UserInterface/Systems/Character/CharacterUIController.cs @@ -8,6 +8,7 @@ using Content.Client.UserInterface.Systems.Objectives.Controls; using Content.Shared.Input; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.Player; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controllers; using Robust.Client.UserInterface.Controls; @@ -21,6 +22,7 @@ namespace Content.Client.UserInterface.Systems.Character; [UsedImplicitly] public sealed class CharacterUIController : UIController, IOnStateEntered, IOnStateExited, IOnSystemChanged { + [Dependency] private readonly IPlayerManager _player = default!; [UISystemDependency] private readonly CharacterInfoSystem _characterInfo = default!; [UISystemDependency] private readonly SpriteSystem _sprite = default!; @@ -56,13 +58,13 @@ public sealed class CharacterUIController : UIController, IOnStateEntered(OnChatMessage); _net.RegisterNetMessage(OnDeleteChatMessagesBy); @@ -170,7 +171,7 @@ public sealed class ChatUIController : UIController _speechBubbleRoot = new LayoutContainer(); - OnLocalPlayerChanged(new LocalPlayerChangedEventArgs(null, _player.LocalPlayer)); + UpdateChannelPermissions(); _input.SetInputCommand(ContentKeyFunctions.FocusChat, InputCmdHandler.FromDelegate(_ => FocusChat())); @@ -363,29 +364,7 @@ public sealed class ChatUIController : UIController _speechBubbleRoot.SetPositionLast(); } - private void OnLocalPlayerChanged(LocalPlayerChangedEventArgs obj) - { - if (obj.OldPlayer != null) - { - obj.OldPlayer.EntityAttached -= OnLocalPlayerEntityAttached; - obj.OldPlayer.EntityDetached -= OnLocalPlayerEntityDetached; - } - - if (obj.NewPlayer != null) - { - obj.NewPlayer.EntityAttached += OnLocalPlayerEntityAttached; - obj.NewPlayer.EntityDetached += OnLocalPlayerEntityDetached; - } - - UpdateChannelPermissions(); - } - - private void OnLocalPlayerEntityAttached(EntityAttachedEventArgs obj) - { - UpdateChannelPermissions(); - } - - private void OnLocalPlayerEntityDetached(EntityDetachedEventArgs obj) + private void OnAttachedChanged(EntityUid uid) { UpdateChannelPermissions(); } diff --git a/Content.Client/UserInterface/Systems/DamageOverlays/DamageOverlayUiController.cs b/Content.Client/UserInterface/Systems/DamageOverlays/DamageOverlayUiController.cs index 0836314dbc..ba4a871199 100644 --- a/Content.Client/UserInterface/Systems/DamageOverlays/DamageOverlayUiController.cs +++ b/Content.Client/UserInterface/Systems/DamageOverlays/DamageOverlayUiController.cs @@ -1,11 +1,9 @@ -using Content.Client.Alerts; using Content.Shared.Damage; using Content.Shared.FixedPoint; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; using JetBrains.Annotations; -using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.Player; using Robust.Client.UserInterface; @@ -25,13 +23,13 @@ public sealed class DamageOverlayUiController : UIController public override void Initialize() { _overlay = new Overlays.DamageOverlay(); - SubscribeLocalEvent(OnPlayerAttach); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttach); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(OnMobStateChanged); SubscribeLocalEvent(OnThresholdCheck); } - private void OnPlayerAttach(PlayerAttachedEvent args) + private void OnPlayerAttach(LocalPlayerAttachedEvent args) { ClearOverlay(); if (!EntityManager.TryGetComponent(args.Entity, out var mobState)) @@ -41,7 +39,7 @@ public sealed class DamageOverlayUiController : UIController _overlayManager.AddOverlay(_overlay); } - private void OnPlayerDetached(PlayerDetachedEvent args) + private void OnPlayerDetached(LocalPlayerDetachedEvent args) { _overlayManager.RemoveOverlay(_overlay); ClearOverlay(); diff --git a/Content.Client/UserInterface/Systems/Sandbox/SandboxUIController.cs b/Content.Client/UserInterface/Systems/Sandbox/SandboxUIController.cs index d7ec9f3497..778de82210 100644 --- a/Content.Client/UserInterface/Systems/Sandbox/SandboxUIController.cs +++ b/Content.Client/UserInterface/Systems/Sandbox/SandboxUIController.cs @@ -17,7 +17,7 @@ using Robust.Client.UserInterface.Controllers; using Robust.Client.UserInterface.Controllers.Implementations; using Robust.Shared.Input.Binding; using Robust.Shared.Map; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Utility; using static Robust.Client.UserInterface.Controls.BaseButton; diff --git a/Content.Client/Weapons/Melee/MeleeWeaponSystem.cs b/Content.Client/Weapons/Melee/MeleeWeaponSystem.cs index 397032cd15..2d2883d8b7 100644 --- a/Content.Client/Weapons/Melee/MeleeWeaponSystem.cs +++ b/Content.Client/Weapons/Melee/MeleeWeaponSystem.cs @@ -16,7 +16,8 @@ using Robust.Client.State; using Robust.Shared.Input; using Robust.Shared.Map; using Robust.Shared.Player; -using Robust.Shared.Players; +using Robust.Shared.Prototypes; +using Robust.Shared.Timing; namespace Content.Client.Weapons.Melee; diff --git a/Content.IntegrationTests/Pair/TestPair.cs b/Content.IntegrationTests/Pair/TestPair.cs index 2971573ff2..2672b4db56 100644 --- a/Content.IntegrationTests/Pair/TestPair.cs +++ b/Content.IntegrationTests/Pair/TestPair.cs @@ -3,13 +3,11 @@ using System.Collections.Generic; using System.IO; using System.Linq; using Content.Server.GameTicking; -using Content.Server.Players; -using Content.Shared.Mind; using Content.Shared.Players; -using Robust.Server.Player; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Timing; using Robust.UnitTesting; @@ -30,8 +28,8 @@ public sealed partial class TestPair public RobustIntegrationTest.ServerIntegrationInstance Server { get; private set; } = default!; public RobustIntegrationTest.ClientIntegrationInstance Client { get; private set; } = default!; - public IPlayerSession? Player => (IPlayerSession?) Server.PlayerMan.Sessions.FirstOrDefault(); - public PlayerData? PlayerData => Player?.Data.ContentData(); + public ICommonSession? Player => Server.PlayerMan.Sessions.FirstOrDefault(); + public ContentPlayerData? PlayerData => Player?.Data.ContentData(); public PoolTestLogHandler ServerLogHandler { get; private set; } = default!; public PoolTestLogHandler ClientLogHandler { get; private set; } = default!; diff --git a/Content.IntegrationTests/Tests/Actions/ActionsAddedTest.cs b/Content.IntegrationTests/Tests/Actions/ActionsAddedTest.cs index 01f8bdd938..01daeea93c 100644 --- a/Content.IntegrationTests/Tests/Actions/ActionsAddedTest.cs +++ b/Content.IntegrationTests/Tests/Actions/ActionsAddedTest.cs @@ -3,8 +3,6 @@ using Content.Shared.Actions; using Content.Shared.CombatMode; using Robust.Server.Player; using Robust.Shared.GameObjects; -using Robust.Shared.Players; -using PlayerManager = Robust.Client.Player.PlayerManager; namespace Content.IntegrationTests.Tests.Actions; @@ -26,7 +24,7 @@ public sealed class ActionsAddedTest var sEntMan = server.ResolveDependency(); var cEntMan = client.ResolveDependency(); var clientSession = client.ResolveDependency().LocalPlayer?.Session; - var serverSession = server.ResolveDependency().ServerSessions.Single(); + var serverSession = server.ResolveDependency().Sessions.Single(); var sActionSystem = server.System(); var cActionSystem = client.System(); diff --git a/Content.IntegrationTests/Tests/Administration/Logs/AddTests.cs b/Content.IntegrationTests/Tests/Administration/Logs/AddTests.cs index 6562a26b5e..98c7363a6c 100644 --- a/Content.IntegrationTests/Tests/Administration/Logs/AddTests.cs +++ b/Content.IntegrationTests/Tests/Administration/Logs/AddTests.cs @@ -7,8 +7,6 @@ using Content.Shared.Administration.Logs; using Content.Shared.Database; using Robust.Server.Player; using Robust.Shared.GameObjects; -using Robust.Shared.Map; -using Robust.Shared.Utility; namespace Content.IntegrationTests.Tests.Administration.Logs; @@ -177,7 +175,7 @@ public sealed class AddTests await server.WaitPost(() => { - var player = sPlayers.ServerSessions.First(); + var player = sPlayers.Sessions.First(); playerGuid = player.UserId; Assert.DoesNotThrow(() => @@ -280,7 +278,7 @@ public sealed class AddTests await server.WaitPost(() => { - var player = sPlayers.ServerSessions.Single(); + var player = sPlayers.Sessions.Single(); sAdminLogSystem.Add(LogType.Unknown, $"{player} {player} test log: {guid}"); }); @@ -318,7 +316,7 @@ public sealed class AddTests await server.WaitPost(() => { - var player = sPlayers.ServerSessions.Single(); + var player = sPlayers.Sessions.Single(); sAdminLogSystem.Add(LogType.Unknown, $"{player:first} {player:second} test log: {guid}"); }); diff --git a/Content.IntegrationTests/Tests/Administration/Logs/QueryTests.cs b/Content.IntegrationTests/Tests/Administration/Logs/QueryTests.cs index 1155edfad2..5a58757d53 100644 --- a/Content.IntegrationTests/Tests/Administration/Logs/QueryTests.cs +++ b/Content.IntegrationTests/Tests/Administration/Logs/QueryTests.cs @@ -5,6 +5,7 @@ using Content.Server.GameTicking; using Content.Shared.Database; using Robust.Server.Player; using Robust.Shared.GameObjects; +using Robust.Shared.Player; namespace Content.IntegrationTests.Tests.Administration.Logs; @@ -27,11 +28,11 @@ public sealed class QueryTests var date = DateTime.UtcNow; var guid = Guid.NewGuid(); - IPlayerSession player = default; + ICommonSession player = default; await server.WaitPost(() => { - player = sPlayers.ServerSessions.First(); + player = sPlayers.Sessions.First(); sAdminLogSystem.Add(LogType.Unknown, $"{player.AttachedEntity:Entity} test log: {guid}"); }); diff --git a/Content.IntegrationTests/Tests/Cleanup/EuiManagerTest.cs b/Content.IntegrationTests/Tests/Cleanup/EuiManagerTest.cs index 9aac4e2892..e2bff03501 100644 --- a/Content.IntegrationTests/Tests/Cleanup/EuiManagerTest.cs +++ b/Content.IntegrationTests/Tests/Cleanup/EuiManagerTest.cs @@ -25,7 +25,7 @@ public sealed class EuiManagerTest await server.WaitAssertion(() => { - var clientSession = sPlayerManager.ServerSessions.Single(); + var clientSession = sPlayerManager.Sessions.Single(); var ui = new AdminAnnounceEui(); eui.OpenEui(ui, clientSession); }); diff --git a/Content.IntegrationTests/Tests/Interaction/InteractionTest.cs b/Content.IntegrationTests/Tests/Interaction/InteractionTest.cs index b4b6c2239f..df77410e54 100644 --- a/Content.IntegrationTests/Tests/Interaction/InteractionTest.cs +++ b/Content.IntegrationTests/Tests/Interaction/InteractionTest.cs @@ -14,6 +14,7 @@ using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction; using Content.Shared.Mind; +using Content.Shared.Players; using Robust.Client.Input; using Robust.Client.UserInterface; using Robust.Server.GameObjects; @@ -21,7 +22,7 @@ using Robust.Server.Player; using Robust.Shared.GameObjects; using Robust.Shared.Log; using Robust.Shared.Map; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Timing; using Robust.UnitTesting; @@ -67,7 +68,7 @@ public abstract partial class InteractionTest protected NetEntity Player; protected ICommonSession ClientSession = default!; - protected IPlayerSession ServerSession = default!; + protected ICommonSession ServerSession = default!; public EntityUid? ClientTarget; diff --git a/Content.IntegrationTests/Tests/Minds/GhostRoleTests.cs b/Content.IntegrationTests/Tests/Minds/GhostRoleTests.cs index 28e49645c9..22a185798e 100644 --- a/Content.IntegrationTests/Tests/Minds/GhostRoleTests.cs +++ b/Content.IntegrationTests/Tests/Minds/GhostRoleTests.cs @@ -5,6 +5,7 @@ using Content.Server.Ghost.Roles.Components; using Content.Server.Players; using Content.Shared.Ghost; using Content.Shared.Mind; +using Content.Shared.Players; using Robust.Shared.Console; using Robust.Shared.GameObjects; using Robust.Shared.Map; @@ -43,7 +44,7 @@ public sealed class GhostRoleTests var sPlayerMan = server.ResolveDependency(); var conHost = client.ResolveDependency(); var mindSystem = entMan.System(); - var session = sPlayerMan.ServerSessions.Single(); + var session = sPlayerMan.Sessions.Single(); var originalMindId = session.ContentData()!.Mind!.Value; // Spawn player entity & attach diff --git a/Content.IntegrationTests/Tests/Minds/MindTests.EntityDeletion.cs b/Content.IntegrationTests/Tests/Minds/MindTests.EntityDeletion.cs index 9fc68ef93d..a67a45ecb4 100644 --- a/Content.IntegrationTests/Tests/Minds/MindTests.EntityDeletion.cs +++ b/Content.IntegrationTests/Tests/Minds/MindTests.EntityDeletion.cs @@ -2,6 +2,7 @@ using System.Linq; using Content.Server.Players; using Content.Shared.Ghost; using Content.Shared.Mind; +using Content.Shared.Players; using Robust.Server.Console; using Robust.Server.GameObjects; using Robust.Server.Player; @@ -35,7 +36,7 @@ public sealed partial class MindTests MindComponent mind = default!; await server.WaitAssertion(() => { - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); playerEnt = entMan.SpawnEntity(null, MapCoordinates.Nullspace); visitEnt = entMan.SpawnEntity(null, MapCoordinates.Nullspace); @@ -81,7 +82,7 @@ public sealed partial class MindTests var entMan = server.ResolveDependency(); var mapManager = server.ResolveDependency(); var playerMan = server.ResolveDependency(); - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); var mindSystem = entMan.EntitySysManager.GetEntitySystem(); @@ -128,7 +129,7 @@ public sealed partial class MindTests var entMan = server.ResolveDependency(); var playerMan = server.ResolveDependency(); - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); Assert.That(!entMan.HasComponent(player.AttachedEntity), "Player was initially a ghost?"); @@ -162,7 +163,7 @@ public sealed partial class MindTests var mindSystem = entMan.EntitySysManager.GetEntitySystem(); var mind = GetMind(pair); - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); #pragma warning disable NUnit2045 // Interdependent assertions. Assert.That(player.AttachedEntity, Is.Not.Null); Assert.That(entMan.EntityExists(player.AttachedEntity)); @@ -218,7 +219,7 @@ public sealed partial class MindTests var playerMan = server.ResolveDependency(); var serverConsole = server.ResolveDependency(); - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); var ghost = await BecomeGhost(pair); @@ -263,7 +264,7 @@ public sealed partial class MindTests var playerMan = server.ResolveDependency(); var serverConsole = server.ResolveDependency(); - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); EntityUid ghost = default!; diff --git a/Content.IntegrationTests/Tests/Minds/MindTests.Helpers.cs b/Content.IntegrationTests/Tests/Minds/MindTests.Helpers.cs index f71a6ad5f9..d6b30d60a0 100644 --- a/Content.IntegrationTests/Tests/Minds/MindTests.Helpers.cs +++ b/Content.IntegrationTests/Tests/Minds/MindTests.Helpers.cs @@ -1,14 +1,17 @@ using System.Linq; using Content.IntegrationTests.Pair; +using Content.Server.Mind; using Content.Server.Players; using Content.Shared.Ghost; using Content.Shared.Mind; +using Content.Shared.Players; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Enums; using Robust.Shared.GameObjects; using Robust.Shared.Map; using Robust.Shared.Network; +using Robust.Shared.Player; namespace Content.IntegrationTests.Tests.Minds; @@ -36,7 +39,7 @@ public sealed partial class MindTests var playerMan = pair.Server.ResolveDependency(); var mindSys = entMan.System(); - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); EntityUid entity = default; EntityUid mindId = default!; @@ -71,7 +74,7 @@ public sealed partial class MindTests EntityUid mindId = default!; MindComponent mind = default!; - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); await pair.Server.WaitAssertion(() => { var oldUid = player.AttachedEntity; @@ -116,20 +119,25 @@ public sealed partial class MindTests /// private static (EntityUid Id, MindComponent Comp) GetMind(Pair.TestPair pair) { - var playerMan = pair.Server.ResolveDependency(); - var entMan = pair.Server.ResolveDependency(); - var player = playerMan.ServerSessions.SingleOrDefault(); + var playerMan = pair.Server.PlayerMan; + var entMan = pair.Server.EntMan; + var player = playerMan.Sessions.SingleOrDefault(); Assert.That(player, Is.Not.Null); var mindId = player.ContentData()!.Mind!.Value; Assert.That(mindId, Is.Not.EqualTo(default(EntityUid))); var mind = entMan.GetComponent(mindId); + ActorComponent actor = default!; Assert.Multiple(() => { + Assert.That(player, Is.EqualTo(mind.Session), "Player session does not match mind session"); + Assert.That(entMan.System().GetMind(player.UserId), Is.EqualTo(mindId)); Assert.That(player.AttachedEntity, Is.EqualTo(mind.CurrentEntity), "Player is not attached to the mind's current entity."); Assert.That(entMan.EntityExists(mind.OwnedEntity), "The mind's current entity does not exist"); Assert.That(mind.VisitingEntity == null || entMan.EntityExists(mind.VisitingEntity), "The minds visited entity does not exist."); + Assert.That(entMan.TryGetComponent(mind.CurrentEntity, out actor)); }); + Assert.That(actor.PlayerSession, Is.EqualTo(mind.Session)); return (mindId, mind); } @@ -139,7 +147,7 @@ public sealed partial class MindTests var netManager = pair.Client.ResolveDependency(); var playerMan = pair.Server.ResolveDependency(); var entMan = pair.Server.ResolveDependency(); - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); var mindId = player.ContentData()!.Mind!.Value; var mind = entMan.GetComponent(mindId); @@ -161,21 +169,21 @@ public sealed partial class MindTests { var netManager = pair.Client.ResolveDependency(); var playerMan = pair.Server.ResolveDependency(); - Assert.That(!playerMan.ServerSessions.Any()); + Assert.That(!playerMan.Sessions.Any()); await Task.WhenAll(pair.Client.WaitIdleAsync(), pair.Client.WaitIdleAsync()); pair.Client.SetConnectTarget(pair.Server); await pair.Client.WaitPost(() => netManager.ClientConnect(null!, 0, username)); await pair.RunTicksSync(5); - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); Assert.That(player.Status, Is.EqualTo(SessionStatus.InGame)); } - private static async Task DisconnectReconnect(Pair.TestPair pair) + private static async Task DisconnectReconnect(Pair.TestPair pair) { var playerMan = pair.Server.ResolveDependency(); - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); var name = player.Name; var id = player.UserId; @@ -183,7 +191,7 @@ public sealed partial class MindTests await Connect(pair, name); // Session has changed - var newSession = playerMan.ServerSessions.Single(); + var newSession = playerMan.Sessions.Single(); Assert.Multiple(() => { Assert.That(newSession, Is.Not.EqualTo(player)); diff --git a/Content.IntegrationTests/Tests/Minds/MindTests.ReconnectTests.cs b/Content.IntegrationTests/Tests/Minds/MindTests.ReconnectTests.cs index ea2110c03a..3cac766825 100644 --- a/Content.IntegrationTests/Tests/Minds/MindTests.ReconnectTests.cs +++ b/Content.IntegrationTests/Tests/Minds/MindTests.ReconnectTests.cs @@ -1,6 +1,8 @@ using System.Linq; using Content.Shared.Ghost; using Content.Shared.Mind; +using NUnit.Framework.Interfaces; +using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.GameObjects; using Robust.Shared.Map; @@ -49,7 +51,7 @@ public sealed partial class MindTests var mind = GetMind(pair); var playerMan = pair.Server.ResolveDependency(); - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); var name = player.Name; var user = player.UserId; Assert.That(mind.Comp.OwnedEntity, Is.Not.Null); @@ -72,7 +74,7 @@ public sealed partial class MindTests // Reconnect await Connect(pair, name); - player = playerMan.ServerSessions.Single(); + player = playerMan.Sessions.Single(); Assert.Multiple(() => { Assert.That(user, Is.EqualTo(player.UserId)); @@ -127,8 +129,10 @@ public sealed partial class MindTests var mindSys = entMan.System(); var mind = GetMind(pair); + Assert.Null(mind.Comp.VisitingEntity); + // Make player visit a new mob - var original = mind.Comp.CurrentEntity; + var original = mind.Comp.OwnedEntity; EntityUid visiting = default; await pair.Server.WaitAssertion(() => { @@ -137,6 +141,7 @@ public sealed partial class MindTests }); await pair.RunTicksSync(5); + Assert.That(mind.Comp.VisitingEntity, Is.EqualTo(visiting)); await DisconnectReconnect(pair); // Player is back in control of the visited mob, mind was preserved @@ -150,4 +155,32 @@ public sealed partial class MindTests await pair.CleanReturnAsync(); } + + // This test will do the following + // - connect as a normal player + // - disconnect + // - reconnect + // - assert that they return to the original entity. + [Test] + public async Task TestReconnect() + { + await using var pair = await SetupPair(); + var mind = GetMind(pair); + + Assert.Null(mind.Comp.VisitingEntity); + Assert.NotNull(mind.Comp.OwnedEntity); + var entity = mind.Comp.OwnedEntity; + + await pair.RunTicksSync(5); + await DisconnectReconnect(pair); + await pair.RunTicksSync(5); + + var newMind = GetMind(pair); + + Assert.Null(newMind.Comp.VisitingEntity); + Assert.That(newMind.Comp.OwnedEntity, Is.EqualTo(entity)); + Assert.That(newMind.Id, Is.EqualTo(mind.Id)); + + await pair.CleanReturnAsync(); + } } diff --git a/Content.IntegrationTests/Tests/Minds/MindTests.cs b/Content.IntegrationTests/Tests/Minds/MindTests.cs index 3ad61bcdf0..c9788b80a6 100644 --- a/Content.IntegrationTests/Tests/Minds/MindTests.cs +++ b/Content.IntegrationTests/Tests/Minds/MindTests.cs @@ -11,6 +11,7 @@ using Content.Shared.Damage.Prototypes; using Content.Shared.FixedPoint; using Content.Shared.Mind; using Content.Shared.Mind.Components; +using Content.Shared.Players; using Content.Shared.Roles; using Content.Shared.Roles.Jobs; using Robust.Server.Console; @@ -345,7 +346,7 @@ public sealed partial class MindTests EntityUid entity = default!; EntityUid mindId = default!; MindComponent mind = default!; - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); await server.WaitAssertion(() => { @@ -406,12 +407,6 @@ public sealed partial class MindTests await pair.CleanReturnAsync(); } - // TODO Implement - /*[Test] - public async Task TestPlayerCanReturnFromGhostWhenDead() - { - }*/ - [Test] public async Task TestGhostDoesNotInfiniteLoop() { @@ -432,7 +427,7 @@ public sealed partial class MindTests EntityUid ghost = default!; EntityUid mindId = default!; MindComponent mind = default!; - var player = playerMan.ServerSessions.Single(); + var player = playerMan.Sessions.Single(); await server.WaitAssertion(() => { diff --git a/Content.IntegrationTests/Tests/Toolshed/ToolshedTest.cs b/Content.IntegrationTests/Tests/Toolshed/ToolshedTest.cs index ca7eeac199..d6aec781a9 100644 --- a/Content.IntegrationTests/Tests/Toolshed/ToolshedTest.cs +++ b/Content.IntegrationTests/Tests/Toolshed/ToolshedTest.cs @@ -2,8 +2,7 @@ using System.Collections.Generic; using Content.IntegrationTests.Pair; using Content.Server.Administration.Managers; -using Robust.Server.Player; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Toolshed; using Robust.Shared.Toolshed.Errors; using Robust.Shared.Toolshed.Syntax; @@ -60,7 +59,7 @@ public abstract class ToolshedTest : IInvocationContext AdminManager = Server.ResolveDependency(); } - protected bool InvokeCommand(string command, out object? result, IPlayerSession? session = null) + protected bool InvokeCommand(string command, out object? result, ICommonSession? session = null) { return Toolshed.InvokeCommand(this, command, null, out result); } @@ -95,7 +94,7 @@ public abstract class ToolshedTest : IInvocationContext return true; } - protected IPlayerSession? InvocationSession { get; set; } + protected ICommonSession? InvocationSession { get; set; } public ICommonSession? Session { diff --git a/Content.MapRenderer/Painters/MapPainter.cs b/Content.MapRenderer/Painters/MapPainter.cs index b799db78a5..8f3dd59baf 100644 --- a/Content.MapRenderer/Painters/MapPainter.cs +++ b/Content.MapRenderer/Painters/MapPainter.cs @@ -68,7 +68,7 @@ namespace Content.MapRenderer.Painters await server.WaitPost(() => { - var playerEntity = sPlayerManager.ServerSessions.Single().AttachedEntity; + var playerEntity = sPlayerManager.Sessions.Single().AttachedEntity; if (playerEntity.HasValue) { diff --git a/Content.Server/Administration/AdminPermsChangedEventArgs.cs b/Content.Server/Administration/AdminPermsChangedEventArgs.cs index 24ca7aca68..07eb416be6 100644 --- a/Content.Server/Administration/AdminPermsChangedEventArgs.cs +++ b/Content.Server/Administration/AdminPermsChangedEventArgs.cs @@ -1,5 +1,5 @@ using Content.Shared.Administration; -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Administration { @@ -8,7 +8,7 @@ namespace Content.Server.Administration /// public sealed class AdminPermsChangedEventArgs : EventArgs { - public AdminPermsChangedEventArgs(IPlayerSession player, AdminFlags? flags) + public AdminPermsChangedEventArgs(ICommonSession player, AdminFlags? flags) { Player = player; Flags = flags; @@ -17,7 +17,7 @@ namespace Content.Server.Administration /// /// The player that had their admin permissions changed. /// - public IPlayerSession Player { get; } + public ICommonSession Player { get; } /// /// The admin flags of the player. Null if the player is no longer an admin. diff --git a/Content.Server/Administration/Commands/AGhost.cs b/Content.Server/Administration/Commands/AGhost.cs index 42a8600ff1..2d1a15a0be 100644 --- a/Content.Server/Administration/Commands/AGhost.cs +++ b/Content.Server/Administration/Commands/AGhost.cs @@ -2,7 +2,6 @@ using Content.Shared.Administration; using Content.Shared.Ghost; using Content.Shared.Mind; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands @@ -18,7 +17,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("Nah"); diff --git a/Content.Server/Administration/Commands/AdminWhoCommand.cs b/Content.Server/Administration/Commands/AdminWhoCommand.cs index 8e6c402c4e..9765e8385f 100644 --- a/Content.Server/Administration/Commands/AdminWhoCommand.cs +++ b/Content.Server/Administration/Commands/AdminWhoCommand.cs @@ -2,7 +2,6 @@ using Content.Server.Administration.Managers; using Content.Server.Afk; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Utility; @@ -35,7 +34,7 @@ public sealed class AdminWhoCommand : IConsoleCommand if (adminData.Title is { } title) sb.Append($": [{title}]"); - if (shell.Player is IPlayerSession player && adminMgr.HasAdminFlag(player, AdminFlags.Admin)) + if (shell.Player is { } player && adminMgr.HasAdminFlag(player, AdminFlags.Admin)) { if (afk.IsAfk(admin)) sb.Append(" [AFK]"); diff --git a/Content.Server/Administration/Commands/AnnounceUiCommand.cs b/Content.Server/Administration/Commands/AnnounceUiCommand.cs index c4cd7f13e4..d80db96686 100644 --- a/Content.Server/Administration/Commands/AnnounceUiCommand.cs +++ b/Content.Server/Administration/Commands/AnnounceUiCommand.cs @@ -1,7 +1,6 @@ using Content.Server.Administration.UI; using Content.Server.EUI; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands @@ -17,7 +16,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("This does not work from the server console."); diff --git a/Content.Server/Administration/Commands/BanCommand.cs b/Content.Server/Administration/Commands/BanCommand.cs index 58a801e410..156fdf496a 100644 --- a/Content.Server/Administration/Commands/BanCommand.cs +++ b/Content.Server/Administration/Commands/BanCommand.cs @@ -1,15 +1,8 @@ using System.Linq; -using System.Net; -using System.Net.Sockets; -using System.Text; using Content.Server.Administration.Managers; -using Content.Server.Administration.Notes; -using Content.Server.Database; -using Content.Server.GameTicking; using Content.Shared.Administration; using Content.Shared.CCVar; using Content.Shared.Database; -using Content.Shared.Players.PlayTimeTracking; using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Console; @@ -84,7 +77,7 @@ public sealed class BanCommand : LocalizedCommands } var located = await _locator.LookupIdByNameOrIdAsync(target); - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (located == null) { @@ -102,7 +95,7 @@ public sealed class BanCommand : LocalizedCommands { if (args.Length == 1) { - var options = _playerManager.ServerSessions.Select(c => c.Name).OrderBy(c => c).ToArray(); + var options = _playerManager.Sessions.Select(c => c.Name).OrderBy(c => c).ToArray(); return CompletionResult.FromHintOptions(options, LocalizationManager.GetString("cmd-ban-hint")); } diff --git a/Content.Server/Administration/Commands/BanListCommand.cs b/Content.Server/Administration/Commands/BanListCommand.cs index 1c2be52394..a5bc97dce3 100644 --- a/Content.Server/Administration/Commands/BanListCommand.cs +++ b/Content.Server/Administration/Commands/BanListCommand.cs @@ -36,7 +36,7 @@ public sealed class BanListCommand : LocalizedCommands return; } - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { var bans = await _dbManager.GetServerBansAsync(data.LastAddress, data.UserId, data.LastHWId, false); @@ -67,7 +67,7 @@ public sealed class BanListCommand : LocalizedCommands return CompletionResult.Empty; var playerMgr = IoCManager.Resolve(); - var options = playerMgr.ServerSessions.Select(c => c.Name).OrderBy(c => c).ToArray(); + var options = playerMgr.Sessions.Select(c => c.Name).OrderBy(c => c).ToArray(); return CompletionResult.FromHintOptions(options, Loc.GetString("cmd-banlist-hint")); } } diff --git a/Content.Server/Administration/Commands/BanPanelCommand.cs b/Content.Server/Administration/Commands/BanPanelCommand.cs index 6036e5aa6e..9f9ec9e89f 100644 --- a/Content.Server/Administration/Commands/BanPanelCommand.cs +++ b/Content.Server/Administration/Commands/BanPanelCommand.cs @@ -1,12 +1,6 @@ using Content.Shared.Administration; using Robust.Shared.Console; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Content.Server.EUI; -using Robust.Server.Player; namespace Content.Server.Administration.Commands; @@ -21,7 +15,7 @@ public sealed class BanPanelCommand : LocalizedCommands public override async void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError(Loc.GetString("cmd-banpanel-server")); return; diff --git a/Content.Server/Administration/Commands/ControlMob.cs b/Content.Server/Administration/Commands/ControlMob.cs index 8fc74c61d4..317461a373 100644 --- a/Content.Server/Administration/Commands/ControlMob.cs +++ b/Content.Server/Administration/Commands/ControlMob.cs @@ -1,6 +1,5 @@ using Content.Server.Mind; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands @@ -16,7 +15,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteLine("shell-server-cannot"); return; diff --git a/Content.Server/Administration/Commands/DSay.cs b/Content.Server/Administration/Commands/DSay.cs index 79b0e8db7d..61b47d7856 100644 --- a/Content.Server/Administration/Commands/DSay.cs +++ b/Content.Server/Administration/Commands/DSay.cs @@ -1,7 +1,5 @@ -using Content.Server.Chat; using Content.Server.Chat.Systems; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands @@ -17,7 +15,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("shell-only-players-can-run-this-command"); diff --git a/Content.Server/Administration/Commands/DeAdminCommand.cs b/Content.Server/Administration/Commands/DeAdminCommand.cs index c2bbfa7a33..cf65941200 100644 --- a/Content.Server/Administration/Commands/DeAdminCommand.cs +++ b/Content.Server/Administration/Commands/DeAdminCommand.cs @@ -1,10 +1,8 @@ using Content.Server.Administration.Managers; using Content.Shared.Administration; using JetBrains.Annotations; -using Robust.Server.Player; using Robust.Shared.Console; - namespace Content.Server.Administration.Commands { [UsedImplicitly] @@ -17,7 +15,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("You cannot use this command from the server console."); diff --git a/Content.Server/Administration/Commands/ExplosionCommand.cs b/Content.Server/Administration/Commands/ExplosionCommand.cs index d48b69a5ad..56ed78b2e2 100644 --- a/Content.Server/Administration/Commands/ExplosionCommand.cs +++ b/Content.Server/Administration/Commands/ExplosionCommand.cs @@ -3,7 +3,6 @@ using Content.Server.EUI; using Content.Server.Explosion.EntitySystems; using Content.Shared.Administration; using Content.Shared.Explosion; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; using Robust.Shared.Prototypes; @@ -21,7 +20,7 @@ public sealed class OpenExplosionEui : IConsoleCommand public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteError("This does not work from the server console."); diff --git a/Content.Server/Administration/Commands/FaxUiCommand.cs b/Content.Server/Administration/Commands/FaxUiCommand.cs index b06d36d08b..cf9e97e399 100644 --- a/Content.Server/Administration/Commands/FaxUiCommand.cs +++ b/Content.Server/Administration/Commands/FaxUiCommand.cs @@ -1,7 +1,6 @@ using Content.Server.EUI; using Content.Server.Fax.AdminUI; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands; @@ -16,7 +15,7 @@ public sealed class FaxUiCommand : IConsoleCommand public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("shell-only-players-can-run-this-command"); diff --git a/Content.Server/Administration/Commands/OpenAdminLogsCommand.cs b/Content.Server/Administration/Commands/OpenAdminLogsCommand.cs index 9f28dc907c..47ff3e1a1c 100644 --- a/Content.Server/Administration/Commands/OpenAdminLogsCommand.cs +++ b/Content.Server/Administration/Commands/OpenAdminLogsCommand.cs @@ -1,7 +1,6 @@ using Content.Server.Administration.Logs; using Content.Server.EUI; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands; @@ -15,7 +14,7 @@ public sealed class OpenAdminLogsCommand : IConsoleCommand public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteLine("This does not work from the server console."); return; diff --git a/Content.Server/Administration/Commands/OpenAdminNotesCommand.cs b/Content.Server/Administration/Commands/OpenAdminNotesCommand.cs index 147c0d6a82..e6ae4f7616 100644 --- a/Content.Server/Administration/Commands/OpenAdminNotesCommand.cs +++ b/Content.Server/Administration/Commands/OpenAdminNotesCommand.cs @@ -1,7 +1,5 @@ using Content.Server.Administration.Notes; -using Content.Server.Database; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands; @@ -17,7 +15,7 @@ public sealed class OpenAdminNotesCommand : IConsoleCommand public async void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError("This does not work from the server console."); return; diff --git a/Content.Server/Administration/Commands/OpenPermissionsCommand.cs b/Content.Server/Administration/Commands/OpenPermissionsCommand.cs index 78d56cb4fb..fd3227d4aa 100644 --- a/Content.Server/Administration/Commands/OpenPermissionsCommand.cs +++ b/Content.Server/Administration/Commands/OpenPermissionsCommand.cs @@ -1,10 +1,8 @@ using Content.Server.Administration.UI; using Content.Server.EUI; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; - namespace Content.Server.Administration.Commands { [AdminCommand(AdminFlags.Permissions)] @@ -16,7 +14,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("This does not work from the server console."); diff --git a/Content.Server/Administration/Commands/OpenUserVisibleNotesCommand.cs b/Content.Server/Administration/Commands/OpenUserVisibleNotesCommand.cs index d61114fcae..507c7ab279 100644 --- a/Content.Server/Administration/Commands/OpenUserVisibleNotesCommand.cs +++ b/Content.Server/Administration/Commands/OpenUserVisibleNotesCommand.cs @@ -1,7 +1,6 @@ using Content.Server.Administration.Notes; using Content.Shared.Administration; using Content.Shared.CCVar; -using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Console; @@ -27,7 +26,7 @@ public sealed class OpenUserVisibleNotesCommand : IConsoleCommand return; } - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError("This does not work from the server console."); return; diff --git a/Content.Server/Administration/Commands/PardonCommand.cs b/Content.Server/Administration/Commands/PardonCommand.cs index 869024eb7c..9cbaaece31 100644 --- a/Content.Server/Administration/Commands/PardonCommand.cs +++ b/Content.Server/Administration/Commands/PardonCommand.cs @@ -1,7 +1,6 @@ using System.Text; using Content.Server.Database; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands @@ -15,7 +14,7 @@ namespace Content.Server.Administration.Commands public async void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; var dbMan = IoCManager.Resolve(); if (args.Length != 1) diff --git a/Content.Server/Administration/Commands/PlayGlobalSoundCommand.cs b/Content.Server/Administration/Commands/PlayGlobalSoundCommand.cs index ec5b21dcee..fdf067181d 100644 --- a/Content.Server/Administration/Commands/PlayGlobalSoundCommand.cs +++ b/Content.Server/Administration/Commands/PlayGlobalSoundCommand.cs @@ -6,7 +6,6 @@ using Robust.Shared.Audio; using Robust.Shared.Console; using Robust.Shared.ContentPack; using Robust.Shared.Player; -using Robust.Shared.Players; using Robust.Shared.Prototypes; namespace Content.Server.Administration.Commands; diff --git a/Content.Server/Administration/Commands/ReAdminCommand.cs b/Content.Server/Administration/Commands/ReAdminCommand.cs index 12ff13221a..a3f5993766 100644 --- a/Content.Server/Administration/Commands/ReAdminCommand.cs +++ b/Content.Server/Administration/Commands/ReAdminCommand.cs @@ -1,9 +1,7 @@ using Content.Server.Administration.Managers; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; - namespace Content.Server.Administration.Commands { [AnyCommand] @@ -15,7 +13,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("You cannot use this command from the server console."); diff --git a/Content.Server/Administration/Commands/SetAdminOOC.cs b/Content.Server/Administration/Commands/SetAdminOOC.cs index bb11b938d8..27528e1940 100644 --- a/Content.Server/Administration/Commands/SetAdminOOC.cs +++ b/Content.Server/Administration/Commands/SetAdminOOC.cs @@ -1,8 +1,6 @@ - using Content.Server.Database; using Content.Server.Preferences.Managers; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands @@ -16,7 +14,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (!(shell.Player is IPlayerSession)) + if (shell.Player == null) { shell.WriteError(Loc.GetString("shell-only-players-can-run-this-command")); return; diff --git a/Content.Server/Administration/Commands/SetMindCommand.cs b/Content.Server/Administration/Commands/SetMindCommand.cs index b9ff329ed2..5310c2dd7f 100644 --- a/Content.Server/Administration/Commands/SetMindCommand.cs +++ b/Content.Server/Administration/Commands/SetMindCommand.cs @@ -2,6 +2,7 @@ using Content.Server.Players; using Content.Shared.Administration; using Content.Shared.Mind; using Content.Shared.Mind.Components; +using Content.Shared.Players; using Robust.Server.Player; using Robust.Shared.Console; diff --git a/Content.Server/Administration/Commands/SetOutfitCommand.cs b/Content.Server/Administration/Commands/SetOutfitCommand.cs index 28172ee6c5..b2e7f4e6cc 100644 --- a/Content.Server/Administration/Commands/SetOutfitCommand.cs +++ b/Content.Server/Administration/Commands/SetOutfitCommand.cs @@ -10,7 +10,6 @@ using Content.Shared.PDA; using Content.Shared.Preferences; using Content.Shared.Roles; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Prototypes; @@ -57,7 +56,7 @@ namespace Content.Server.Administration.Commands if (args.Length == 1) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError(Loc.GetString("set-outfit-command-is-not-player-error")); return; diff --git a/Content.Server/Administration/Commands/WarpCommand.cs b/Content.Server/Administration/Commands/WarpCommand.cs index 30a6d127aa..0d6da0d993 100644 --- a/Content.Server/Administration/Commands/WarpCommand.cs +++ b/Content.Server/Administration/Commands/WarpCommand.cs @@ -4,11 +4,9 @@ using Content.Server.Warps; using Content.Shared.Administration; using Content.Shared.Follower; using Content.Shared.Ghost; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; using Robust.Shared.Map; -using Robust.Shared.Physics; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; @@ -28,7 +26,7 @@ namespace Content.Server.Administration.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("Only players can use this command"); diff --git a/Content.Server/Administration/ContentNetworkResourceManager.cs b/Content.Server/Administration/ContentNetworkResourceManager.cs index 0d3f3291e6..dd95a2d897 100644 --- a/Content.Server/Administration/ContentNetworkResourceManager.cs +++ b/Content.Server/Administration/ContentNetworkResourceManager.cs @@ -1,8 +1,8 @@ using Content.Server.Database; using Content.Shared.CCVar; -using Robust.Server.Player; using Robust.Server.Upload; using Robust.Shared.Configuration; +using Robust.Shared.Player; using Robust.Shared.Upload; namespace Content.Server.Administration; @@ -22,7 +22,7 @@ public sealed class ContentNetworkResourceManager _netRes.OnResourceUploaded += OnUploadResource; } - private async void OnUploadResource(IPlayerSession session, NetworkResourceUploadMessage msg) + private async void OnUploadResource(ICommonSession session, NetworkResourceUploadMessage msg) { if (StoreUploaded) await _serverDb.AddUploadedResourceLogAsync(session.UserId, DateTime.Now, msg.RelativePath.ToString(), msg.Data); diff --git a/Content.Server/Administration/Logs/AdminLogManager.Json.cs b/Content.Server/Administration/Logs/AdminLogManager.Json.cs index 63f30c7a66..0a67d61cef 100644 --- a/Content.Server/Administration/Logs/AdminLogManager.Json.cs +++ b/Content.Server/Administration/Logs/AdminLogManager.Json.cs @@ -3,8 +3,8 @@ using System.Text.Json; using System.Text.Json.Serialization; using Content.Server.Administration.Logs.Converters; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Map; +using Robust.Shared.Player; namespace Content.Server.Administration.Logs; @@ -44,7 +44,7 @@ public sealed partial class AdminLogManager var value = properties[key]; value = value switch { - IPlayerSession player => new SerializablePlayer(player), + ICommonSession player => new SerializablePlayer(player), EntityCoordinates entityCoordinates => new SerializableEntityCoordinates(_entityManager, entityCoordinates), _ => value }; @@ -56,7 +56,7 @@ public sealed partial class AdminLogManager { EntityUid id => id, EntityStringRepresentation rep => rep.Uid, - IPlayerSession {AttachedEntity: {Valid: true}} session => session.AttachedEntity, + ICommonSession {AttachedEntity: {Valid: true}} session => session.AttachedEntity, IComponent component => component.Owner, _ => null }; diff --git a/Content.Server/Administration/Logs/Converters/PlayerSessionConverter.cs b/Content.Server/Administration/Logs/Converters/PlayerSessionConverter.cs index 0605c2db2a..c1567448cc 100644 --- a/Content.Server/Administration/Logs/Converters/PlayerSessionConverter.cs +++ b/Content.Server/Administration/Logs/Converters/PlayerSessionConverter.cs @@ -1,5 +1,5 @@ using System.Text.Json; -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Administration.Logs.Converters; @@ -36,9 +36,9 @@ public sealed class PlayerSessionConverter : AdminLogConverter _admins = new(); + private readonly Dictionary _admins = new(); private readonly HashSet _promotedPlayers = new(); public event Action? OnPermsChanged; - public IEnumerable ActiveAdmins => _admins + public IEnumerable ActiveAdmins => _admins .Where(p => p.Value.Data.Active) .Select(p => p.Key); - public IEnumerable AllAdmins => _admins.Select(p => p.Key); + public IEnumerable AllAdmins => _admins.Select(p => p.Key); private readonly AdminCommandPermissions _commandPermissions = new(); private readonly AdminCommandPermissions _toolshedCommandPermissions = new(); @@ -56,7 +56,7 @@ namespace Content.Server.Administration.Managers public AdminData? GetAdminData(ICommonSession session, bool includeDeAdmin = false) { - if (_admins.TryGetValue((IPlayerSession)session, out var reg) && (reg.Data.Active || includeDeAdmin)) + if (_admins.TryGetValue(session, out var reg) && (reg.Data.Active || includeDeAdmin)) { return reg.Data; } @@ -66,13 +66,13 @@ namespace Content.Server.Administration.Managers public AdminData? GetAdminData(EntityUid uid, bool includeDeAdmin = false) { - if (_playerManager.TryGetSessionByEntity(uid, out var session) && session is IPlayerSession playerSession) - return GetAdminData(playerSession, includeDeAdmin); + if (_playerManager.TryGetSessionByEntity(uid, out var session)) + return GetAdminData(session, includeDeAdmin); return null; } - public void DeAdmin(IPlayerSession session) + public void DeAdmin(ICommonSession session) { if (!_admins.TryGetValue(session, out var reg)) { @@ -95,7 +95,7 @@ namespace Content.Server.Administration.Managers UpdateAdminStatus(session); } - public void ReAdmin(IPlayerSession session) + public void ReAdmin(ICommonSession session) { if (!_admins.TryGetValue(session, out var reg)) { @@ -119,7 +119,7 @@ namespace Content.Server.Administration.Managers UpdateAdminStatus(session); } - public async void ReloadAdmin(IPlayerSession player) + public async void ReloadAdmin(ICommonSession player) { var data = await LoadAdminData(player); var curAdmin = _admins.GetValueOrDefault(player); @@ -236,7 +236,7 @@ namespace Content.Server.Administration.Managers _toolshed.ActivePermissionController = this; } - public void PromoteHost(IPlayerSession player) + public void PromoteHost(ICommonSession player) { _promotedPlayers.Add(player.UserId); @@ -250,7 +250,7 @@ namespace Content.Server.Administration.Managers } // NOTE: Also sends commands list for non admins.. - private void UpdateAdminStatus(IPlayerSession session) + private void UpdateAdminStatus(ICommonSession session) { var msg = new MsgUpdateAdminStatus(); @@ -290,7 +290,7 @@ namespace Content.Server.Administration.Managers } } - private async void LoginAdminMaybe(IPlayerSession session) + private async void LoginAdminMaybe(ICommonSession session) { var adminDat = await LoadAdminData(session); if (adminDat == null) @@ -323,7 +323,7 @@ namespace Content.Server.Administration.Managers UpdateAdminStatus(session); } - private async Task<(AdminData dat, int? rankId, bool specialLogin)?> LoadAdminData(IPlayerSession session) + private async Task<(AdminData dat, int? rankId, bool specialLogin)?> LoadAdminData(ICommonSession session) { var promoteHost = IsLocal(session) && _cfg.GetCVar(CCVars.ConsoleLoginLocal) || _promotedPlayers.Contains(session.UserId) @@ -387,7 +387,7 @@ namespace Content.Server.Administration.Managers } } - private static bool IsLocal(IPlayerSession player) + private static bool IsLocal(ICommonSession player) { var ep = player.ConnectedClient.RemoteEndPoint; var addr = ep.Address; @@ -419,7 +419,7 @@ namespace Content.Server.Administration.Managers return false; } - public bool CanCommand(IPlayerSession session, string cmdName) + public bool CanCommand(ICommonSession session, string cmdName) { if (_commandPermissions.AnyCommands.Contains(cmdName)) { @@ -474,7 +474,7 @@ namespace Content.Server.Administration.Managers return true; } - var data = GetAdminData((IPlayerSession)user); + var data = GetAdminData(user); if (data == null) { // Player isn't an admin. @@ -520,32 +520,32 @@ namespace Content.Server.Administration.Managers return (attribs.Length != 0, attribs); } - public bool CanViewVar(IPlayerSession session) + public bool CanViewVar(ICommonSession session) { return CanCommand(session, "vv"); } - public bool CanAdminPlace(IPlayerSession session) + public bool CanAdminPlace(ICommonSession session) { return GetAdminData(session)?.CanAdminPlace() ?? false; } - public bool CanScript(IPlayerSession session) + public bool CanScript(ICommonSession session) { return GetAdminData(session)?.CanScript() ?? false; } - public bool CanAdminMenu(IPlayerSession session) + public bool CanAdminMenu(ICommonSession session) { return GetAdminData(session)?.CanAdminMenu() ?? false; } - public bool CanAdminReloadPrototypes(IPlayerSession session) + public bool CanAdminReloadPrototypes(ICommonSession session) { return GetAdminData(session)?.CanAdminReloadPrototypes() ?? false; } - private void SendPermsChangedEvent(IPlayerSession session) + private void SendPermsChangedEvent(ICommonSession session) { var flags = GetAdminData(session)?.Flags; OnPermsChanged?.Invoke(new AdminPermsChangedEventArgs(session, flags)); @@ -553,7 +553,7 @@ namespace Content.Server.Administration.Managers private sealed class AdminReg { - public readonly IPlayerSession Session; + public readonly ICommonSession Session; public AdminData Data; public int? RankId; @@ -561,7 +561,7 @@ namespace Content.Server.Administration.Managers // Such as console.loginlocal or promotehost public bool IsSpecialLogin; - public AdminReg(IPlayerSession session, AdminData data) + public AdminReg(ICommonSession session, AdminData data) { Data = data; Session = session; diff --git a/Content.Server/Administration/Managers/BanManager.cs b/Content.Server/Administration/Managers/BanManager.cs index 765df17b17..4d51d35576 100644 --- a/Content.Server/Administration/Managers/BanManager.cs +++ b/Content.Server/Administration/Managers/BanManager.cs @@ -15,6 +15,7 @@ using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Utility; @@ -283,7 +284,7 @@ public sealed class BanManager : IBanManager, IPostInjectInit SendRoleBans(player); } - public void SendRoleBans(IPlayerSession pSession) + public void SendRoleBans(ICommonSession pSession) { var roleBans = _cachedRoleBans.GetValueOrDefault(pSession.UserId) ?? new HashSet(); var bans = new MsgRoleBans() diff --git a/Content.Server/Administration/Managers/IAdminManager.cs b/Content.Server/Administration/Managers/IAdminManager.cs index eeed5cc36e..a52ec7b099 100644 --- a/Content.Server/Administration/Managers/IAdminManager.cs +++ b/Content.Server/Administration/Managers/IAdminManager.cs @@ -1,9 +1,8 @@ using Content.Shared.Administration; using Content.Shared.Administration.Managers; -using Robust.Server.Player; +using Robust.Shared.Player; using Robust.Shared.Toolshed; - namespace Content.Server.Administration.Managers { /// @@ -22,12 +21,12 @@ namespace Content.Server.Administration.Managers /// /// This does not include admins that are de-adminned. /// - IEnumerable ActiveAdmins { get; } + IEnumerable ActiveAdmins { get; } /// /// Gets all admins currently on the server, even de-adminned ones. /// - IEnumerable AllAdmins { get; } + IEnumerable AllAdmins { get; } /// /// De-admins an admin temporarily so they are effectively a normal player. @@ -35,18 +34,18 @@ namespace Content.Server.Administration.Managers /// /// De-adminned admins are able to re-admin at any time if they so desire. /// - void DeAdmin(IPlayerSession session); + void DeAdmin(ICommonSession session); /// /// Re-admins a de-adminned admin. /// - void ReAdmin(IPlayerSession session); + void ReAdmin(ICommonSession session); /// /// Re-loads the permissions of an player in case their admin data changed DB-side. /// /// - void ReloadAdmin(IPlayerSession player); + void ReloadAdmin(ICommonSession player); /// /// Reloads admin permissions for all admins with a certain rank. @@ -57,7 +56,7 @@ namespace Content.Server.Administration.Managers void Initialize(); - void PromoteHost(IPlayerSession player); + void PromoteHost(ICommonSession player); bool TryGetCommandFlags(CommandSpec command, out AdminFlags[]? flags); } diff --git a/Content.Server/Administration/Managers/IBanManager.cs b/Content.Server/Administration/Managers/IBanManager.cs index 8458feac8d..dafe3d35bd 100644 --- a/Content.Server/Administration/Managers/IBanManager.cs +++ b/Content.Server/Administration/Managers/IBanManager.cs @@ -2,8 +2,8 @@ using System.Collections.Immutable; using System.Net; using System.Threading.Tasks; using Content.Shared.Database; -using Robust.Server.Player; using Robust.Shared.Network; +using Robust.Shared.Player; namespace Content.Server.Administration.Managers; @@ -55,5 +55,5 @@ public interface IBanManager /// Sends role bans to the target /// /// Player's session - public void SendRoleBans(IPlayerSession pSession); + public void SendRoleBans(ICommonSession pSession); } diff --git a/Content.Server/Administration/Notes/AdminNotesManager.cs b/Content.Server/Administration/Notes/AdminNotesManager.cs index 8a7846663f..0c1e7f3daa 100644 --- a/Content.Server/Administration/Notes/AdminNotesManager.cs +++ b/Content.Server/Administration/Notes/AdminNotesManager.cs @@ -11,7 +11,7 @@ using Content.Shared.Database; using Content.Shared.Players.PlayTimeTracking; using Robust.Shared.Configuration; using Robust.Shared.Network; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.Administration.Notes; diff --git a/Content.Server/Administration/Notes/AdminNotesSystem.cs b/Content.Server/Administration/Notes/AdminNotesSystem.cs index fd9f3f6bfa..f2eb033dca 100644 --- a/Content.Server/Administration/Notes/AdminNotesSystem.cs +++ b/Content.Server/Administration/Notes/AdminNotesSystem.cs @@ -1,13 +1,13 @@ using Content.Server.Administration.Commands; using Content.Server.Chat.Managers; using Content.Server.EUI; -using Content.Shared.Chat; using Content.Shared.Database; using Content.Shared.Verbs; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; +using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Server.Administration.Notes; diff --git a/Content.Server/Administration/Notes/IAdminNotesManager.cs b/Content.Server/Administration/Notes/IAdminNotesManager.cs index ae7133c56d..a726bd11c8 100644 --- a/Content.Server/Administration/Notes/IAdminNotesManager.cs +++ b/Content.Server/Administration/Notes/IAdminNotesManager.cs @@ -2,7 +2,7 @@ using System.Threading.Tasks; using Content.Server.Database; using Content.Shared.Administration.Notes; using Content.Shared.Database; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.Administration.Notes; diff --git a/Content.Server/Administration/QuickDialogSystem.OpenDialog.cs b/Content.Server/Administration/QuickDialogSystem.OpenDialog.cs index 521bee776f..fb013a88ad 100644 --- a/Content.Server/Administration/QuickDialogSystem.OpenDialog.cs +++ b/Content.Server/Administration/QuickDialogSystem.OpenDialog.cs @@ -1,6 +1,6 @@ using Content.Shared.Administration; using JetBrains.Annotations; -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Administration; @@ -16,7 +16,7 @@ public sealed partial class QuickDialogSystem /// The action to execute upon the dialog being cancelled. /// Type of the input. [PublicAPI] - public void OpenDialog(IPlayerSession session, string title, string prompt, Action okAction, + public void OpenDialog(ICommonSession session, string title, string prompt, Action okAction, Action? cancelAction = null) { OpenDialogInternal( @@ -53,7 +53,7 @@ public sealed partial class QuickDialogSystem /// Type of the first input. /// Type of the second input. [PublicAPI] - public void OpenDialog(IPlayerSession session, string title, string prompt1, string prompt2, + public void OpenDialog(ICommonSession session, string title, string prompt1, string prompt2, Action okAction, Action? cancelAction = null) { OpenDialogInternal( @@ -96,7 +96,7 @@ public sealed partial class QuickDialogSystem /// Type of the second input. /// Type of the third input. [PublicAPI] - public void OpenDialog(IPlayerSession session, string title, string prompt1, string prompt2, + public void OpenDialog(ICommonSession session, string title, string prompt1, string prompt2, string prompt3, Action okAction, Action? cancelAction = null) { OpenDialogInternal( @@ -142,7 +142,7 @@ public sealed partial class QuickDialogSystem /// Type of the third input. /// Type of the fourth input. [PublicAPI] - public void OpenDialog(IPlayerSession session, string title, string prompt1, string prompt2, + public void OpenDialog(ICommonSession session, string title, string prompt1, string prompt2, string prompt3, string prompt4, Action okAction, Action? cancelAction = null) { OpenDialogInternal( diff --git a/Content.Server/Administration/QuickDialogSystem.cs b/Content.Server/Administration/QuickDialogSystem.cs index 51b8cf79c2..96423e5223 100644 --- a/Content.Server/Administration/QuickDialogSystem.cs +++ b/Content.Server/Administration/QuickDialogSystem.cs @@ -1,12 +1,9 @@ -using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.CodeAnalysis; using Content.Shared.Administration; -using Microsoft.CodeAnalysis.CSharp.Syntax; using Robust.Server.Player; using Robust.Shared.Enums; using Robust.Shared.Network; using Robust.Shared.Player; -using Robust.Shared.Serialization.TypeSerializers.Interfaces; namespace Content.Server.Administration; @@ -87,7 +84,7 @@ public sealed partial class QuickDialogSystem : EntitySystem _openDialogsByUser.Remove(user); } - private void OpenDialogInternal(IPlayerSession session, string title, List entries, QuickDialogButtonFlag buttons, Action okAction, Action cancelAction) + private void OpenDialogInternal(ICommonSession session, string title, List entries, QuickDialogButtonFlag buttons, Action okAction, Action cancelAction) { var did = GetDialogId(); RaiseNetworkEvent( diff --git a/Content.Server/Administration/Systems/AdminSystem.cs b/Content.Server/Administration/Systems/AdminSystem.cs index 66f7a8999b..feabaa2aad 100644 --- a/Content.Server/Administration/Systems/AdminSystem.cs +++ b/Content.Server/Administration/Systems/AdminSystem.cs @@ -109,7 +109,7 @@ namespace Content.Server.Administration.Systems } } - public void UpdatePlayerList(IPlayerSession player) + public void UpdatePlayerList(ICommonSession player) { _playerList[player.UserId] = GetPlayerInfo(player.Data, player); @@ -203,7 +203,7 @@ namespace Content.Server.Administration.Systems UpdatePanicBunker(); } - private void SendFullPlayerList(IPlayerSession playerSession) + private void SendFullPlayerList(ICommonSession playerSession) { var ev = new FullPlayerListEvent(); @@ -212,7 +212,7 @@ namespace Content.Server.Administration.Systems RaiseNetworkEvent(ev, playerSession.ConnectedClient); } - private PlayerInfo GetPlayerInfo(IPlayerData data, IPlayerSession? session) + private PlayerInfo GetPlayerInfo(SessionData data, ICommonSession? session) { var name = data.UserName; var entityName = string.Empty; @@ -326,7 +326,7 @@ namespace Content.Server.Administration.Systems /// chat messages and showing a popup to other players. /// Their items are dropped on the ground. /// - public void Erase(IPlayerSession player) + public void Erase(ICommonSession player) { var entity = player.AttachedEntity; _chat.DeleteMessagesBy(player); diff --git a/Content.Server/Administration/Systems/AdminTestArenaSystem.cs b/Content.Server/Administration/Systems/AdminTestArenaSystem.cs index e65acf571c..e3671bcdfb 100644 --- a/Content.Server/Administration/Systems/AdminTestArenaSystem.cs +++ b/Content.Server/Administration/Systems/AdminTestArenaSystem.cs @@ -1,8 +1,8 @@ using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Map; using Robust.Shared.Map.Components; using Robust.Shared.Network; +using Robust.Shared.Player; namespace Content.Server.Administration.Systems; @@ -20,7 +20,7 @@ public sealed class AdminTestArenaSystem : EntitySystem public Dictionary ArenaMap { get; private set; } = new(); public Dictionary ArenaGrid { get; private set; } = new(); - public (EntityUid Map, EntityUid? Grid) AssertArenaLoaded(IPlayerSession admin) + public (EntityUid Map, EntityUid? Grid) AssertArenaLoaded(ICommonSession admin) { if (ArenaMap.TryGetValue(admin.UserId, out var arenaMap) && !Deleted(arenaMap) && !Terminating(arenaMap)) { diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.cs b/Content.Server/Administration/Systems/AdminVerbSystem.cs index 0f0c562356..bc065745f5 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.cs @@ -24,11 +24,10 @@ using Content.Shared.Popups; using Content.Shared.Verbs; using Robust.Server.Console; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; using Robust.Shared.Map.Components; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Timing; using Robust.Shared.Toolshed; @@ -427,7 +426,7 @@ namespace Content.Server.Administration.Systems } } - public void OpenEditSolutionsEui(IPlayerSession session, EntityUid uid) + public void OpenEditSolutionsEui(ICommonSession session, EntityUid uid) { if (session.AttachedEntity == null) return; diff --git a/Content.Server/Administration/Systems/BwoinkSystem.cs b/Content.Server/Administration/Systems/BwoinkSystem.cs index 98e5af1126..31ef285a88 100644 --- a/Content.Server/Administration/Systems/BwoinkSystem.cs +++ b/Content.Server/Administration/Systems/BwoinkSystem.cs @@ -17,6 +17,7 @@ using Robust.Shared; using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -119,7 +120,7 @@ namespace Content.Server.Administration.Systems _typingUpdateTimestamps[args.SenderSession.UserId] = (_timing.RealTime, msg.Typing); // Non-admins can only ever type on their own ahelp, guard against fake messages - var isAdmin = _adminManager.GetAdminData((IPlayerSession) args.SenderSession)?.HasFlag(AdminFlags.Adminhelp) ?? false; + var isAdmin = _adminManager.GetAdminData(args.SenderSession)?.HasFlag(AdminFlags.Adminhelp) ?? false; var channel = isAdmin ? msg.Channel : args.SenderSession.UserId; var update = new BwoinkPlayerTypingUpdated(channel, args.SenderSession.Name, msg.Typing); @@ -376,7 +377,7 @@ namespace Content.Server.Administration.Systems protected override void OnBwoinkTextMessage(BwoinkTextMessage message, EntitySessionEventArgs eventArgs) { base.OnBwoinkTextMessage(message, eventArgs); - var senderSession = (IPlayerSession) eventArgs.SenderSession; + var senderSession = eventArgs.SenderSession; // TODO: Sanitize text? // Confirm that this person is actually allowed to send a message here. diff --git a/Content.Server/Administration/Toolshed/AdminsCommand.cs b/Content.Server/Administration/Toolshed/AdminsCommand.cs index aa82e0f1d9..1d64f748fd 100644 --- a/Content.Server/Administration/Toolshed/AdminsCommand.cs +++ b/Content.Server/Administration/Toolshed/AdminsCommand.cs @@ -1,6 +1,6 @@ using Content.Server.Administration.Managers; using Content.Shared.Administration; -using Robust.Server.Player; +using Robust.Shared.Player; using Robust.Shared.Toolshed; namespace Content.Server.Administration.Toolshed; @@ -11,13 +11,13 @@ public sealed class AdminsCommand : ToolshedCommand [Dependency] private readonly IAdminManager _admin = default!; [CommandImplementation("active")] - public IEnumerable Active() + public IEnumerable Active() { return _admin.ActiveAdmins; } [CommandImplementation("all")] - public IEnumerable All() + public IEnumerable All() { return _admin.AllAdmins; } diff --git a/Content.Server/Afk/AFKSystem.cs b/Content.Server/Afk/AFKSystem.cs index 0938f45f73..f634a415dc 100644 --- a/Content.Server/Afk/AFKSystem.cs +++ b/Content.Server/Afk/AFKSystem.cs @@ -1,4 +1,3 @@ -using System.Linq; using Content.Server.Afk.Events; using Content.Server.GameTicking; using Content.Shared.CCVar; @@ -24,7 +23,7 @@ public sealed class AFKSystem : EntitySystem private float _checkDelay; private TimeSpan _checkTime; - private readonly HashSet _afkPlayers = new(); + private readonly HashSet _afkPlayers = new(); public override void Initialize() { @@ -73,11 +72,9 @@ public sealed class AFKSystem : EntitySystem _checkTime = _timing.CurTime + TimeSpan.FromSeconds(_checkDelay); - foreach (var session in Filter.GetAllPlayers()) + foreach (var pSession in Filter.GetAllPlayers()) { - if (session.Status != SessionStatus.InGame) continue; - - var pSession = (IPlayerSession) session; + if (pSession.Status != SessionStatus.InGame) continue; var isAfk = _afkManager.IsAfk(pSession); if (isAfk && _afkPlayers.Add(pSession)) diff --git a/Content.Server/Afk/AfkManager.cs b/Content.Server/Afk/AfkManager.cs index 24cd1e28ce..52dc7715df 100644 --- a/Content.Server/Afk/AfkManager.cs +++ b/Content.Server/Afk/AfkManager.cs @@ -5,6 +5,7 @@ using Robust.Shared.Configuration; using Robust.Shared.Console; using Robust.Shared.Enums; using Robust.Shared.Input; +using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.Afk @@ -20,13 +21,13 @@ namespace Content.Server.Afk /// /// The player to check. /// True if the player is AFK, false otherwise. - bool IsAfk(IPlayerSession player); + bool IsAfk(ICommonSession player); /// /// Resets AFK status for the player as if they just did an action and are definitely not AFK. /// /// The player to set AFK status for. - void PlayerDidAction(IPlayerSession player); + void PlayerDidAction(ICommonSession player); void Initialize(); } @@ -40,7 +41,7 @@ namespace Content.Server.Afk [Dependency] private readonly IConfigurationManager _cfg = default!; [Dependency] private readonly IConsoleHost _consoleHost = default!; - private readonly Dictionary _lastActionTimes = new(); + private readonly Dictionary _lastActionTimes = new(); public void Initialize() { @@ -55,7 +56,7 @@ namespace Content.Server.Afk HandleInputCmd); } - public void PlayerDidAction(IPlayerSession player) + public void PlayerDidAction(ICommonSession player) { if (player.Status == SessionStatus.Disconnected) // Make sure we don't re-add to the dictionary if the player is disconnected now. @@ -64,7 +65,7 @@ namespace Content.Server.Afk _lastActionTimes[player] = _gameTiming.RealTime; } - public bool IsAfk(IPlayerSession player) + public bool IsAfk(ICommonSession player) { if (!_lastActionTimes.TryGetValue(player, out var time)) // Some weird edge case like disconnected clients. Just say true I guess. @@ -87,13 +88,13 @@ namespace Content.Server.Afk private void ConsoleHostOnAnyCommandExecuted(IConsoleShell shell, string commandname, string argstr, string[] args) { - if (shell.Player is IPlayerSession player) + if (shell.Player is { } player) PlayerDidAction(player); } private void HandleInputCmd(FullInputCmdMessage msg, EntitySessionEventArgs args) { - PlayerDidAction((IPlayerSession) args.SenderSession); + PlayerDidAction(args.SenderSession); } } } diff --git a/Content.Server/Afk/Events/AFKEvent.cs b/Content.Server/Afk/Events/AFKEvent.cs index 6adb950e47..ee9d548043 100644 --- a/Content.Server/Afk/Events/AFKEvent.cs +++ b/Content.Server/Afk/Events/AFKEvent.cs @@ -1,4 +1,4 @@ -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Afk.Events; @@ -8,9 +8,9 @@ namespace Content.Server.Afk.Events; [ByRefEvent] public readonly struct AFKEvent { - public readonly IPlayerSession Session; + public readonly ICommonSession Session; - public AFKEvent(IPlayerSession playerSession) + public AFKEvent(ICommonSession playerSession) { Session = playerSession; } diff --git a/Content.Server/Afk/Events/UnAFKEvent.cs b/Content.Server/Afk/Events/UnAFKEvent.cs index 3dd034583c..0983c256f0 100644 --- a/Content.Server/Afk/Events/UnAFKEvent.cs +++ b/Content.Server/Afk/Events/UnAFKEvent.cs @@ -1,4 +1,4 @@ -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Afk.Events; @@ -8,9 +8,9 @@ namespace Content.Server.Afk.Events; [ByRefEvent] public readonly struct UnAFKEvent { - public readonly IPlayerSession Session; + public readonly ICommonSession Session; - public UnAFKEvent(IPlayerSession playerSession) + public UnAFKEvent(ICommonSession playerSession) { Session = playerSession; } diff --git a/Content.Server/Alert/Commands/ClearAlert.cs b/Content.Server/Alert/Commands/ClearAlert.cs index e43f06413c..1759612702 100644 --- a/Content.Server/Alert/Commands/ClearAlert.cs +++ b/Content.Server/Alert/Commands/ClearAlert.cs @@ -2,7 +2,6 @@ using Content.Server.Administration; using Content.Server.Commands; using Content.Shared.Administration; using Content.Shared.Alert; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Alert.Commands @@ -16,7 +15,7 @@ namespace Content.Server.Alert.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player?.AttachedEntity == null) { shell.WriteLine("You don't have an entity."); diff --git a/Content.Server/Alert/Commands/ShowAlert.cs b/Content.Server/Alert/Commands/ShowAlert.cs index edb634b546..11901e9af0 100644 --- a/Content.Server/Alert/Commands/ShowAlert.cs +++ b/Content.Server/Alert/Commands/ShowAlert.cs @@ -2,7 +2,6 @@ using Content.Server.Administration; using Content.Server.Commands; using Content.Shared.Administration; using Content.Shared.Alert; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Alert.Commands @@ -16,7 +15,7 @@ namespace Content.Server.Alert.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player?.AttachedEntity == null) { shell.WriteLine("You cannot run this from the server or without an attached entity."); diff --git a/Content.Server/AlertLevel/Commands/SetAlertLevelCommand.cs b/Content.Server/AlertLevel/Commands/SetAlertLevelCommand.cs index 009a8b5f23..2c432a2419 100644 --- a/Content.Server/AlertLevel/Commands/SetAlertLevelCommand.cs +++ b/Content.Server/AlertLevel/Commands/SetAlertLevelCommand.cs @@ -3,7 +3,6 @@ using Content.Server.Administration; using Content.Server.Station.Systems; using Content.Shared.Administration; using JetBrains.Annotations; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.AlertLevel.Commands @@ -19,7 +18,7 @@ namespace Content.Server.AlertLevel.Commands public CompletionResult GetCompletion(IConsoleShell shell, string[] args) { var levelNames = new string[] {}; - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player?.AttachedEntity != null) { var stationUid = EntitySystem.Get().GetOwningStation(player.AttachedEntity.Value); @@ -54,7 +53,7 @@ namespace Content.Server.AlertLevel.Commands return; } - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player?.AttachedEntity == null) { shell.WriteLine(Loc.GetString("shell-only-players-can-run-this-command")); diff --git a/Content.Server/Antag/AntagSelectionSystem.cs b/Content.Server/Antag/AntagSelectionSystem.cs index 5e323f5ab8..737b723d39 100644 --- a/Content.Server/Antag/AntagSelectionSystem.cs +++ b/Content.Server/Antag/AntagSelectionSystem.cs @@ -22,6 +22,7 @@ using Content.Server.Station.Systems; using Content.Server.Shuttles.Systems; using Content.Shared.Mobs; using Robust.Server.Containers; +using Robust.Shared.Player; using Robust.Shared.Prototypes; namespace Content.Server.Antag; @@ -88,9 +89,9 @@ public sealed class AntagSelectionSystem : GameRuleSystem out List chosen, bool includeHeads = false) { - var allPlayers = _playerSystem.ServerSessions.ToList(); - var playerList = new List(); - var prefList = new List(); + var allPlayers = _playerSystem.Sessions.ToList(); + var playerList = new List(); + var prefList = new List(); chosen = new List(); foreach (var player in allPlayers) { @@ -116,7 +117,7 @@ public sealed class AntagSelectionSystem : GameRuleSystem var antags = Math.Clamp(allPlayers.Count / antagsPerPlayer, 1, maxAntags); for (var antag = 0; antag < antags; antag++) { - IPlayerSession chosenPlayer = null!; + ICommonSession? chosenPlayer = null; if (prefList.Count == 0) { if (playerList.Count == 0) diff --git a/Content.Server/Arcade/BlockGame/BlockGame.Ui.cs b/Content.Server/Arcade/BlockGame/BlockGame.Ui.cs index 92a96ea226..ef69600783 100644 --- a/Content.Server/Arcade/BlockGame/BlockGame.Ui.cs +++ b/Content.Server/Arcade/BlockGame/BlockGame.Ui.cs @@ -1,6 +1,6 @@ using Content.Shared.Arcade; -using Robust.Server.Player; using System.Linq; +using Robust.Shared.Player; namespace Content.Server.Arcade.BlockGame; @@ -166,7 +166,7 @@ public sealed partial class BlockGame /// /// The message to send to a specific player/spectator. /// The target recipient. - private void SendMessage(BoundUserInterfaceMessage message, IPlayerSession session) + private void SendMessage(BoundUserInterfaceMessage message, ICommonSession session) { if (_uiSystem.TryGetUi(_owner, BlockGameUiKey.Key, out var bui)) _uiSystem.TrySendUiMessage(bui, message, session); @@ -176,7 +176,7 @@ public sealed partial class BlockGame /// Handles sending the current state of the game to a player that has just opened the UI. ///
/// The target recipient. - public void UpdateNewPlayerUI(IPlayerSession session) + public void UpdateNewPlayerUI(ICommonSession session) { if (_gameOver) { @@ -209,7 +209,7 @@ public sealed partial class BlockGame /// Handles broadcasting the full player-visible game state to a specific player/spectator. ///
/// The target recipient. - private void FullUpdate(IPlayerSession session) + private void FullUpdate(ICommonSession session) { UpdateFieldUI(session); SendNextPieceUpdate(session); @@ -235,7 +235,7 @@ public sealed partial class BlockGame /// Handles broadcasting the current location of all of the blocks in the playfield + the active piece to a specific player/spectator. ///
/// The target recipient. - public void UpdateFieldUI(IPlayerSession session) + public void UpdateFieldUI(ICommonSession session) { if (!Started) return; @@ -283,7 +283,7 @@ public sealed partial class BlockGame /// Broadcasts the state of the next queued piece to a specific viewer. ///
/// The target recipient. - private void SendNextPieceUpdate(IPlayerSession session) + private void SendNextPieceUpdate(ICommonSession session) { SendMessage(new BlockGameMessages.BlockGameVisualUpdateMessage(NextPiece.BlocksForPreview(), BlockGameMessages.BlockGameVisualType.NextBlock), session); } @@ -303,7 +303,7 @@ public sealed partial class BlockGame /// Broadcasts the state of the currently held piece to a specific viewer. ///
/// The target recipient. - private void SendHoldPieceUpdate(IPlayerSession session) + private void SendHoldPieceUpdate(ICommonSession session) { if (HeldPiece.HasValue) SendMessage(new BlockGameMessages.BlockGameVisualUpdateMessage(HeldPiece.Value.BlocksForPreview(), BlockGameMessages.BlockGameVisualType.HoldBlock), session); @@ -323,7 +323,7 @@ public sealed partial class BlockGame /// Broadcasts the current game level to a specific viewer. ///
/// The target recipient. - private void SendLevelUpdate(IPlayerSession session) + private void SendLevelUpdate(ICommonSession session) { SendMessage(new BlockGameMessages.BlockGameLevelUpdateMessage(Level), session); } @@ -340,7 +340,7 @@ public sealed partial class BlockGame /// Broadcasts the current game score to a specific viewer. ///
/// The target recipient. - private void SendPointsUpdate(IPlayerSession session) + private void SendPointsUpdate(ICommonSession session) { SendMessage(new BlockGameMessages.BlockGameScoreUpdateMessage(Points), session); } @@ -357,7 +357,7 @@ public sealed partial class BlockGame /// Broadcasts the current game high score positions to a specific viewer. /// /// The target recipient. - private void SendHighscoreUpdate(IPlayerSession session) + private void SendHighscoreUpdate(ICommonSession session) { SendMessage(new BlockGameMessages.BlockGameHighScoreUpdateMessage(_arcadeSystem.GetLocalHighscores(), _arcadeSystem.GetGlobalHighscores()), session); } diff --git a/Content.Server/Arcade/BlockGame/BlockGameArcadeComponent.cs b/Content.Server/Arcade/BlockGame/BlockGameArcadeComponent.cs index 268d5be4d2..5613d91544 100644 --- a/Content.Server/Arcade/BlockGame/BlockGameArcadeComponent.cs +++ b/Content.Server/Arcade/BlockGame/BlockGameArcadeComponent.cs @@ -1,4 +1,4 @@ -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Arcade.BlockGame; @@ -13,10 +13,10 @@ public sealed partial class BlockGameArcadeComponent : Component /// /// The player currently playing the active session of NT-BG. /// - public IPlayerSession? Player = null; + public ICommonSession? Player = null; /// /// The players currently viewing (but not playing) the active session of NT-BG. /// - public readonly List Spectators = new(); + public readonly List Spectators = new(); } diff --git a/Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs b/Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs index dac29accc9..ecc5bfd3e2 100644 --- a/Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs +++ b/Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs @@ -2,7 +2,7 @@ using Content.Server.Power.Components; using Content.Server.UserInterface; using Content.Shared.Arcade; using Robust.Server.GameObjects; -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Arcade.BlockGame; @@ -30,7 +30,7 @@ public sealed class BlockGameArcadeSystem : EntitySystem } } - private void UpdatePlayerStatus(EntityUid uid, IPlayerSession session, PlayerBoundUserInterface? bui = null, BlockGameArcadeComponent? blockGame = null) + private void UpdatePlayerStatus(EntityUid uid, ICommonSession session, PlayerBoundUserInterface? bui = null, BlockGameArcadeComponent? blockGame = null) { if (!Resolve(uid, ref blockGame)) return; @@ -67,7 +67,7 @@ public sealed class BlockGameArcadeSystem : EntitySystem private void OnAfterUiClose(EntityUid uid, BlockGameArcadeComponent component, BoundUIClosedEvent args) { - if (args.Session is not IPlayerSession session) + if (args.Session is not { } session) return; if (component.Player != session) diff --git a/Content.Server/Atmos/Commands/DeleteGasCommand.cs b/Content.Server/Atmos/Commands/DeleteGasCommand.cs index 0f0c399b11..9e7594c024 100644 --- a/Content.Server/Atmos/Commands/DeleteGasCommand.cs +++ b/Content.Server/Atmos/Commands/DeleteGasCommand.cs @@ -2,7 +2,6 @@ using Content.Server.Administration; using Content.Server.Atmos.EntitySystems; using Content.Shared.Administration; using Content.Shared.Atmos; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; @@ -20,7 +19,7 @@ namespace Content.Server.Atmos.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; EntityUid? gridId; Gas? gas = null; diff --git a/Content.Server/Atmos/Commands/ShowAtmosCommand.cs b/Content.Server/Atmos/Commands/ShowAtmosCommand.cs index 5ad73ec906..263ef947d0 100644 --- a/Content.Server/Atmos/Commands/ShowAtmosCommand.cs +++ b/Content.Server/Atmos/Commands/ShowAtmosCommand.cs @@ -1,7 +1,6 @@ using Content.Server.Administration; using Content.Server.Atmos.EntitySystems; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Atmos.Commands @@ -15,7 +14,7 @@ namespace Content.Server.Atmos.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("You must be a player to use this command."); diff --git a/Content.Server/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs b/Content.Server/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs index 34f558a252..90edd4caed 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs @@ -10,6 +10,7 @@ using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Map; using Robust.Shared.Map.Components; +using Robust.Shared.Player; namespace Content.Server.Atmos.EntitySystems { @@ -27,7 +28,7 @@ namespace Content.Server.Atmos.EntitySystems /// To modify it see and /// . /// - private readonly HashSet _playerObservers = new(); + private readonly HashSet _playerObservers = new(); /// /// Overlay update ticks per second. @@ -48,17 +49,17 @@ namespace Content.Server.Atmos.EntitySystems _playerManager.PlayerStatusChanged -= OnPlayerStatusChanged; } - public bool AddObserver(IPlayerSession observer) + public bool AddObserver(ICommonSession observer) { return _playerObservers.Add(observer); } - public bool HasObserver(IPlayerSession observer) + public bool HasObserver(ICommonSession observer) { return _playerObservers.Contains(observer); } - public bool RemoveObserver(IPlayerSession observer) + public bool RemoveObserver(ICommonSession observer) { if (!_playerObservers.Remove(observer)) { @@ -76,7 +77,7 @@ namespace Content.Server.Atmos.EntitySystems /// /// The observer to toggle. /// true if added, false if removed. - public bool ToggleObserver(IPlayerSession observer) + public bool ToggleObserver(ICommonSession observer) { if (HasObserver(observer)) { diff --git a/Content.Server/Atmos/EntitySystems/GasTankSystem.cs b/Content.Server/Atmos/EntitySystems/GasTankSystem.cs index df867d3516..17715435b2 100644 --- a/Content.Server/Atmos/EntitySystems/GasTankSystem.cs +++ b/Content.Server/Atmos/EntitySystems/GasTankSystem.cs @@ -12,7 +12,6 @@ using Content.Shared.Toggleable; using Content.Shared.Verbs; using JetBrains.Annotations; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Audio; using Robust.Shared.Containers; using Robust.Shared.Physics.Systems; @@ -60,12 +59,6 @@ namespace Content.Server.Atmos.EntitySystems private void OnGasTankToggleInternals(Entity ent, ref GasTankToggleInternalsMessage args) { - if (args.Session is not IPlayerSession playerSession || - playerSession.AttachedEntity == null) - { - return; - } - ToggleInternals(ent); } diff --git a/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs b/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs index c229ef50c9..b0e8cf71c7 100644 --- a/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs +++ b/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs @@ -16,6 +16,7 @@ using Robust.Shared; using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Map; +using Robust.Shared.Player; using Robust.Shared.Threading; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -35,7 +36,7 @@ namespace Content.Server.Atmos.EntitySystems [Robust.Shared.IoC.Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!; [Robust.Shared.IoC.Dependency] private readonly ChunkingSystem _chunkingSys = default!; - private readonly Dictionary>> _lastSentChunks = new(); + private readonly Dictionary>> _lastSentChunks = new(); // Oh look its more duplicated decal system code! private ObjectPool> _chunkIndexPool = @@ -286,12 +287,12 @@ namespace Content.Server.Atmos.EntitySystems // Now we'll go through each player, then through each chunk in range of that player checking if the player is still in range // If they are, check if they need the new data to send (i.e. if there's an overlay for the gas). // Afterwards we reset all the chunk data for the next time we tick. - var players = _playerManager.ServerSessions.Where(x => x.Status == SessionStatus.InGame).ToArray(); + var players = _playerManager.Sessions.Where(x => x.Status == SessionStatus.InGame).ToArray(); var opts = new ParallelOptions { MaxDegreeOfParallelism = _parMan.ParallelProcessCount }; Parallel.ForEach(players, opts, p => UpdatePlayer(p, curTick)); } - private void UpdatePlayer(IPlayerSession playerSession, GameTick curTick) + private void UpdatePlayer(ICommonSession playerSession, GameTick curTick) { var chunksInRange = _chunkingSys.GetChunksForSession(playerSession, ChunkSize, _chunkIndexPool, _chunkViewerPool); var previouslySent = _lastSentChunks[playerSession]; diff --git a/Content.Server/Body/Commands/AddHandCommand.cs b/Content.Server/Body/Commands/AddHandCommand.cs index 308295c06c..655d0c88f9 100644 --- a/Content.Server/Body/Commands/AddHandCommand.cs +++ b/Content.Server/Body/Commands/AddHandCommand.cs @@ -4,7 +4,6 @@ using Content.Server.Body.Systems; using Content.Shared.Administration; using Content.Shared.Body.Components; using Content.Shared.Body.Part; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -27,7 +26,7 @@ namespace Content.Server.Body.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; EntityUid entity; EntityUid hand; diff --git a/Content.Server/Body/Commands/AttachBodyPartCommand.cs b/Content.Server/Body/Commands/AttachBodyPartCommand.cs index 267b520808..24604b88b7 100644 --- a/Content.Server/Body/Commands/AttachBodyPartCommand.cs +++ b/Content.Server/Body/Commands/AttachBodyPartCommand.cs @@ -1,10 +1,8 @@ -using System.Linq; using Content.Server.Administration; using Content.Server.Body.Systems; using Content.Shared.Administration; using Content.Shared.Body.Components; using Content.Shared.Body.Part; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Body.Commands @@ -20,7 +18,7 @@ namespace Content.Server.Body.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; EntityUid bodyId; EntityUid? partUid; diff --git a/Content.Server/Body/Commands/DestroyMechanismCommand.cs b/Content.Server/Body/Commands/DestroyMechanismCommand.cs index 6ad0631150..3aa28f4072 100644 --- a/Content.Server/Body/Commands/DestroyMechanismCommand.cs +++ b/Content.Server/Body/Commands/DestroyMechanismCommand.cs @@ -2,7 +2,6 @@ using Content.Server.Administration; using Content.Server.Body.Systems; using Content.Shared.Administration; using Content.Shared.Body.Components; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Random; @@ -17,7 +16,7 @@ namespace Content.Server.Body.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("Only a player can run this command."); diff --git a/Content.Server/Body/Commands/RemoveHandCommand.cs b/Content.Server/Body/Commands/RemoveHandCommand.cs index 729db4bc44..4a2956ae7a 100644 --- a/Content.Server/Body/Commands/RemoveHandCommand.cs +++ b/Content.Server/Body/Commands/RemoveHandCommand.cs @@ -4,7 +4,6 @@ using Content.Server.Body.Systems; using Content.Shared.Administration; using Content.Shared.Body.Components; using Content.Shared.Body.Part; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Random; @@ -22,7 +21,7 @@ namespace Content.Server.Body.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("Only a player can run this command."); diff --git a/Content.Server/Body/Systems/BodySystem.cs b/Content.Server/Body/Systems/BodySystem.cs index f2f848c488..242b02d78c 100644 --- a/Content.Server/Body/Systems/BodySystem.cs +++ b/Content.Server/Body/Systems/BodySystem.cs @@ -116,7 +116,7 @@ public sealed class BodySystem : SharedBodySystem if (!Resolve(bodyId, ref body, false)) return new HashSet(); - if (LifeStage(bodyId) >= EntityLifeStage.Terminating || EntityManager.IsQueuedForDeletion(bodyId)) + if (TerminatingOrDeleted(bodyId) || EntityManager.IsQueuedForDeletion(bodyId)) return new HashSet(); var xform = Transform(bodyId); diff --git a/Content.Server/Cargo/Systems/CargoSystem.Orders.cs b/Content.Server/Cargo/Systems/CargoSystem.Orders.cs index d9327b5150..f659357ad3 100644 --- a/Content.Server/Cargo/Systems/CargoSystem.Orders.cs +++ b/Content.Server/Cargo/Systems/CargoSystem.Orders.cs @@ -8,7 +8,7 @@ using Content.Shared.Cargo.Events; using Content.Shared.Cargo.Prototypes; using Content.Shared.Database; using Robust.Shared.Map; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Utility; diff --git a/Content.Server/CartridgeLoader/CartridgeLoaderSystem.cs b/Content.Server/CartridgeLoader/CartridgeLoaderSystem.cs index 9f7acce4fd..02b2eee771 100644 --- a/Content.Server/CartridgeLoader/CartridgeLoaderSystem.cs +++ b/Content.Server/CartridgeLoader/CartridgeLoaderSystem.cs @@ -6,9 +6,9 @@ using Content.Shared.CartridgeLoader; using Content.Shared.Interaction; using Robust.Server.Containers; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Containers; using Robust.Shared.Map; +using Robust.Shared.Player; namespace Content.Server.CartridgeLoader; @@ -98,7 +98,7 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem /// and use this method to update its state so the cartridge loaders state can be added to it. /// /// - public void UpdateUiState(EntityUid loaderUid, IPlayerSession? session, CartridgeLoaderComponent? loader) + public void UpdateUiState(EntityUid loaderUid, ICommonSession? session, CartridgeLoaderComponent? loader) { if (!Resolve(loaderUid, ref loader)) return; @@ -122,7 +122,7 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem /// This method is called "UpdateCartridgeUiState" but cartridges and a programs are the same. A cartridge is just a program as a visible item. /// /// - public void UpdateCartridgeUiState(EntityUid loaderUid, BoundUserInterfaceState state, IPlayerSession? session = default!, CartridgeLoaderComponent? loader = default!) + public void UpdateCartridgeUiState(EntityUid loaderUid, BoundUserInterfaceState state, ICommonSession? session = default!, CartridgeLoaderComponent? loader = default!) { if (!Resolve(loaderUid, ref loader)) return; diff --git a/Content.Server/Chat/Commands/AdminChatCommand.cs b/Content.Server/Chat/Commands/AdminChatCommand.cs index 8aa95ffee1..979051e9d3 100644 --- a/Content.Server/Chat/Commands/AdminChatCommand.cs +++ b/Content.Server/Chat/Commands/AdminChatCommand.cs @@ -1,7 +1,6 @@ using Content.Server.Administration; using Content.Server.Chat.Managers; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Chat.Commands @@ -15,7 +14,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = (IPlayerSession?) shell.Player; + var player = shell.Player; if (player == null) { diff --git a/Content.Server/Chat/Commands/LOOCCommand.cs b/Content.Server/Chat/Commands/LOOCCommand.cs index a897a0b2bf..9e16193fc3 100644 --- a/Content.Server/Chat/Commands/LOOCCommand.cs +++ b/Content.Server/Chat/Commands/LOOCCommand.cs @@ -1,6 +1,5 @@ using Content.Server.Chat.Systems; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; @@ -15,7 +14,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError("This command cannot be run from the server."); return; diff --git a/Content.Server/Chat/Commands/MeCommand.cs b/Content.Server/Chat/Commands/MeCommand.cs index 36f86cf4d6..e763d5656e 100644 --- a/Content.Server/Chat/Commands/MeCommand.cs +++ b/Content.Server/Chat/Commands/MeCommand.cs @@ -1,6 +1,5 @@ using Content.Server.Chat.Systems; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; @@ -15,7 +14,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError("This command cannot be run from the server."); return; diff --git a/Content.Server/Chat/Commands/OOCCommand.cs b/Content.Server/Chat/Commands/OOCCommand.cs index bef2024608..36f6303fbd 100644 --- a/Content.Server/Chat/Commands/OOCCommand.cs +++ b/Content.Server/Chat/Commands/OOCCommand.cs @@ -1,6 +1,5 @@ using Content.Server.Chat.Managers; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Chat.Commands @@ -14,7 +13,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError("This command cannot be run from the server."); return; diff --git a/Content.Server/Chat/Commands/SayCommand.cs b/Content.Server/Chat/Commands/SayCommand.cs index 7c2125d8c1..273f908c9a 100644 --- a/Content.Server/Chat/Commands/SayCommand.cs +++ b/Content.Server/Chat/Commands/SayCommand.cs @@ -1,6 +1,5 @@ using Content.Server.Chat.Systems; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; @@ -15,7 +14,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError("This command cannot be run from the server."); return; diff --git a/Content.Server/Chat/Commands/SuicideCommand.cs b/Content.Server/Chat/Commands/SuicideCommand.cs index 389ff039bf..c967ba78d7 100644 --- a/Content.Server/Chat/Commands/SuicideCommand.cs +++ b/Content.Server/Chat/Commands/SuicideCommand.cs @@ -1,7 +1,6 @@ using Content.Server.GameTicking; using Content.Shared.Administration; using Content.Shared.Mind; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; @@ -18,7 +17,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteLine(Loc.GetString("shell-cannot-run-command-from-server")); return; diff --git a/Content.Server/Chat/Commands/WhisperCommand.cs b/Content.Server/Chat/Commands/WhisperCommand.cs index 41eba8b384..c88e2519ee 100644 --- a/Content.Server/Chat/Commands/WhisperCommand.cs +++ b/Content.Server/Chat/Commands/WhisperCommand.cs @@ -1,6 +1,5 @@ using Content.Server.Chat.Systems; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; @@ -15,7 +14,7 @@ namespace Content.Server.Chat.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError("This command cannot be run from the server."); return; diff --git a/Content.Server/Chat/Managers/ChatManager.cs b/Content.Server/Chat/Managers/ChatManager.cs index 88e143d24e..59a9d305bd 100644 --- a/Content.Server/Chat/Managers/ChatManager.cs +++ b/Content.Server/Chat/Managers/ChatManager.cs @@ -10,11 +10,9 @@ using Content.Shared.CCVar; using Content.Shared.Chat; using Content.Shared.Database; using Content.Shared.Mind; -using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Network; using Robust.Shared.Player; -using Robust.Shared.Players; using Robust.Shared.Replays; using Robust.Shared.Utility; @@ -51,8 +49,8 @@ namespace Content.Server.Chat.Managers private bool _oocEnabled = true; private bool _adminOocEnabled = true; - public Dictionary SenderKeys { get; } = new(); - public Dictionary> SenderEntities { get; } = new(); + public Dictionary SenderKeys { get; } = new(); + public Dictionary> SenderEntities { get; } = new(); public void Initialize() { @@ -79,7 +77,7 @@ namespace Content.Server.Chat.Managers DispatchServerAnnouncement(Loc.GetString(val ? "chat-manager-admin-ooc-chat-enabled-message" : "chat-manager-admin-ooc-chat-disabled-message")); } - public void DeleteMessagesBy(IPlayerSession player) + public void DeleteMessagesBy(ICommonSession player) { var key = SenderKeys.GetValueOrDefault(player); var entities = SenderEntities.GetValueOrDefault(player) ?? new HashSet(); @@ -165,7 +163,7 @@ namespace Content.Server.Chat.Managers /// The player sending the message. /// The message. /// The type of message. - public void TrySendOOCMessage(IPlayerSession player, string message, OOCChatType type) + public void TrySendOOCMessage(ICommonSession player, string message, OOCChatType type) { // Check if message exceeds the character limit if (message.Length > MaxMessageLength) @@ -189,7 +187,7 @@ namespace Content.Server.Chat.Managers #region Private API - private void SendOOC(IPlayerSession player, string message) + private void SendOOC(ICommonSession player, string message) { if (_adminManager.IsAdmin(player)) { @@ -226,7 +224,7 @@ namespace Content.Server.Chat.Managers _adminLogger.Add(LogType.Chat, LogImpact.Low, $"OOC from {player:Player}: {message}"); } - private void SendAdminChat(IPlayerSession player, string message) + private void SendAdminChat(ICommonSession player, string message) { if (!_adminManager.IsAdmin(player)) { @@ -326,7 +324,7 @@ namespace Content.Server.Chat.Managers } } - public bool MessageCharacterLimit(IPlayerSession? player, string message) + public bool MessageCharacterLimit(ICommonSession? player, string message) { var isOverLength = false; diff --git a/Content.Server/Chat/Managers/IChatManager.cs b/Content.Server/Chat/Managers/IChatManager.cs index 10103f011d..5317b3054e 100644 --- a/Content.Server/Chat/Managers/IChatManager.cs +++ b/Content.Server/Chat/Managers/IChatManager.cs @@ -1,8 +1,6 @@ using Content.Shared.Chat; -using Robust.Server.Player; using Robust.Shared.Network; using Robust.Shared.Player; -using Robust.Shared.Players; namespace Content.Server.Chat.Managers { @@ -12,12 +10,12 @@ namespace Content.Server.Chat.Managers /// Keys identifying messages sent by a specific player, used when sending /// /// - Dictionary SenderKeys { get; } + Dictionary SenderKeys { get; } /// /// Tracks which entities a player was attached to while sending messages. /// - Dictionary> SenderEntities { get; } + Dictionary> SenderEntities { get; } void Initialize(); @@ -30,7 +28,7 @@ namespace Content.Server.Chat.Managers void DispatchServerMessage(ICommonSession player, string message, bool suppressLog = false); - void TrySendOOCMessage(IPlayerSession player, string message, OOCChatType type); + void TrySendOOCMessage(ICommonSession player, string message, OOCChatType type); void SendHookOOC(string sender, string message); void SendAdminAnnouncement(string message); @@ -47,8 +45,8 @@ namespace Content.Server.Chat.Managers void ChatMessageToAll(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, bool recordReplay, Color? colorOverride = null, string? audioPath = null, float audioVolume = 0, int? senderKey = null); - bool MessageCharacterLimit(IPlayerSession player, string message); + bool MessageCharacterLimit(ICommonSession player, string message); - void DeleteMessagesBy(IPlayerSession player); + void DeleteMessagesBy(ICommonSession player); } } diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs index 455d34c907..3315f61c2f 100644 --- a/Content.Server/Chat/Systems/ChatSystem.cs +++ b/Content.Server/Chat/Systems/ChatSystem.cs @@ -7,7 +7,6 @@ using Content.Server.Administration.Logs; using Content.Server.Administration.Managers; using Content.Server.Chat.Managers; using Content.Server.GameTicking; -using Content.Server.Players; using Content.Server.Station.Components; using Content.Server.Station.Systems; using Content.Shared.ActionBlocker; @@ -18,6 +17,7 @@ using Content.Shared.Ghost; using Content.Shared.IdentityManagement; using Content.Shared.Interaction; using Content.Shared.Mobs.Systems; +using Content.Shared.Players; using Content.Shared.Radio; using Robust.Server.GameObjects; using Robust.Server.Player; @@ -26,7 +26,6 @@ using Robust.Shared.Configuration; using Robust.Shared.Console; using Robust.Shared.Network; using Robust.Shared.Player; -using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Replays; @@ -147,7 +146,7 @@ public sealed partial class ChatSystem : SharedChatSystem InGameICChatType desiredType, bool hideChat, bool hideLog = false, IConsoleShell? shell = null, - IPlayerSession? player = null, string? nameOverride = null, + ICommonSession? player = null, string? nameOverride = null, bool checkRadioPrefix = true, bool ignoreActionBlocker = false) { @@ -172,7 +171,7 @@ public sealed partial class ChatSystem : SharedChatSystem ChatTransmitRange range, bool hideLog = false, IConsoleShell? shell = null, - IPlayerSession? player = null, + ICommonSession? player = null, string? nameOverride = null, bool checkRadioPrefix = true, bool ignoreActionBlocker = false @@ -253,7 +252,7 @@ public sealed partial class ChatSystem : SharedChatSystem InGameOOCChatType type, bool hideChat, IConsoleShell? shell = null, - IPlayerSession? player = null + ICommonSession? player = null ) { if (!CanSendInGame(message, shell, player)) @@ -547,7 +546,7 @@ public sealed partial class ChatSystem : SharedChatSystem } // ReSharper disable once InconsistentNaming - private void SendLOOC(EntityUid source, IPlayerSession player, string message, bool hideChat) + private void SendLOOC(EntityUid source, ICommonSession player, string message, bool hideChat) { var name = FormattedMessage.EscapeText(Identity.Name(source, EntityManager)); @@ -571,7 +570,7 @@ public sealed partial class ChatSystem : SharedChatSystem _adminLogger.Add(LogType.Chat, LogImpact.Low, $"LOOC from {player:Player}: {message}"); } - private void SendDeadChat(EntityUid source, IPlayerSession player, string message, bool hideChat) + private void SendDeadChat(EntityUid source, ICommonSession player, string message, bool hideChat) { var clients = GetDeadChatClients(); var playerName = Name(source); @@ -628,13 +627,13 @@ public sealed partial class ChatSystem : SharedChatSystem initialResult = MessageRangeCheckResult.Full; break; case ChatTransmitRange.GhostRangeLimit: - initialResult = (data.Observer && data.Range < 0 && !_adminManager.IsAdmin((IPlayerSession) session)) ? MessageRangeCheckResult.HideChat : MessageRangeCheckResult.Full; + initialResult = (data.Observer && data.Range < 0 && !_adminManager.IsAdmin(session)) ? MessageRangeCheckResult.HideChat : MessageRangeCheckResult.Full; break; case ChatTransmitRange.HideChat: initialResult = MessageRangeCheckResult.HideChat; break; case ChatTransmitRange.NoGhosts: - initialResult = (data.Observer && !_adminManager.IsAdmin((IPlayerSession) session)) ? MessageRangeCheckResult.Disallowed : MessageRangeCheckResult.Full; + initialResult = (data.Observer && !_adminManager.IsAdmin(session)) ? MessageRangeCheckResult.Disallowed : MessageRangeCheckResult.Full; break; } var insistHideChat = data.HideChatOverride ?? false; @@ -666,7 +665,7 @@ public sealed partial class ChatSystem : SharedChatSystem /// /// Returns true if the given player is 'allowed' to send the given message, false otherwise. /// - private bool CanSendInGame(string message, IConsoleShell? shell = null, IPlayerSession? player = null) + private bool CanSendInGame(string message, IConsoleShell? shell = null, ICommonSession? player = null) { // Non-players don't have to worry about these restrictions. if (player == null) @@ -694,7 +693,7 @@ public sealed partial class ChatSystem : SharedChatSystem { var newMessage = message.Trim(); newMessage = SanitizeMessageReplaceWords(newMessage); - + if (capitalize) newMessage = SanitizeMessageCapital(newMessage); if (capitalizeTheWordI) diff --git a/Content.Server/Chemistry/EntitySystems/ChemistryGuideDataSystem.cs b/Content.Server/Chemistry/EntitySystems/ChemistryGuideDataSystem.cs index 8cbdd82f07..7485c0e901 100644 --- a/Content.Server/Chemistry/EntitySystems/ChemistryGuideDataSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/ChemistryGuideDataSystem.cs @@ -2,6 +2,7 @@ using Content.Shared.Chemistry.Reagent; using Robust.Server.Player; using Robust.Shared.Enums; +using Robust.Shared.Player; using Robust.Shared.Prototypes; namespace Content.Server.Chemistry.EntitySystems; diff --git a/Content.Server/Chunking/ChunkingSystem.cs b/Content.Server/Chunking/ChunkingSystem.cs index 4ef44d1678..6f44c43be8 100644 --- a/Content.Server/Chunking/ChunkingSystem.cs +++ b/Content.Server/Chunking/ChunkingSystem.cs @@ -1,12 +1,12 @@ using System.Linq; using Content.Shared.Decals; using Microsoft.Extensions.ObjectPool; -using Robust.Server.Player; using Robust.Shared; using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Map; using Robust.Shared.Map.Components; +using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Shared.Chunking; @@ -41,7 +41,7 @@ public sealed class ChunkingSystem : EntitySystem private void OnPvsRangeChanged(float value) => _baseViewBounds = Box2.UnitCentered.Scale(value); public Dictionary> GetChunksForSession( - IPlayerSession session, + ICommonSession session, int chunkSize, ObjectPool> indexPool, ObjectPool>> viewerPool, @@ -52,7 +52,7 @@ public sealed class ChunkingSystem : EntitySystem return chunks; } - private HashSet GetSessionViewers(IPlayerSession session) + private HashSet GetSessionViewers(ICommonSession session) { var viewers = new HashSet(); if (session.Status != SessionStatus.InGame || session.AttachedEntity is null) diff --git a/Content.Server/Commands/CommandUtils.cs b/Content.Server/Commands/CommandUtils.cs index 11adaec9a2..172f3324e3 100644 --- a/Content.Server/Commands/CommandUtils.cs +++ b/Content.Server/Commands/CommandUtils.cs @@ -3,6 +3,7 @@ using System.Globalization; using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Network; +using Robust.Shared.Player; namespace Content.Server.Commands { @@ -16,7 +17,7 @@ namespace Content.Server.Commands /// sending a failure to the performer if unable to. /// public static bool TryGetSessionByUsernameOrId(IConsoleShell shell, - string usernameOrId, IPlayerSession performer, [NotNullWhen(true)] out IPlayerSession? session) + string usernameOrId, ICommonSession performer, [NotNullWhen(true)] out ICommonSession? session) { var plyMgr = IoCManager.Resolve(); if (plyMgr.TryGetSessionByUsername(usernameOrId, out session)) return true; @@ -36,7 +37,7 @@ namespace Content.Server.Commands /// sending a failure to the performer if unable to. /// public static bool TryGetAttachedEntityByUsernameOrId(IConsoleShell shell, - string usernameOrId, IPlayerSession performer, out EntityUid attachedEntity) + string usernameOrId, ICommonSession performer, out EntityUid attachedEntity) { attachedEntity = default; if (!TryGetSessionByUsernameOrId(shell, usernameOrId, performer, out var session)) return false; @@ -67,7 +68,7 @@ namespace Content.Server.Commands transform.LocalPosition.Y.ToString(CultureInfo.InvariantCulture)); ruleString = ruleString.Replace("$NAME", entMan.GetComponent(ent).EntityName); - if (shell.Player is IPlayerSession player) + if (shell.Player is { } player) { if (player.AttachedEntity is {Valid: true} p) { diff --git a/Content.Server/Construction/Commands/FixRotationsCommand.cs b/Content.Server/Construction/Commands/FixRotationsCommand.cs index d23fa0a31b..bdbfaf170d 100644 --- a/Content.Server/Construction/Commands/FixRotationsCommand.cs +++ b/Content.Server/Construction/Commands/FixRotationsCommand.cs @@ -3,7 +3,6 @@ using Content.Server.Power.Components; using Content.Shared.Administration; using Content.Shared.Construction; using Content.Shared.Tag; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map.Components; @@ -21,7 +20,7 @@ namespace Content.Server.Construction.Commands public void Execute(IConsoleShell shell, string argsOther, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; EntityUid? gridId; var xformQuery = _entManager.GetEntityQuery(); diff --git a/Content.Server/Construction/Commands/TileReplaceCommand.cs b/Content.Server/Construction/Commands/TileReplaceCommand.cs index ed1fba2424..f63fd4c13e 100644 --- a/Content.Server/Construction/Commands/TileReplaceCommand.cs +++ b/Content.Server/Construction/Commands/TileReplaceCommand.cs @@ -1,6 +1,5 @@ using Content.Server.Administration; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; using Robust.Shared.Map.Components; @@ -20,7 +19,7 @@ sealed class TileReplaceCommand : IConsoleCommand public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; EntityUid? gridId; string tileIdA; string tileIdB; diff --git a/Content.Server/Construction/Commands/TileWallsCommand.cs b/Content.Server/Construction/Commands/TileWallsCommand.cs index 55389e41cc..731d4da7f8 100644 --- a/Content.Server/Construction/Commands/TileWallsCommand.cs +++ b/Content.Server/Construction/Commands/TileWallsCommand.cs @@ -2,10 +2,9 @@ using Content.Server.Administration; using Content.Shared.Administration; using Content.Shared.Maps; using Content.Shared.Tag; -using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; +using Robust.Server.GameObjects; using Robust.Shared.Map.Components; namespace Content.Server.Construction.Commands @@ -29,7 +28,7 @@ namespace Content.Server.Construction.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; EntityUid? gridId; switch (args.Length) diff --git a/Content.Server/Construction/ConstructionSystem.Initial.cs b/Content.Server/Construction/ConstructionSystem.Initial.cs index e74edb5da2..21978f2d0c 100644 --- a/Content.Server/Construction/ConstructionSystem.Initial.cs +++ b/Content.Server/Construction/ConstructionSystem.Initial.cs @@ -16,7 +16,7 @@ using Content.Shared.Interaction; using Content.Shared.Inventory; using Content.Shared.Storage; using Robust.Shared.Containers; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.Construction diff --git a/Content.Server/CrewManifest/CrewManifestSystem.cs b/Content.Server/CrewManifest/CrewManifestSystem.cs index aed0575324..4c4f17f61d 100644 --- a/Content.Server/CrewManifest/CrewManifestSystem.cs +++ b/Content.Server/CrewManifest/CrewManifestSystem.cs @@ -10,10 +10,9 @@ using Content.Shared.CCVar; using Content.Shared.CrewManifest; using Content.Shared.GameTicking; using Content.Shared.StationRecords; -using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Console; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.CrewManifest; @@ -60,7 +59,7 @@ public sealed class CrewManifestSystem : EntitySystem private void OnRequestCrewManifest(RequestCrewManifestMessage message, EntitySessionEventArgs args) { - if (args.SenderSession is not IPlayerSession sessionCast + if (args.SenderSession is not { } sessionCast || !_configManager.GetCVar(CCVars.CrewManifestWithoutEntity)) { return; @@ -93,12 +92,12 @@ public sealed class CrewManifestSystem : EntitySystem private void OnBoundUiClose(EntityUid uid, CrewManifestViewerComponent component, BoundUIClosedEvent ev) { var owningStation = _stationSystem.GetOwningStation(uid); - if (owningStation == null || ev.Session is not IPlayerSession sessionCast) + if (owningStation == null || ev.Session is not { } session) { return; } - CloseEui(owningStation.Value, sessionCast, uid); + CloseEui(owningStation.Value, session, uid); } /// @@ -126,7 +125,7 @@ public sealed class CrewManifestSystem : EntitySystem private void OpenEuiFromBui(EntityUid uid, CrewManifestViewerComponent component, CrewManifestOpenUiMessage msg) { var owningStation = _stationSystem.GetOwningStation(uid); - if (owningStation == null || msg.Session is not IPlayerSession sessionCast) + if (owningStation == null || msg.Session is not { } session) { return; } @@ -136,7 +135,7 @@ public sealed class CrewManifestSystem : EntitySystem return; } - OpenEui(owningStation.Value, sessionCast, uid); + OpenEui(owningStation.Value, session, uid); } /// @@ -145,7 +144,7 @@ public sealed class CrewManifestSystem : EntitySystem /// Station that we're displaying the crew manifest for. /// The player's session. /// If this EUI should be 'owned' by an entity. - public void OpenEui(EntityUid station, IPlayerSession session, EntityUid? owner = null) + public void OpenEui(EntityUid station, ICommonSession session, EntityUid? owner = null) { if (!HasComp(station)) { @@ -252,7 +251,7 @@ public sealed class CrewManifestCommand : IConsoleCommand return; } - if (shell.Player == null || shell.Player is not IPlayerSession session) + if (shell.Player == null || shell.Player is not { } session) { shell.WriteLine("You must run this from a client."); return; diff --git a/Content.Server/Damage/Commands/GodModeCommand.cs b/Content.Server/Damage/Commands/GodModeCommand.cs index 92a0e53f0f..866737f17a 100644 --- a/Content.Server/Damage/Commands/GodModeCommand.cs +++ b/Content.Server/Damage/Commands/GodModeCommand.cs @@ -1,8 +1,6 @@ using Content.Server.Administration; -using Content.Server.Damage.Systems; using Content.Shared.Administration; using Content.Shared.Damage.Systems; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Damage.Commands @@ -18,7 +16,7 @@ namespace Content.Server.Damage.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; EntityUid entity; switch (args.Length) diff --git a/Content.Server/Damage/ForceSay/DamageForceSaySystem.cs b/Content.Server/Damage/ForceSay/DamageForceSaySystem.cs index 3d3346403a..457fab4bb2 100644 --- a/Content.Server/Damage/ForceSay/DamageForceSaySystem.cs +++ b/Content.Server/Damage/ForceSay/DamageForceSaySystem.cs @@ -6,7 +6,6 @@ using Content.Shared.Mobs.Systems; using Content.Shared.Stunnable; using Robust.Server.GameObjects; using Robust.Server.Player; -using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; diff --git a/Content.Server/Database/UserDbDataManager.cs b/Content.Server/Database/UserDbDataManager.cs index f2c506240b..f8b1611fd5 100644 --- a/Content.Server/Database/UserDbDataManager.cs +++ b/Content.Server/Database/UserDbDataManager.cs @@ -2,8 +2,8 @@ using System.Threading.Tasks; using Content.Server.Players.PlayTimeTracking; using Content.Server.Preferences.Managers; -using Robust.Server.Player; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Server.Database; @@ -25,7 +25,7 @@ public sealed class UserDbDataManager // TODO: Ideally connected/disconnected would be subscribed to IPlayerManager directly, // but this runs into ordering issues with game ticker. - public void ClientConnected(IPlayerSession session) + public void ClientConnected(ICommonSession session) { DebugTools.Assert(!_users.ContainsKey(session.UserId), "We should not have any cached data on client connect."); @@ -36,7 +36,7 @@ public sealed class UserDbDataManager _users.Add(session.UserId, data); } - public void ClientDisconnected(IPlayerSession session) + public void ClientDisconnected(ICommonSession session) { _users.Remove(session.UserId, out var data); if (data == null) @@ -49,24 +49,24 @@ public sealed class UserDbDataManager _playTimeTracking.ClientDisconnected(session); } - private async Task Load(IPlayerSession session, CancellationToken cancel) + private async Task Load(ICommonSession session, CancellationToken cancel) { await Task.WhenAll( _prefs.LoadData(session, cancel), _playTimeTracking.LoadData(session, cancel)); } - public Task WaitLoadComplete(IPlayerSession session) + public Task WaitLoadComplete(ICommonSession session) { return _users[session.UserId].Task; } - public bool IsLoadComplete(IPlayerSession session) + public bool IsLoadComplete(ICommonSession session) { return GetLoadTask(session).IsCompleted; } - public Task GetLoadTask(IPlayerSession session) + public Task GetLoadTask(ICommonSession session) { return _users[session.UserId].Task; } diff --git a/Content.Server/Decals/DecalSystem.cs b/Content.Server/Decals/DecalSystem.cs index ed281e05ba..ce2e0711e7 100644 --- a/Content.Server/Decals/DecalSystem.cs +++ b/Content.Server/Decals/DecalSystem.cs @@ -16,6 +16,7 @@ using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Map; using Robust.Shared.Map.Components; +using Robust.Shared.Player; using Robust.Shared.Threading; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -36,7 +37,7 @@ namespace Content.Server.Decals [Dependency] private readonly MapSystem _mapSystem = default!; private readonly Dictionary> _dirtyChunks = new(); - private readonly Dictionary>> _previousSentChunks = new(); + private readonly Dictionary>> _previousSentChunks = new(); private static readonly Vector2 _boundsMinExpansion = new(0.01f, 0.01f); private static readonly Vector2 _boundsMaxExpansion = new(1.01f, 1.01f); @@ -197,7 +198,7 @@ namespace Content.Server.Decals private void OnDecalPlacementRequest(RequestDecalPlacementEvent ev, EntitySessionEventArgs eventArgs) { - if (eventArgs.SenderSession is not IPlayerSession session) + if (eventArgs.SenderSession is not { } session) return; // bad @@ -226,7 +227,7 @@ namespace Content.Server.Decals private void OnDecalRemovalRequest(RequestDecalRemovalEvent ev, EntitySessionEventArgs eventArgs) { - if (eventArgs.SenderSession is not IPlayerSession session) + if (eventArgs.SenderSession is not { } session) return; // bad @@ -427,7 +428,7 @@ namespace Content.Server.Decals if (PvsEnabled) { - var players = _playerManager.ServerSessions.Where(x => x.Status == SessionStatus.InGame).ToArray(); + var players = _playerManager.Sessions.Where(x => x.Status == SessionStatus.InGame).ToArray(); var opts = new ParallelOptions { MaxDegreeOfParallelism = _parMan.ParallelProcessCount }; Parallel.ForEach(players, opts, UpdatePlayer); } @@ -435,7 +436,7 @@ namespace Content.Server.Decals _dirtyChunks.Clear(); } - public void UpdatePlayer(IPlayerSession player) + public void UpdatePlayer(ICommonSession player) { var chunksInRange = _chunking.GetChunksForSession(player, ChunkSize, _chunkIndexPool, _chunkViewerPool); var staleChunks = _chunkViewerPool.Get(); @@ -530,7 +531,7 @@ namespace Content.Server.Decals } private void SendChunkUpdates( - IPlayerSession session, + ICommonSession session, Dictionary> updatedChunks, Dictionary> staleChunks) { diff --git a/Content.Server/Disposal/TubeConnectionsCommand.cs b/Content.Server/Disposal/TubeConnectionsCommand.cs index 7895dcbca6..55e6465937 100644 --- a/Content.Server/Disposal/TubeConnectionsCommand.cs +++ b/Content.Server/Disposal/TubeConnectionsCommand.cs @@ -2,7 +2,6 @@ using Content.Server.Administration; using Content.Server.Disposal.Tube; using Content.Server.Disposal.Tube.Components; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Disposal @@ -18,7 +17,7 @@ namespace Content.Server.Disposal public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player?.AttachedEntity == null) { shell.WriteLine(Loc.GetString("shell-only-players-can-run-this-command")); diff --git a/Content.Server/EUI/BaseEui.cs b/Content.Server/EUI/BaseEui.cs index 4a41ad40a5..70cbfc3775 100644 --- a/Content.Server/EUI/BaseEui.cs +++ b/Content.Server/EUI/BaseEui.cs @@ -1,6 +1,6 @@ using Content.Shared.Eui; using Robust.Shared.Network; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.EUI { diff --git a/Content.Server/EUI/EuiManager.cs b/Content.Server/EUI/EuiManager.cs index 4d99719525..fe8e486b68 100644 --- a/Content.Server/EUI/EuiManager.cs +++ b/Content.Server/EUI/EuiManager.cs @@ -2,7 +2,7 @@ using Robust.Server.Player; using Robust.Shared.Enums; using Robust.Shared.Network; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Server.EUI diff --git a/Content.Server/EntityList/SpawnEntityListCommand.cs b/Content.Server/EntityList/SpawnEntityListCommand.cs index 0891bbd12a..027d25dc2c 100644 --- a/Content.Server/EntityList/SpawnEntityListCommand.cs +++ b/Content.Server/EntityList/SpawnEntityListCommand.cs @@ -1,7 +1,6 @@ using Content.Server.Administration; using Content.Shared.Administration; using Content.Shared.EntityList; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Prototypes; @@ -22,7 +21,7 @@ namespace Content.Server.EntityList return; } - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError("You must be a player to run this command."); return; diff --git a/Content.Server/Examine/ExamineSystem.cs b/Content.Server/Examine/ExamineSystem.cs index 98aa806885..3447810896 100644 --- a/Content.Server/Examine/ExamineSystem.cs +++ b/Content.Server/Examine/ExamineSystem.cs @@ -4,7 +4,6 @@ using Content.Shared.Examine; using Content.Shared.Verbs; using JetBrains.Annotations; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Utility; namespace Content.Server.Examine @@ -46,7 +45,7 @@ namespace Content.Server.Examine private void ExamineInfoRequest(ExamineSystemMessages.RequestExamineInfoMessage request, EntitySessionEventArgs eventArgs) { - var player = (IPlayerSession) eventArgs.SenderSession; + var player = eventArgs.SenderSession; var session = eventArgs.SenderSession; var channel = player.ConnectedClient; var entity = GetEntity(request.NetEntity); diff --git a/Content.Server/Fluids/EntitySystems/PuddleDebugDebugOverlaySystem.cs b/Content.Server/Fluids/EntitySystems/PuddleDebugDebugOverlaySystem.cs index 59f0a13695..c17eea684d 100644 --- a/Content.Server/Fluids/EntitySystems/PuddleDebugDebugOverlaySystem.cs +++ b/Content.Server/Fluids/EntitySystems/PuddleDebugDebugOverlaySystem.cs @@ -1,9 +1,9 @@ using System.Numerics; using Content.Shared.Fluids; using Content.Shared.Fluids.Components; -using Robust.Server.Player; using Robust.Shared.Map; using Robust.Shared.Map.Components; +using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.Fluids.EntitySystems; @@ -14,10 +14,10 @@ public sealed class PuddleDebugDebugOverlaySystem : SharedPuddleDebugOverlaySyst [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly PuddleSystem _puddle = default!; - private readonly HashSet _playerObservers = new(); + private readonly HashSet _playerObservers = new(); private List> _grids = new(); - public bool ToggleObserver(IPlayerSession observer) + public bool ToggleObserver(ICommonSession observer) { NextTick ??= _timing.CurTime + Cooldown; @@ -31,7 +31,7 @@ public sealed class PuddleDebugDebugOverlaySystem : SharedPuddleDebugOverlaySyst return true; } - private void RemoveObserver(IPlayerSession observer) + private void RemoveObserver(ICommonSession observer) { if (!_playerObservers.Remove(observer)) { diff --git a/Content.Server/Fluids/ShowFluidsCommand.cs b/Content.Server/Fluids/ShowFluidsCommand.cs index f122eadea7..71ac273a45 100644 --- a/Content.Server/Fluids/ShowFluidsCommand.cs +++ b/Content.Server/Fluids/ShowFluidsCommand.cs @@ -1,7 +1,6 @@ using Content.Server.Administration; using Content.Server.Fluids.EntitySystems; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Fluids; @@ -15,7 +14,7 @@ public sealed class ShowFluidsCommand : IConsoleCommand public string Help => $"Usage: {Command}"; public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("You must be a player to use this command."); diff --git a/Content.Server/GameTicking/Commands/JoinGameCommand.cs b/Content.Server/GameTicking/Commands/JoinGameCommand.cs index 366e6c4e77..3276b91200 100644 --- a/Content.Server/GameTicking/Commands/JoinGameCommand.cs +++ b/Content.Server/GameTicking/Commands/JoinGameCommand.cs @@ -2,7 +2,6 @@ using Content.Server.Station.Systems; using Content.Shared.Administration; using Content.Shared.GameTicking; using Content.Shared.Roles; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Prototypes; @@ -30,7 +29,7 @@ namespace Content.Server.GameTicking.Commands return; } - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { diff --git a/Content.Server/GameTicking/Commands/ObserveCommand.cs b/Content.Server/GameTicking/Commands/ObserveCommand.cs index d608dda9c1..747e54e28b 100644 --- a/Content.Server/GameTicking/Commands/ObserveCommand.cs +++ b/Content.Server/GameTicking/Commands/ObserveCommand.cs @@ -1,6 +1,5 @@ using Content.Shared.Administration; using Content.Shared.GameTicking; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.GameTicking.Commands @@ -14,7 +13,7 @@ namespace Content.Server.GameTicking.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { return; } diff --git a/Content.Server/GameTicking/Commands/RespawnCommand.cs b/Content.Server/GameTicking/Commands/RespawnCommand.cs index 057572297f..4f101d0939 100644 --- a/Content.Server/GameTicking/Commands/RespawnCommand.cs +++ b/Content.Server/GameTicking/Commands/RespawnCommand.cs @@ -14,7 +14,7 @@ namespace Content.Server.GameTicking.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (args.Length > 1) { shell.WriteLine("Must provide <= 1 argument."); diff --git a/Content.Server/GameTicking/Commands/ToggleReadyCommand.cs b/Content.Server/GameTicking/Commands/ToggleReadyCommand.cs index e68c4c5fa7..df418c27ee 100644 --- a/Content.Server/GameTicking/Commands/ToggleReadyCommand.cs +++ b/Content.Server/GameTicking/Commands/ToggleReadyCommand.cs @@ -1,5 +1,4 @@ using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.GameTicking.Commands @@ -13,7 +12,7 @@ namespace Content.Server.GameTicking.Commands public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (args.Length != 1) { shell.WriteError(Loc.GetString("shell-wrong-arguments-number")); diff --git a/Content.Server/GameTicking/GameTicker.GamePreset.cs b/Content.Server/GameTicking/GameTicker.GamePreset.cs index a5e6d7a605..2d7539bd0f 100644 --- a/Content.Server/GameTicking/GameTicker.GamePreset.cs +++ b/Content.Server/GameTicking/GameTicker.GamePreset.cs @@ -11,7 +11,7 @@ using Content.Shared.Ghost; using Content.Shared.Mind; using Content.Shared.Mobs.Components; using JetBrains.Annotations; -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.GameTicking { @@ -29,7 +29,7 @@ namespace Content.Server.GameTicking /// public GamePresetPrototype? CurrentPreset { get; private set; } - private bool StartPreset(IPlayerSession[] origReadyPlayers, bool force) + private bool StartPreset(ICommonSession[] origReadyPlayers, bool force) { var startAttempt = new RoundStartAttemptEvent(origReadyPlayers, force); RaiseLocalEvent(startAttempt); @@ -214,7 +214,7 @@ namespace Content.Server.GameTicking { if (mind.Session != null) // Logging is suppressed to prevent spam from ghost attempts caused by movement attempts { - _chatManager.DispatchServerMessage((IPlayerSession) mind.Session, Loc.GetString("comp-mind-ghosting-prevented"), + _chatManager.DispatchServerMessage(mind.Session, Loc.GetString("comp-mind-ghosting-prevented"), true); } diff --git a/Content.Server/GameTicking/GameTicker.Lobby.cs b/Content.Server/GameTicking/GameTicker.Lobby.cs index b7b6a29a5a..1943a82617 100644 --- a/Content.Server/GameTicking/GameTicker.Lobby.cs +++ b/Content.Server/GameTicking/GameTicker.Lobby.cs @@ -1,10 +1,8 @@ using System.Linq; using Content.Shared.GameTicking; using Content.Server.Station.Components; -using Robust.Server.Player; using Robust.Shared.Network; using Robust.Shared.Player; -using Robust.Shared.Players; using System.Text; namespace Content.Server.GameTicking @@ -79,7 +77,7 @@ namespace Content.Server.GameTicking ("roundId", RoundId), ("playerCount", playerCount), ("readyCount", readyCount), ("mapName", stationNames.ToString()),("gmTitle", gmTitle),("desc", desc)); } - private TickerLobbyStatusEvent GetStatusMsg(IPlayerSession session) + private TickerLobbyStatusEvent GetStatusMsg(ICommonSession session) { _playerGameStatuses.TryGetValue(session.UserId, out var status); return new TickerLobbyStatusEvent(RunLevel != GameRunLevel.PreRoundLobby, LobbySong, LobbyBackground,status == PlayerGameStatus.ReadyToPlay, _roundStartTime, RoundPreloadTime, _roundStartTimeSpan, Paused); @@ -87,7 +85,7 @@ namespace Content.Server.GameTicking private void SendStatusToAll() { - foreach (var player in _playerManager.ServerSessions) + foreach (var player in _playerManager.Sessions) { RaiseNetworkEvent(GetStatusMsg(player), player.ConnectedClient); } @@ -148,7 +146,7 @@ namespace Content.Server.GameTicking } } - public void ToggleReady(IPlayerSession player, bool ready) + public void ToggleReady(ICommonSession player, bool ready) { if (!_playerGameStatuses.ContainsKey(player.UserId)) return; diff --git a/Content.Server/GameTicking/GameTicker.Player.cs b/Content.Server/GameTicking/GameTicker.Player.cs index 3aef1bbe78..dfd2e98499 100644 --- a/Content.Server/GameTicking/GameTicker.Player.cs +++ b/Content.Server/GameTicking/GameTicker.Player.cs @@ -1,12 +1,13 @@ using Content.Server.Database; -using Content.Server.Players; using Content.Shared.GameTicking; using Content.Shared.GameWindow; using Content.Shared.Players; using Content.Shared.Preferences; using JetBrains.Annotations; +using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Enums; +using Robust.Shared.Player; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -17,6 +18,7 @@ namespace Content.Server.GameTicking { [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IServerDbManager _dbManager = default!; + [Dependency] private readonly ActorSystem _actor = default!; private void InitializePlayer() { @@ -49,14 +51,14 @@ namespace Content.Server.GameTicking // Always make sure the client has player data. if (session.Data.ContentDataUncast == null) { - var data = new PlayerData(session.UserId, args.Session.Name); + var data = new ContentPlayerData(session.UserId, args.Session.Name); data.Mind = mindId; session.Data.ContentDataUncast = data; } // Make the player actually join the game. // timer time must be > tick length - Timer.Spawn(0, args.Session.JoinGame); + Timer.Spawn(0, () => _playerManager.JoinGame(args.Session)); var record = await _dbManager.GetPlayerRecordByUserId(args.Session.UserId); var firstConnection = record != null && @@ -100,9 +102,16 @@ namespace Content.Server.GameTicking } else { - // Simply re-attach to existing entity. - session.AttachToEntity(mind.CurrentEntity); - PlayerJoinGame(session); + if (_actor.Attach(mind.CurrentEntity, session)) + { + PlayerJoinGame(session); + } + else + { + Log.Error( + $"Failed to attach player {session} with mind {ToPrettyString(mindId)} to its current entity {ToPrettyString(mind.CurrentEntity)}"); + SpawnObserverWaitDb(); + } } break; @@ -146,12 +155,12 @@ namespace Content.Server.GameTicking } } - private HumanoidCharacterProfile GetPlayerProfile(IPlayerSession p) + private HumanoidCharacterProfile GetPlayerProfile(ICommonSession p) { return (HumanoidCharacterProfile) _prefsManager.GetPreferences(p.UserId).SelectedCharacter; } - public void PlayerJoinGame(IPlayerSession session, bool silent = false) + public void PlayerJoinGame(ICommonSession session, bool silent = false) { if (!silent) _chatManager.DispatchServerMessage(session, Loc.GetString("game-ticker-player-join-game-message")); @@ -162,7 +171,7 @@ namespace Content.Server.GameTicking RaiseNetworkEvent(new TickerJoinGameEvent(), session.ConnectedClient); } - private void PlayerJoinLobby(IPlayerSession session) + private void PlayerJoinLobby(ICommonSession session) { _playerGameStatuses[session.UserId] = LobbyEnabled ? PlayerGameStatus.NotReadyToPlay : PlayerGameStatus.ReadyToPlay; _db.AddRoundPlayers(RoundId, session.UserId); @@ -182,9 +191,9 @@ namespace Content.Server.GameTicking public sealed class PlayerJoinedLobbyEvent : EntityEventArgs { - public readonly IPlayerSession PlayerSession; + public readonly ICommonSession PlayerSession; - public PlayerJoinedLobbyEvent(IPlayerSession playerSession) + public PlayerJoinedLobbyEvent(ICommonSession playerSession) { PlayerSession = playerSession; } diff --git a/Content.Server/GameTicking/GameTicker.RoundFlow.cs b/Content.Server/GameTicking/GameTicker.RoundFlow.cs index a10196a43e..85f833bd1c 100644 --- a/Content.Server/GameTicking/GameTicker.RoundFlow.cs +++ b/Content.Server/GameTicking/GameTicker.RoundFlow.cs @@ -12,7 +12,6 @@ using Content.Shared.Preferences; using JetBrains.Annotations; using Prometheus; using Robust.Server.Maps; -using Robust.Server.Player; using Robust.Shared.Asynchronous; using Robust.Shared.Audio; using Robust.Shared.Map; @@ -205,7 +204,7 @@ namespace Content.Server.GameTicking var startingEvent = new RoundStartingEvent(RoundId); RaiseLocalEvent(startingEvent); - var readyPlayers = new List(); + var readyPlayers = new List(); var readyPlayerProfiles = new Dictionary(); foreach (var (userId, status) in _playerGameStatuses) @@ -344,7 +343,7 @@ namespace Content.Server.GameTicking { connected = true; } - PlayerData? contentPlayerData = null; + ContentPlayerData? contentPlayerData = null; if (userId != null && _playerManager.TryGetPlayerData(userId.Value, out var playerData)) { contentPlayerData = playerData.ContentData(); @@ -493,7 +492,7 @@ namespace Content.Server.GameTicking private void ResettingCleanup() { // Move everybody currently in the server to lobby. - foreach (var player in _playerManager.ServerSessions) + foreach (var player in _playerManager.Sessions) { PlayerJoinLobby(player); } @@ -541,7 +540,7 @@ namespace Content.Server.GameTicking DisallowLateJoin = false; _playerGameStatuses.Clear(); - foreach (var session in _playerManager.ServerSessions) + foreach (var session in _playerManager.Sessions) { _playerGameStatuses[session.UserId] = LobbyEnabled ? PlayerGameStatus.NotReadyToPlay : PlayerGameStatus.ReadyToPlay; } @@ -735,10 +734,10 @@ namespace Content.Server.GameTicking /// public sealed class RoundStartAttemptEvent : CancellableEntityEventArgs { - public IPlayerSession[] Players { get; } + public ICommonSession[] Players { get; } public bool Forced { get; } - public RoundStartAttemptEvent(IPlayerSession[] players, bool forced) + public RoundStartAttemptEvent(ICommonSession[] players, bool forced) { Players = players; Forced = forced; @@ -757,11 +756,11 @@ namespace Content.Server.GameTicking /// If you want to handle a specific player being spawned, remove it from this list and do what you need. /// /// If you spawn a player by yourself from this event, don't forget to call on them. - public List PlayerPool { get; } + public List PlayerPool { get; } public IReadOnlyDictionary Profiles { get; } public bool Forced { get; } - public RulePlayerSpawningEvent(List playerPool, IReadOnlyDictionary profiles, bool forced) + public RulePlayerSpawningEvent(List playerPool, IReadOnlyDictionary profiles, bool forced) { PlayerPool = playerPool; Profiles = profiles; @@ -775,11 +774,11 @@ namespace Content.Server.GameTicking /// public sealed class RulePlayerJobsAssignedEvent { - public IPlayerSession[] Players { get; } + public ICommonSession[] Players { get; } public IReadOnlyDictionary Profiles { get; } public bool Forced { get; } - public RulePlayerJobsAssignedEvent(IPlayerSession[] players, IReadOnlyDictionary profiles, bool forced) + public RulePlayerJobsAssignedEvent(ICommonSession[] players, IReadOnlyDictionary profiles, bool forced) { Players = players; Profiles = profiles; diff --git a/Content.Server/GameTicking/GameTicker.Spawning.cs b/Content.Server/GameTicking/GameTicker.Spawning.cs index 0c59f93bb0..c2bf523657 100644 --- a/Content.Server/GameTicking/GameTicker.Spawning.cs +++ b/Content.Server/GameTicking/GameTicker.Spawning.cs @@ -3,20 +3,20 @@ using System.Linq; using System.Numerics; using Content.Server.Administration.Managers; using Content.Server.Ghost; -using Content.Server.Players; using Content.Server.Spawners.Components; using Content.Server.Speech.Components; using Content.Server.Station.Components; using Content.Shared.CCVar; using Content.Shared.Database; +using Content.Shared.Players; using Content.Shared.Preferences; using Content.Shared.Roles; using Content.Shared.Roles.Jobs; using JetBrains.Annotations; -using Robust.Server.Player; using Robust.Shared.Map; using Robust.Shared.Map.Components; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Utility; @@ -29,7 +29,7 @@ namespace Content.Server.GameTicking [Dependency] private readonly SharedJobSystem _jobs = default!; [ValidatePrototypeId] - private const string ObserverPrototypeName = "MobObserver"; + public const string ObserverPrototypeName = "MobObserver"; /// /// How many players have joined the round through normal methods. @@ -52,7 +52,7 @@ namespace Content.Server.GameTicking return spawnableStations; } - private void SpawnPlayers(List readyPlayers, Dictionary profiles, bool force) + private void SpawnPlayers(List readyPlayers, Dictionary profiles, bool force) { // Allow game rules to spawn players by themselves if needed. (For example, nuke ops or wizard) RaiseLocalEvent(new RulePlayerSpawningEvent(readyPlayers, profiles, force)); @@ -116,7 +116,7 @@ namespace Content.Server.GameTicking RaiseLocalEvent(new RulePlayerJobsAssignedEvent(assignedJobs.Keys.Select(x => _playerManager.GetSessionByUserId(x)).ToArray(), profiles, force)); } - private void SpawnPlayer(IPlayerSession player, EntityUid station, string? jobId = null, bool lateJoin = true, bool silent = false) + private void SpawnPlayer(ICommonSession player, EntityUid station, string? jobId = null, bool lateJoin = true, bool silent = false) { var character = GetPlayerProfile(player); @@ -129,7 +129,7 @@ namespace Content.Server.GameTicking SpawnPlayer(player, character, station, jobId, lateJoin, silent); } - private void SpawnPlayer(IPlayerSession player, HumanoidCharacterProfile character, EntityUid station, string? jobId = null, bool lateJoin = true, bool silent = false) + private void SpawnPlayer(ICommonSession player, HumanoidCharacterProfile character, EntityUid station, string? jobId = null, bool lateJoin = true, bool silent = false) { // Can't spawn players with a dummy ticker! if (DummyTicker) @@ -271,7 +271,7 @@ namespace Content.Server.GameTicking RaiseLocalEvent(mob, aev, true); } - public void Respawn(IPlayerSession player) + public void Respawn(ICommonSession player) { _mind.WipeMind(player); _adminLogger.Add(LogType.Respawn, LogImpact.Medium, $"Player {player} was respawned."); @@ -289,7 +289,7 @@ namespace Content.Server.GameTicking /// The station they're spawning on /// An optional job for them to spawn as /// Whether or not the player should be greeted upon joining - public void MakeJoinGame(IPlayerSession player, EntityUid station, string? jobId = null, bool silent = false) + public void MakeJoinGame(ICommonSession player, EntityUid station, string? jobId = null, bool silent = false) { if (!_playerGameStatuses.ContainsKey(player.UserId)) return; @@ -303,7 +303,7 @@ namespace Content.Server.GameTicking /// /// Causes the given player to join the current game as observer ghost. See also /// - public void JoinAsObserver(IPlayerSession player) + public void JoinAsObserver(ICommonSession player) { // Can't spawn players with a dummy ticker! if (DummyTicker) @@ -317,7 +317,7 @@ namespace Content.Server.GameTicking /// Spawns an observer ghost and attaches the given player to it. If the player does not yet have a mind, the /// player is given a new mind with the observer role. Otherwise, the current mind is transferred to the ghost. /// - public void SpawnObserver(IPlayerSession player) + public void SpawnObserver(ICommonSession player) { if (DummyTicker) return; @@ -430,13 +430,13 @@ namespace Content.Server.GameTicking [PublicAPI] public sealed class PlayerBeforeSpawnEvent : HandledEntityEventArgs { - public IPlayerSession Player { get; } + public ICommonSession Player { get; } public HumanoidCharacterProfile Profile { get; } public string? JobId { get; } public bool LateJoin { get; } public EntityUid Station { get; } - public PlayerBeforeSpawnEvent(IPlayerSession player, HumanoidCharacterProfile profile, string? jobId, bool lateJoin, EntityUid station) + public PlayerBeforeSpawnEvent(ICommonSession player, HumanoidCharacterProfile profile, string? jobId, bool lateJoin, EntityUid station) { Player = player; Profile = profile; @@ -455,7 +455,7 @@ namespace Content.Server.GameTicking public sealed class PlayerSpawnCompleteEvent : EntityEventArgs { public EntityUid Mob { get; } - public IPlayerSession Player { get; } + public ICommonSession Player { get; } public string? JobId { get; } public bool LateJoin { get; } public EntityUid Station { get; } @@ -464,7 +464,7 @@ namespace Content.Server.GameTicking // Ex. If this is the 27th person to join, this will be 27. public int JoinOrder { get; } - public PlayerSpawnCompleteEvent(EntityUid mob, IPlayerSession player, string? jobId, bool lateJoin, int joinOrder, EntityUid station, HumanoidCharacterProfile profile) + public PlayerSpawnCompleteEvent(EntityUid mob, ICommonSession player, string? jobId, bool lateJoin, int joinOrder, EntityUid station, HumanoidCharacterProfile profile) { Mob = mob; Player = player; diff --git a/Content.Server/GameTicking/Rules/Components/TraitorRuleComponent.cs b/Content.Server/GameTicking/Rules/Components/TraitorRuleComponent.cs index 883abef52f..7af87179d6 100644 --- a/Content.Server/GameTicking/Rules/Components/TraitorRuleComponent.cs +++ b/Content.Server/GameTicking/Rules/Components/TraitorRuleComponent.cs @@ -1,7 +1,7 @@ using Content.Shared.Preferences; using Content.Shared.Roles; -using Robust.Server.Player; using Robust.Shared.Audio; +using Robust.Shared.Player; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Server.GameTicking.Rules.Components; @@ -26,7 +26,7 @@ public sealed partial class TraitorRuleComponent : Component public SelectionState SelectionStatus = SelectionState.WaitingForSpawn; public TimeSpan AnnounceAt = TimeSpan.Zero; - public Dictionary StartCandidates = new(); + public Dictionary StartCandidates = new(); /// /// Path to antagonist alert sound. diff --git a/Content.Server/GameTicking/Rules/InactivityTimeRestartRuleSystem.cs b/Content.Server/GameTicking/Rules/InactivityTimeRestartRuleSystem.cs index c2e91ba4a5..b775b7af56 100644 --- a/Content.Server/GameTicking/Rules/InactivityTimeRestartRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/InactivityTimeRestartRuleSystem.cs @@ -2,6 +2,7 @@ using System.Threading; using Content.Server.Chat.Managers; using Content.Server.GameTicking.Rules.Components; using Robust.Server.Player; +using Robust.Shared.Player; using Timer = Robust.Shared.Timing.Timer; namespace Content.Server.GameTicking.Rules; diff --git a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs index 13d4ed71c8..4d3eee81e2 100644 --- a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs @@ -602,11 +602,11 @@ public sealed class NukeopsRuleSystem : GameRuleSystem var maxOperatives = nukeops.MaxOps; // Dear lord what is happening HERE. - var everyone = new List(ev.PlayerPool); - var prefList = new List(); - var medPrefList = new List(); - var cmdrPrefList = new List(); - var operatives = new List(); + var everyone = new List(ev.PlayerPool); + var prefList = new List(); + var medPrefList = new List(); + var cmdrPrefList = new List(); + var operatives = new List(); // The LINQ expression ReSharper keeps suggesting is completely unintelligible so I'm disabling it // ReSharper disable once ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator @@ -637,7 +637,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem for (var i = 0; i < numNukies; i++) { // TODO: Please fix this if you touch it. - IPlayerSession nukeOp; + ICommonSession nukeOp; // Only one commander, so we do it at the start if (i == 0) { @@ -908,7 +908,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem _npcFaction.AddFaction(mob, "Syndicate"); } - private void SpawnOperatives(int spawnCount, List sessions, bool addSpawnPoints, NukeopsRuleComponent component) + private void SpawnOperatives(int spawnCount, List sessions, bool addSpawnPoints, NukeopsRuleComponent component) { if (component.NukieOutpost == null) return; @@ -987,10 +987,10 @@ public sealed class NukeopsRuleSystem : GameRuleSystem var playersPerOperative = component.PlayersPerOperative; var maxOperatives = component.MaxOps; - var playerPool = _playerManager.ServerSessions.ToList(); + var playerPool = _playerManager.Sessions.ToList(); var numNukies = MathHelper.Clamp(playerPool.Count / playersPerOperative, 1, maxOperatives); - var operatives = new List(); + var operatives = new List(); SpawnOperatives(numNukies, operatives, true, component); } diff --git a/Content.Server/GameTicking/Rules/PiratesRuleSystem.cs b/Content.Server/GameTicking/Rules/PiratesRuleSystem.cs index b223161c10..0785d81d09 100644 --- a/Content.Server/GameTicking/Rules/PiratesRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/PiratesRuleSystem.cs @@ -15,10 +15,10 @@ using Content.Shared.Preferences; using Content.Shared.Roles; using Robust.Server.GameObjects; using Robust.Server.Maps; -using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Map; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Utility; @@ -141,7 +141,7 @@ public sealed class PiratesRuleSystem : GameRuleSystem (int) Math.Min( Math.Floor((double) ev.PlayerPool.Count / _cfg.GetCVar(CCVars.PiratesPlayersPerOp)), _cfg.GetCVar(CCVars.PiratesMaxOps))); - var ops = new IPlayerSession[numOps]; + var ops = new ICommonSession[numOps]; for (var i = 0; i < numOps; i++) { ops[i] = _random.PickAndTake(ev.PlayerPool); diff --git a/Content.Server/GameTicking/Rules/RespawnRuleSystem.cs b/Content.Server/GameTicking/Rules/RespawnRuleSystem.cs index a286808623..738883fff3 100644 --- a/Content.Server/GameTicking/Rules/RespawnRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/RespawnRuleSystem.cs @@ -6,6 +6,7 @@ using Content.Shared.Chat; using Content.Shared.Interaction.Events; using Content.Shared.Mind; using Content.Shared.Mobs; +using Content.Shared.Players; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Network; diff --git a/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs b/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs index 01317dbfc1..ef949d09fc 100644 --- a/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs @@ -17,9 +17,8 @@ using Content.Shared.PDA; using Content.Shared.Preferences; using Content.Shared.Roles; using Content.Shared.Roles.Jobs; -using Robust.Server.Player; using Robust.Shared.Configuration; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -151,9 +150,9 @@ public sealed class TraitorRuleSystem : GameRuleSystem } } - private List FindPotentialTraitors(in Dictionary candidates, TraitorRuleComponent component) + private List FindPotentialTraitors(in Dictionary candidates, TraitorRuleComponent component) { - var list = new List(); + var list = new List(); var pendingQuery = GetEntityQuery(); foreach (var player in candidates.Keys) @@ -171,7 +170,7 @@ public sealed class TraitorRuleSystem : GameRuleSystem list.Add(player); } - var prefList = new List(); + var prefList = new List(); foreach (var player in list) { @@ -189,9 +188,9 @@ public sealed class TraitorRuleSystem : GameRuleSystem return prefList; } - private List PickTraitors(int traitorCount, List prefList) + private List PickTraitors(int traitorCount, List prefList) { - var results = new List(traitorCount); + var results = new List(traitorCount); if (prefList.Count == 0) { Log.Info("Insufficient ready players to fill up with traitors, stopping the selection."); diff --git a/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs b/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs index 82ae4b8fa6..a4febc385c 100644 --- a/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs @@ -23,7 +23,7 @@ using Content.Shared.Zombies; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Configuration; -using Robust.Shared.Prototypes; +using Robust.Shared.Player; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -264,9 +264,9 @@ public sealed class ZombieRuleSystem : GameRuleSystem return; component.InfectedChosen = true; - var allPlayers = _playerManager.ServerSessions.ToList(); - var playerList = new List(); - var prefList = new List(); + var allPlayers = _playerManager.Sessions.ToList(); + var playerList = new List(); + var prefList = new List(); foreach (var player in allPlayers) { if (player.AttachedEntity == null || !HasComp(player.AttachedEntity) || HasComp(player.AttachedEntity)) @@ -288,7 +288,7 @@ public sealed class ZombieRuleSystem : GameRuleSystem var totalInfected = 0; while (totalInfected < numInfected) { - IPlayerSession zombie; + ICommonSession zombie; if (prefList.Count == 0) { if (playerList.Count == 0) diff --git a/Content.Server/Ghost/Ghost.cs b/Content.Server/Ghost/Ghost.cs index d04b1197af..1453bf3faa 100644 --- a/Content.Server/Ghost/Ghost.cs +++ b/Content.Server/Ghost/Ghost.cs @@ -1,7 +1,6 @@ using Content.Server.GameTicking; using Content.Shared.Administration; using Content.Shared.Mind; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Ghost @@ -17,7 +16,7 @@ namespace Content.Server.Ghost public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("You have no session, you can't ghost."); diff --git a/Content.Server/Ghost/Roles/Components/TakeGhostRoleEvent.cs b/Content.Server/Ghost/Roles/Components/TakeGhostRoleEvent.cs index c97e3be9dc..16d46871fe 100644 --- a/Content.Server/Ghost/Roles/Components/TakeGhostRoleEvent.cs +++ b/Content.Server/Ghost/Roles/Components/TakeGhostRoleEvent.cs @@ -1,4 +1,4 @@ -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.Ghost.Roles.Components; diff --git a/Content.Server/Ghost/Roles/GhostRoleSystem.cs b/Content.Server/Ghost/Roles/GhostRoleSystem.cs index 5a4cc176f2..f372cb4f62 100644 --- a/Content.Server/Ghost/Roles/GhostRoleSystem.cs +++ b/Content.Server/Ghost/Roles/GhostRoleSystem.cs @@ -4,7 +4,6 @@ using Content.Server.Ghost.Roles.Components; using Content.Server.Ghost.Roles.Events; using Content.Server.Ghost.Roles.UI; using Content.Server.Mind.Commands; -using Content.Server.Players; using Content.Shared.Administration; using Content.Shared.Database; using Content.Shared.Follower; @@ -14,13 +13,14 @@ using Content.Shared.Ghost.Roles; using Content.Shared.Mind; using Content.Shared.Mind.Components; using Content.Shared.Mobs; +using Content.Shared.Players; using Content.Shared.Roles; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Random; using Robust.Shared.Utility; @@ -97,7 +97,7 @@ namespace Content.Server.Ghost.Roles return unchecked(_nextRoleIdentifier++); } - public void OpenEui(IPlayerSession session) + public void OpenEui(ICommonSession session) { if (session.AttachedEntity is not {Valid: true} attached || !EntityManager.HasComponent(attached)) @@ -111,7 +111,7 @@ namespace Content.Server.Ghost.Roles eui.StateDirty(); } - public void OpenMakeGhostRoleEui(IPlayerSession session, EntityUid uid) + public void OpenMakeGhostRoleEui(ICommonSession session, EntityUid uid) { if (session.AttachedEntity == null) return; @@ -420,7 +420,7 @@ namespace Content.Server.Ghost.Roles public void Execute(IConsoleShell shell, string argStr, string[] args) { if(shell.Player != null) - EntitySystem.Get().OpenEui((IPlayerSession)shell.Player); + EntitySystem.Get().OpenEui(shell.Player); else shell.WriteLine("You can only open the ghost roles UI on a client."); } diff --git a/Content.Server/Gravity/GravityGeneratorSystem.cs b/Content.Server/Gravity/GravityGeneratorSystem.cs index 48002fb823..0bd159f61a 100644 --- a/Content.Server/Gravity/GravityGeneratorSystem.cs +++ b/Content.Server/Gravity/GravityGeneratorSystem.cs @@ -6,7 +6,7 @@ using Content.Shared.Database; using Content.Shared.Gravity; using Content.Shared.Interaction; using Robust.Server.GameObjects; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.Gravity { @@ -139,7 +139,7 @@ namespace Content.Server.Gravity return; if (session is { AttachedEntity: { } }) - _adminLogger.Add(LogType.Action, on ? LogImpact.Medium : LogImpact.High, $"{ToPrettyString(session.AttachedEntity.Value):player} set ${ToPrettyString(uid):target} to {(on ? "on" : "off")}"); + _adminLogger.Add(LogType.Action, on ? LogImpact.Medium : LogImpact.High, $"{session:player} set ${ToPrettyString(uid):target} to {(on ? "on" : "off")}"); component.SwitchedOn = on; UpdatePowerState(component, powerReceiver); diff --git a/Content.Server/Hands/Systems/HandsSystem.cs b/Content.Server/Hands/Systems/HandsSystem.cs index b5b01ac001..e3e6699537 100644 --- a/Content.Server/Hands/Systems/HandsSystem.cs +++ b/Content.Server/Hands/Systems/HandsSystem.cs @@ -18,12 +18,11 @@ using Content.Shared.Pulling.Components; using Content.Shared.Stacks; using Content.Shared.Storage; using Content.Shared.Throwing; -using Robust.Server.Player; using Robust.Shared.Containers; using Robust.Shared.GameStates; using Robust.Shared.Input.Binding; using Robust.Shared.Map; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Server.Hands.Systems @@ -159,9 +158,9 @@ namespace Content.Server.Hands.Systems #endregion #region interactions - private bool HandleThrowItem(ICommonSession? session, EntityCoordinates coordinates, EntityUid entity) + private bool HandleThrowItem(ICommonSession? playerSession, EntityCoordinates coordinates, EntityUid entity) { - if (session is not IPlayerSession playerSession) + if (playerSession == null) return false; if (playerSession.AttachedEntity is not {Valid: true} player || @@ -220,7 +219,7 @@ namespace Content.Server.Hands.Systems // TODO: move to storage or inventory private void HandleSmartEquip(ICommonSession? session, string equipmentSlot) { - if (session is not IPlayerSession playerSession) + if (session is not { } playerSession) return; if (playerSession.AttachedEntity is not {Valid: true} plyEnt || !Exists(plyEnt)) diff --git a/Content.Server/Humanoid/Systems/HumanoidAppearanceSystem.Modifier.cs b/Content.Server/Humanoid/Systems/HumanoidAppearanceSystem.Modifier.cs index 7c0bb7383b..b47fe71714 100644 --- a/Content.Server/Humanoid/Systems/HumanoidAppearanceSystem.Modifier.cs +++ b/Content.Server/Humanoid/Systems/HumanoidAppearanceSystem.Modifier.cs @@ -3,7 +3,6 @@ using Content.Shared.Administration; using Content.Shared.Humanoid; using Content.Shared.Verbs; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Utility; namespace Content.Server.Humanoid; @@ -48,7 +47,7 @@ public sealed partial class HumanoidAppearanceSystem private void OnBaseLayersSet(EntityUid uid, HumanoidAppearanceComponent component, HumanoidMarkingModifierBaseLayersSetMessage message) { - if (message.Session is not IPlayerSession player + if (message.Session is not { } player || !_adminManager.HasAdminFlag(player, AdminFlags.Fun)) { return; @@ -81,7 +80,7 @@ public sealed partial class HumanoidAppearanceSystem private void OnMarkingsSet(EntityUid uid, HumanoidAppearanceComponent component, HumanoidMarkingModifierMarkingSetMessage message) { - if (message.Session is not IPlayerSession player + if (message.Session is not { } player || !_adminManager.HasAdminFlag(player, AdminFlags.Fun)) { return; diff --git a/Content.Server/Instruments/InstrumentComponent.cs b/Content.Server/Instruments/InstrumentComponent.cs index 810d265314..4302ab6791 100644 --- a/Content.Server/Instruments/InstrumentComponent.cs +++ b/Content.Server/Instruments/InstrumentComponent.cs @@ -1,7 +1,7 @@ using Content.Server.UserInterface; using Content.Shared.Instruments; using Robust.Server.GameObjects; -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Instruments; @@ -17,7 +17,7 @@ public sealed partial class InstrumentComponent : SharedInstrumentComponent [ViewVariables] public uint LastSequencerTick = 0; // TODO Instruments: Make this ECS - public IPlayerSession? InstrumentPlayer => + public ICommonSession? InstrumentPlayer => _entMan.GetComponentOrNull(Owner)?.CurrentSingleUser ?? _entMan.GetComponentOrNull(Owner)?.PlayerSession; } diff --git a/Content.Server/Instruments/InstrumentSystem.cs b/Content.Server/Instruments/InstrumentSystem.cs index ec23382105..6f8369182c 100644 --- a/Content.Server/Instruments/InstrumentSystem.cs +++ b/Content.Server/Instruments/InstrumentSystem.cs @@ -9,12 +9,12 @@ using Content.Shared.Physics; using Content.Shared.Popups; using JetBrains.Annotations; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Audio.Midi; using Robust.Shared.Collections; using Robust.Shared.Configuration; using Robust.Shared.Console; using Robust.Shared.GameStates; +using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.Instruments; @@ -385,7 +385,7 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem var nearby = GetBands(entity); _bui.TrySendUiMessage(entity, request.UiKey, new InstrumentBandResponseBuiMessage(nearby), - (IPlayerSession)request.Session); + request.Session); } _bandRequestQueue.Clear(); @@ -447,7 +447,7 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem } } - public void ToggleInstrumentUi(EntityUid uid, IPlayerSession session, InstrumentComponent? component = null) + public void ToggleInstrumentUi(EntityUid uid, ICommonSession session, InstrumentComponent? component = null) { if (!Resolve(uid, ref component)) return; diff --git a/Content.Server/Interaction/InteractionSystem.cs b/Content.Server/Interaction/InteractionSystem.cs index a612b73840..9237a1f7dd 100644 --- a/Content.Server/Interaction/InteractionSystem.cs +++ b/Content.Server/Interaction/InteractionSystem.cs @@ -13,7 +13,6 @@ using Robust.Server.GameObjects; using Robust.Shared.Containers; using Robust.Shared.Input.Binding; using Robust.Shared.Map; -using Robust.Shared.Players; using Robust.Shared.Random; namespace Content.Server.Interaction diff --git a/Content.Server/Interaction/TilePryCommand.cs b/Content.Server/Interaction/TilePryCommand.cs index 4fe3599df9..fa75b6d9e4 100644 --- a/Content.Server/Interaction/TilePryCommand.cs +++ b/Content.Server/Interaction/TilePryCommand.cs @@ -1,10 +1,7 @@ using System.Numerics; using Content.Server.Administration; -using Content.Server.Tools.Components; using Content.Shared.Administration; using Content.Shared.Maps; -using Content.Shared.Tools.Components; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; @@ -24,7 +21,7 @@ namespace Content.Server.Interaction public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player?.AttachedEntity is not {} attached) { return; diff --git a/Content.Server/MagicMirror/MagicMirrorSystem.cs b/Content.Server/MagicMirror/MagicMirrorSystem.cs index 90a0b19b7d..a599a2c868 100644 --- a/Content.Server/MagicMirror/MagicMirrorSystem.cs +++ b/Content.Server/MagicMirror/MagicMirrorSystem.cs @@ -5,8 +5,7 @@ using Content.Shared.Humanoid; using Content.Shared.Humanoid.Markings; using Content.Shared.MagicMirror; using Robust.Server.GameObjects; -using Robust.Server.Player; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.MagicMirror; @@ -147,7 +146,7 @@ public sealed class MagicMirrorSystem : EntitySystem private void UpdateInterface(EntityUid uid, EntityUid playerUid, ICommonSession session, HumanoidAppearanceComponent? humanoid = null) { - if (!Resolve(playerUid, ref humanoid) || session is not IPlayerSession player) + if (!Resolve(playerUid, ref humanoid) || session is not { } player) { return; } diff --git a/Content.Server/Mapping/MappingCommand.cs b/Content.Server/Mapping/MappingCommand.cs index e4a4cd8942..d72a5c4178 100644 --- a/Content.Server/Mapping/MappingCommand.cs +++ b/Content.Server/Mapping/MappingCommand.cs @@ -40,7 +40,7 @@ namespace Content.Server.Mapping public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError(Loc.GetString("cmd-savemap-server")); return; diff --git a/Content.Server/Maps/GridDraggingSystem.cs b/Content.Server/Maps/GridDraggingSystem.cs index 90770af1ad..7d7b61955b 100644 --- a/Content.Server/Maps/GridDraggingSystem.cs +++ b/Content.Server/Maps/GridDraggingSystem.cs @@ -1,10 +1,9 @@ using Content.Shared.Maps; using Robust.Server.Console; -using Robust.Server.Player; -using Robust.Shared.Players; using Robust.Shared.Utility; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; +using Robust.Shared.Player; namespace Content.Server.Maps; @@ -27,7 +26,7 @@ public sealed class GridDraggingSystem : SharedGridDraggingSystem public void Toggle(ICommonSession session) { - if (session is not IPlayerSession pSession) + if (session is not { } pSession) return; DebugTools.Assert(_admin.CanCommand(pSession, CommandName)); @@ -52,7 +51,7 @@ public sealed class GridDraggingSystem : SharedGridDraggingSystem { var grid = GetEntity(ev.Grid); - if (args.SenderSession is not IPlayerSession playerSession || + if (args.SenderSession is not { } playerSession || !_admin.CanCommand(playerSession, CommandName) || !Exists(grid) || Deleted(grid)) @@ -69,7 +68,7 @@ public sealed class GridDraggingSystem : SharedGridDraggingSystem { var grid = GetEntity(msg.Grid); - if (args.SenderSession is not IPlayerSession playerSession || + if (args.SenderSession is not { } playerSession || !_admin.CanCommand(playerSession, CommandName) || !Exists(grid) || Deleted(grid)) diff --git a/Content.Server/Medical/DefibrillatorSystem.cs b/Content.Server/Medical/DefibrillatorSystem.cs index 4ffa9f558d..d041f8ee9d 100644 --- a/Content.Server/Medical/DefibrillatorSystem.cs +++ b/Content.Server/Medical/DefibrillatorSystem.cs @@ -18,7 +18,7 @@ using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; using Content.Shared.Timing; using Content.Shared.Toggleable; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.Medical; diff --git a/Content.Server/Mind/MindSystem.cs b/Content.Server/Mind/MindSystem.cs index d2721db7b6..f23e9b6407 100644 --- a/Content.Server/Mind/MindSystem.cs +++ b/Content.Server/Mind/MindSystem.cs @@ -11,7 +11,9 @@ using Robust.Server.GameObjects; using Robust.Server.GameStates; using Robust.Server.Player; using Robust.Shared.Map; +using Robust.Shared.Map.Components; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -71,51 +73,45 @@ public sealed class MindSystem : SharedMindSystem } TransferTo(mindId, null, createGhost: false, mind: mind); + DebugTools.AssertNull(mind.OwnedEntity); - // Let's not create ghosts if not in the middle of the round. - if (_gameTicker.RunLevel == GameRunLevel.PreRoundLobby) + if (!component.GhostOnShutdown || mind.Session == null || _gameTicker.RunLevel == GameRunLevel.PreRoundLobby) return; - // I just love convoluted entity shutdown logic that results in more entities being spawned. - if (component.GhostOnShutdown && mind.Session != null) + var xform = Transform(uid); + var gridId = xform.GridUid; + var spawnPosition = Transform(uid).Coordinates; + + // Use a regular timer here because the entity has probably been deleted. + Timer.Spawn(0, () => { - var xform = Transform(uid); - var gridId = xform.GridUid; - var spawnPosition = Transform(uid).Coordinates; + // Make extra sure the round didn't end between spawning the timer and it being executed. + if (_gameTicker.RunLevel == GameRunLevel.PreRoundLobby) + return; - // Use a regular timer here because the entity has probably been deleted. - Timer.Spawn(0, () => + // Async this so that we don't throw if the grid we're on is being deleted. + if (!HasComp(gridId)) + spawnPosition = _gameTicker.GetObserverSpawnPoint(); + + // TODO refactor observer spawning. + // please. + if (!spawnPosition.IsValid(EntityManager)) { - // Make extra sure the round didn't end between spawning the timer and it being executed. - if (_gameTicker.RunLevel == GameRunLevel.PreRoundLobby) - return; + // This should be an error, if it didn't cause tests to start erroring when they delete a player. + Log.Warning($"Entity \"{ToPrettyString(uid)}\" for {mind.CharacterName} was deleted, and no applicable spawn location is available."); + TransferTo(mindId, null, createGhost: false, mind: mind); + return; + } - // Async this so that we don't throw if the grid we're on is being deleted. - if (!_maps.GridExists(gridId)) - spawnPosition = _gameTicker.GetObserverSpawnPoint(); + var ghost = Spawn(GameTicker.ObserverPrototypeName, spawnPosition); + var ghostComponent = Comp(ghost); + _ghosts.SetCanReturnToBody(ghostComponent, false); - // TODO refactor observer spawning. - // please. - if (!spawnPosition.IsValid(EntityManager)) - { - // This should be an error, if it didn't cause tests to start erroring when they delete a player. - Log.Warning($"Entity \"{ToPrettyString(uid)}\" for {mind.CharacterName} was deleted, and no applicable spawn location is available."); - TransferTo(mindId, null, createGhost: false, mind: mind); - return; - } - - var ghost = Spawn("MobObserver", spawnPosition); - var ghostComponent = Comp(ghost); - _ghosts.SetCanReturnToBody(ghostComponent, false); - - // Log these to make sure they're not causing the GameTicker round restart bugs... - Log.Debug($"Entity \"{ToPrettyString(uid)}\" for {mind.CharacterName} was deleted, spawned \"{ToPrettyString(ghost)}\"."); - - var val = mind.CharacterName ?? string.Empty; - _metaData.SetEntityName(ghost, val); - TransferTo(mindId, ghost, mind: mind); - }); - } + // Log these to make sure they're not causing the GameTicker round restart bugs... + Log.Debug($"Entity \"{ToPrettyString(uid)}\" for {mind.CharacterName} was deleted, spawned \"{ToPrettyString(ghost)}\"."); + _metaData.SetEntityName(ghost, mind.CharacterName ?? string.Empty); + TransferTo(mindId, ghost, mind: mind); + }); } public override bool TryGetMind(NetUserId user, [NotNullWhen(true)] out EntityUid? mindId, [NotNullWhen(true)] out MindComponent? mind) @@ -130,18 +126,18 @@ public sealed class MindSystem : SharedMindSystem return false; } - public bool TryGetSession(EntityUid? mindId, [NotNullWhen(true)] out IPlayerSession? session) + public bool TryGetSession(EntityUid? mindId, [NotNullWhen(true)] out ICommonSession? session) { session = null; - return TryComp(mindId, out MindComponent? mind) && (session = (IPlayerSession?) mind.Session) != null; + return TryComp(mindId, out MindComponent? mind) && (session = mind.Session) != null; } - public IPlayerSession? GetSession(MindComponent mind) + public ICommonSession? GetSession(MindComponent mind) { - return (IPlayerSession?) mind.Session; + return mind.Session; } - public bool TryGetSession(MindComponent mind, [NotNullWhen(true)] out IPlayerSession? session) + public bool TryGetSession(MindComponent mind, [NotNullWhen(true)] out ICommonSession? session) { return (session = GetSession(mind)) != null; } @@ -179,7 +175,9 @@ public sealed class MindSystem : SharedMindSystem return; } - GetSession(mind)?.AttachToEntity(entity); + if (GetSession(mind) is { } session) + _actor.Attach(entity, session); + mind.VisitingEntity = entity; // EnsureComp instead of AddComp to deal with deferred deletions. @@ -204,7 +202,8 @@ public sealed class MindSystem : SharedMindSystem return; var owned = mind.OwnedEntity; - GetSession(mind)?.AttachToEntity(owned); + if (GetSession(mind) is { } session) + _actor.Attach(owned, session); if (owned.HasValue) { @@ -294,6 +293,7 @@ public sealed class MindSystem : SharedMindSystem if (session != null && !alreadyAttached && mind.VisitingEntity == null) { _actor.Attach(entity, session, true); + DebugTools.Assert(session.AttachedEntity == entity, $"Failed to attach entity."); Log.Info($"Session {session.Name} transferred to entity {entity}."); } diff --git a/Content.Server/Mind/Toolshed/MindCommand.cs b/Content.Server/Mind/Toolshed/MindCommand.cs index b53f9a6a9c..917e6fb7f1 100644 --- a/Content.Server/Mind/Toolshed/MindCommand.cs +++ b/Content.Server/Mind/Toolshed/MindCommand.cs @@ -1,5 +1,5 @@ using Content.Shared.Mind; -using Robust.Server.Player; +using Robust.Shared.Player; using Robust.Shared.Toolshed; using Robust.Shared.Toolshed.Errors; using Robust.Shared.Toolshed.Syntax; @@ -15,7 +15,7 @@ public sealed class MindCommand : ToolshedCommand private SharedMindSystem? _mind; [CommandImplementation("get")] - public MindComponent? Get([PipedArgument] IPlayerSession session) + public MindComponent? Get([PipedArgument] ICommonSession session) { _mind ??= GetSys(); return _mind.TryGetMind(session, out _, out var mind) ? mind : null; @@ -32,7 +32,7 @@ public sealed class MindCommand : ToolshedCommand public EntityUid Control( [CommandInvocationContext] IInvocationContext ctx, [PipedArgument] EntityUid target, - [CommandArgument] ValueRef playerRef) + [CommandArgument] ValueRef playerRef) { _mind ??= GetSys(); diff --git a/Content.Server/Motd/MOTDCommand.cs b/Content.Server/Motd/MOTDCommand.cs index a1aa4d2df5..9e59589b95 100644 --- a/Content.Server/Motd/MOTDCommand.cs +++ b/Content.Server/Motd/MOTDCommand.cs @@ -1,6 +1,5 @@ using Content.Server.Administration.Managers; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Motd; @@ -14,10 +13,10 @@ internal sealed class MOTDCommand : LocalizedCommands [Dependency] private readonly IAdminManager _adminManager = default!; public override string Command => "motd"; - + public override void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = (IPlayerSession?)shell.Player; + var player = shell.Player; if (args.Length < 1 || (player != null && _adminManager is AdminManager aMan && !aMan.CanCommand(player, "set-motd"))) shell.ConsoleHost.ExecuteCommand(shell.Player, "get-motd"); else @@ -26,7 +25,7 @@ internal sealed class MOTDCommand : LocalizedCommands public override CompletionResult GetCompletion(IConsoleShell shell, string[] args) { - var player = (IPlayerSession?)shell.Player; + var player = shell.Player; if (player != null && _adminManager is AdminManager aMan && !aMan.CanCommand(player, "set-motd")) return CompletionResult.Empty; if (args.Length == 1) diff --git a/Content.Server/Motd/MOTDSystem.cs b/Content.Server/Motd/MOTDSystem.cs index e749fe48f3..39d780f108 100644 --- a/Content.Server/Motd/MOTDSystem.cs +++ b/Content.Server/Motd/MOTDSystem.cs @@ -2,9 +2,9 @@ using Content.Server.Chat.Managers; using Content.Server.GameTicking; using Content.Shared.CCVar; using Content.Shared.Chat; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Configuration; +using Robust.Shared.Player; namespace Content.Server.Motd; @@ -41,7 +41,7 @@ public sealed class MOTDSystem : EntitySystem { if (string.IsNullOrEmpty(_messageOfTheDay)) return; - + var wrappedMessage = Loc.GetString("motd-wrap-message", ("motd", _messageOfTheDay)); _chatManager.ChatMessageToAll(ChatChannel.Server, _messageOfTheDay, wrappedMessage, source: EntityUid.Invalid, hideChat: false, recordReplay: true); } @@ -49,11 +49,11 @@ public sealed class MOTDSystem : EntitySystem /// /// Sends the Message Of The Day, if any, to a specific player. /// - public void TrySendMOTD(IPlayerSession player) + public void TrySendMOTD(ICommonSession player) { if (string.IsNullOrEmpty(_messageOfTheDay)) return; - + var wrappedMessage = Loc.GetString("motd-wrap-message", ("motd", _messageOfTheDay)); _chatManager.ChatMessageToOne(ChatChannel.Server, _messageOfTheDay, wrappedMessage, source: EntityUid.Invalid, hideChat: false, client: player.ConnectedClient); } @@ -68,10 +68,10 @@ public sealed class MOTDSystem : EntitySystem { if (string.IsNullOrEmpty(_messageOfTheDay)) return; - + var wrappedMessage = Loc.GetString("motd-wrap-message", ("motd", _messageOfTheDay)); shell.WriteLine(wrappedMessage); - if (shell.Player is IPlayerSession player) + if (shell.Player is { } player) _chatManager.ChatMessageToOne(ChatChannel.Server, _messageOfTheDay, wrappedMessage, source: EntityUid.Invalid, hideChat: false, client: player.ConnectedClient); } @@ -92,7 +92,7 @@ public sealed class MOTDSystem : EntitySystem { if (val == _messageOfTheDay) return; - + _messageOfTheDay = val; TrySendMOTD(); } diff --git a/Content.Server/Motd/SetMOTDCommand.cs b/Content.Server/Motd/SetMOTDCommand.cs index f3f52b0670..9678781c87 100644 --- a/Content.Server/Motd/SetMOTDCommand.cs +++ b/Content.Server/Motd/SetMOTDCommand.cs @@ -4,7 +4,6 @@ using Content.Shared.Administration; using Content.Shared.Database; using Content.Shared.CCVar; using Content.Server.Chat.Managers; -using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Console; @@ -21,18 +20,18 @@ public sealed class SetMotdCommand : LocalizedCommands [Dependency] private readonly IConfigurationManager _configurationManager = default!; public override string Command => "set-motd"; - + public override void Execute(IConsoleShell shell, string argStr, string[] args) { string motd = ""; - var player = (IPlayerSession?)shell.Player; + var player = shell.Player; if (args.Length > 0) { motd = string.Join(" ", args).Trim(); if (player != null && _chatManager.MessageCharacterLimit(player, motd)) return; // check function prints its own error response } - + _configurationManager.SetCVar(CCVars.MOTD, motd); // A hook in MOTDSystem broadcasts changes to the MOTD to everyone so we don't need to do it here. if (string.IsNullOrEmpty(motd)) { diff --git a/Content.Server/Movement/Systems/LagCompensationSystem.cs b/Content.Server/Movement/Systems/LagCompensationSystem.cs index 64965c2fee..0576fe8f25 100644 --- a/Content.Server/Movement/Systems/LagCompensationSystem.cs +++ b/Content.Server/Movement/Systems/LagCompensationSystem.cs @@ -1,7 +1,7 @@ using Content.Server.Movement.Components; using Robust.Server.Player; using Robust.Shared.Map; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.Movement.Systems; diff --git a/Content.Server/NPC/Commands/NPCCommand.cs b/Content.Server/NPC/Commands/NPCCommand.cs index 57fe223b66..7f9e56b8ca 100644 --- a/Content.Server/NPC/Commands/NPCCommand.cs +++ b/Content.Server/NPC/Commands/NPCCommand.cs @@ -2,7 +2,6 @@ using Content.Server.Administration; using Content.Server.EUI; using Content.Server.NPC.UI; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.NPC.Commands; @@ -15,7 +14,7 @@ public sealed class NPCCommand : IConsoleCommand public string Help => $"{Command}"; public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession playerSession) + if (shell.Player is not { } playerSession) { return; } diff --git a/Content.Server/NPC/HTN/HTNSystem.cs b/Content.Server/NPC/HTN/HTNSystem.cs index 2c1dadb127..a7689fbabe 100644 --- a/Content.Server/NPC/HTN/HTNSystem.cs +++ b/Content.Server/NPC/HTN/HTNSystem.cs @@ -4,17 +4,14 @@ using System.Threading; using Content.Server.Administration.Managers; using Robust.Shared.CPUJob.JobQueues; using Robust.Shared.CPUJob.JobQueues.Queues; -using Content.Server.NPC.Components; using Content.Server.NPC.HTN.PrimitiveTasks; using Content.Server.NPC.Systems; using Content.Shared.Administration; using Content.Shared.Mobs; using Content.Shared.NPC; -using Content.Shared.NPC; using JetBrains.Annotations; using Robust.Server.GameObjects; -using Robust.Server.Player; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Utility; @@ -48,7 +45,7 @@ public sealed class HTNSystem : EntitySystem private void OnHTNMessage(RequestHTNMessage msg, EntitySessionEventArgs args) { - if (!_admin.HasAdminFlag((IPlayerSession) args.SenderSession, AdminFlags.Debug)) + if (!_admin.HasAdminFlag(args.SenderSession, AdminFlags.Debug)) { _subscribers.Remove(args.SenderSession); return; diff --git a/Content.Server/NPC/Pathfinding/PathfindingSystem.cs b/Content.Server/NPC/Pathfinding/PathfindingSystem.cs index bb0eff7b39..1b1f6f5476 100644 --- a/Content.Server/NPC/Pathfinding/PathfindingSystem.cs +++ b/Content.Server/NPC/Pathfinding/PathfindingSystem.cs @@ -13,7 +13,7 @@ using Robust.Shared.Enums; using Robust.Shared.Map; using Robust.Shared.Physics; using Robust.Shared.Physics.Systems; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Random; using Robust.Shared.Threading; using Robust.Shared.Timing; @@ -528,7 +528,7 @@ namespace Content.Server.NPC.Pathfinding private void OnBreadcrumbs(RequestPathfindingDebugMessage msg, EntitySessionEventArgs args) { - var pSession = (IPlayerSession) args.SenderSession; + var pSession = args.SenderSession; if (!_adminManager.HasAdminFlag(pSession, AdminFlags.Debug)) { diff --git a/Content.Server/NPC/Systems/NPCSteeringSystem.cs b/Content.Server/NPC/Systems/NPCSteeringSystem.cs index 61b43df6f0..e5b62acfe8 100644 --- a/Content.Server/NPC/Systems/NPCSteeringSystem.cs +++ b/Content.Server/NPC/Systems/NPCSteeringSystem.cs @@ -17,14 +17,12 @@ using Content.Shared.NPC; using Content.Shared.NPC.Events; using Content.Shared.Physics; using Content.Shared.Weapons.Melee; -using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Map; using Robust.Shared.Physics; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; using Robust.Shared.Player; -using Robust.Shared.Players; using Robust.Shared.Random; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -147,7 +145,7 @@ public sealed partial class NPCSteeringSystem : SharedNPCSteeringSystem private void OnDebugRequest(RequestNPCSteeringDebugEvent msg, EntitySessionEventArgs args) { - if (!_admin.IsAdmin((IPlayerSession)args.SenderSession)) + if (!_admin.IsAdmin(args.SenderSession)) return; if (msg.Enabled) diff --git a/Content.Server/NodeContainer/EntitySystems/NodeGroupSystem.cs b/Content.Server/NodeContainer/EntitySystems/NodeGroupSystem.cs index e4bd303150..9ee9702c5b 100644 --- a/Content.Server/NodeContainer/EntitySystems/NodeGroupSystem.cs +++ b/Content.Server/NodeContainer/EntitySystems/NodeGroupSystem.cs @@ -9,6 +9,7 @@ using JetBrains.Annotations; using Robust.Server.Player; using Robust.Shared.Enums; using Robust.Shared.Map; +using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Server.NodeContainer.EntitySystems @@ -29,7 +30,7 @@ namespace Content.Server.NodeContainer.EntitySystems private readonly List _visDeletes = new(); private readonly List _visSends = new(); - private readonly HashSet _visPlayers = new(); + private readonly HashSet _visPlayers = new(); private readonly HashSet _toRemake = new(); private readonly HashSet _nodeGroups = new(); private readonly HashSet _toRemove = new(); @@ -74,7 +75,7 @@ namespace Content.Server.NodeContainer.EntitySystems private void HandleEnableMsg(NodeVis.MsgEnable msg, EntitySessionEventArgs args) { - var session = (IPlayerSession) args.SenderSession; + var session = args.SenderSession; if (!_adminManager.HasAdminFlag(session, AdminFlags.Debug)) return; @@ -397,7 +398,7 @@ namespace Content.Server.NodeContainer.EntitySystems } } - private void VisSendFullStateImmediate(IPlayerSession player) + private void VisSendFullStateImmediate(ICommonSession player) { var msg = new NodeVis.MsgData(); diff --git a/Content.Server/Nutrition/Hungry.cs b/Content.Server/Nutrition/Hungry.cs index c27f302a8d..ae68dcd2fd 100644 --- a/Content.Server/Nutrition/Hungry.cs +++ b/Content.Server/Nutrition/Hungry.cs @@ -1,9 +1,7 @@ using Content.Server.Administration; -using Content.Server.Nutrition.Components; using Content.Shared.Administration; using Content.Shared.Nutrition.Components; using Content.Shared.Nutrition.EntitySystems; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Nutrition @@ -19,7 +17,7 @@ namespace Content.Server.Nutrition public void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null) { shell.WriteLine("You cannot use this command unless you are a player."); diff --git a/Content.Server/Objectives/Commands/ListObjectivesCommand.cs b/Content.Server/Objectives/Commands/ListObjectivesCommand.cs index 93dec3fa44..97fc943269 100644 --- a/Content.Server/Objectives/Commands/ListObjectivesCommand.cs +++ b/Content.Server/Objectives/Commands/ListObjectivesCommand.cs @@ -18,7 +18,7 @@ namespace Content.Server.Objectives.Commands public override void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; + var player = shell.Player; if (player == null || !_players.TryGetSessionByUsername(args[0], out player)) { shell.WriteError(LocalizationManager.GetString("shell-target-player-does-not-exist")); diff --git a/Content.Server/PDA/PdaSystem.cs b/Content.Server/PDA/PdaSystem.cs index 6c506dc3dd..44e2659841 100644 --- a/Content.Server/PDA/PdaSystem.cs +++ b/Content.Server/PDA/PdaSystem.cs @@ -4,9 +4,6 @@ using Content.Server.DeviceNetwork.Components; using Content.Server.Instruments; using Content.Server.Light.EntitySystems; using Content.Server.Light.Events; -using Content.Server.MassMedia.Components; -using Content.Server.MassMedia.Systems; -using Content.Server.Mind; using Content.Server.PDA.Ringer; using Content.Server.Station.Systems; using Content.Server.Store.Components; @@ -16,7 +13,6 @@ using Content.Shared.CartridgeLoader; using Content.Shared.Light.Components; using Content.Shared.PDA; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Containers; namespace Content.Server.PDA @@ -180,7 +176,7 @@ namespace Content.Server.PDA return; if (HasComp(uid)) - _ringer.ToggleRingerUI(uid, (IPlayerSession) msg.Session); + _ringer.ToggleRingerUI(uid, msg.Session); } private void OnUiMessage(EntityUid uid, PdaComponent pda, PdaShowMusicMessage msg) @@ -189,7 +185,7 @@ namespace Content.Server.PDA return; if (TryComp(uid, out var instrument)) - _instrument.ToggleInstrumentUi(uid, (IPlayerSession) msg.Session, instrument); + _instrument.ToggleInstrumentUi(uid, msg.Session, instrument); } private void OnUiMessage(EntityUid uid, PdaComponent pda, PdaShowUplinkMessage msg) diff --git a/Content.Server/PDA/Ringer/RingerSystem.cs b/Content.Server/PDA/Ringer/RingerSystem.cs index a772e76bc4..7494d5e12c 100644 --- a/Content.Server/PDA/Ringer/RingerSystem.cs +++ b/Content.Server/PDA/Ringer/RingerSystem.cs @@ -7,7 +7,6 @@ using Content.Shared.PDA.Ringer; using Content.Shared.Popups; using Content.Shared.Store; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Audio; using Robust.Shared.Network; using Robust.Shared.Player; @@ -182,7 +181,7 @@ namespace Content.Server.PDA.Ringer _ui.SetUiState(bui, new RingerUpdateState(isPlaying, ringer.Ringtone)); } - public bool ToggleRingerUI(EntityUid uid, IPlayerSession session) + public bool ToggleRingerUI(EntityUid uid, ICommonSession session) { if (_ui.TryGetUi(uid, RingerUiKey.Key, out var bui)) _ui.ToggleUi(bui, session); diff --git a/Content.Server/Paper/PaperSystem.cs b/Content.Server/Paper/PaperSystem.cs index f38013e14d..553bcaa0a2 100644 --- a/Content.Server/Paper/PaperSystem.cs +++ b/Content.Server/Paper/PaperSystem.cs @@ -4,15 +4,11 @@ using Content.Server.Popups; using Content.Server.UserInterface; using Content.Shared.Database; using Content.Shared.Examine; -using Content.Shared.IdentityManagement; using Content.Shared.Interaction; using Content.Shared.Paper; using Content.Shared.Tag; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Player; -using Robust.Shared.Utility; -using Robust.Shared.Audio; using static Content.Shared.Paper.SharedPaperComponent; namespace Content.Server.Paper @@ -207,7 +203,7 @@ namespace Content.Server.Paper _appearance.SetData(uid, PaperVisuals.Status, status, appearance); } - public void UpdateUserInterface(EntityUid uid, PaperComponent? paperComp = null, IPlayerSession? session = null) + public void UpdateUserInterface(EntityUid uid, PaperComponent? paperComp = null, ICommonSession? session = null) { if (!Resolve(uid, ref paperComp)) return; diff --git a/Content.Server/Parallax/BiomeSystem.cs b/Content.Server/Parallax/BiomeSystem.cs index a9d78afa86..c9017ac821 100644 --- a/Content.Server/Parallax/BiomeSystem.cs +++ b/Content.Server/Parallax/BiomeSystem.cs @@ -282,9 +282,8 @@ public sealed partial class BiomeSystem : SharedBiomeSystem } // Get chunks in range - foreach (var client in Filter.GetAllPlayers(_playerManager)) + foreach (var pSession in Filter.GetAllPlayers(_playerManager)) { - var pSession = (IPlayerSession) client; if (xformQuery.TryGetComponent(pSession.AttachedEntity, out var xform) && _handledEntities.Add(pSession.AttachedEntity.Value) && diff --git a/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.ControlBox.cs b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.ControlBox.cs index 20ed276967..f200c991d7 100644 --- a/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.ControlBox.cs +++ b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.ControlBox.cs @@ -2,11 +2,10 @@ using Content.Server.ParticleAccelerator.Components; using Content.Server.Power.Components; using Content.Shared.Database; using Content.Shared.Singularity.Components; -using Robust.Server.Player; -using Robust.Server.GameObjects; using Robust.Shared.Utility; using System.Diagnostics; using Content.Shared.CCVar; +using Robust.Shared.Player; namespace Content.Server.ParticleAccelerator.EntitySystems; @@ -60,7 +59,7 @@ public sealed partial class ParticleAcceleratorSystem FireEmitter(comp.StarboardEmitter!.Value, strength); } - public void SwitchOn(EntityUid uid, IPlayerSession? user = null, ParticleAcceleratorControlBoxComponent? comp = null) + public void SwitchOn(EntityUid uid, ICommonSession? user = null, ParticleAcceleratorControlBoxComponent? comp = null) { if (!Resolve(uid, ref comp)) return; @@ -83,7 +82,7 @@ public sealed partial class ParticleAcceleratorSystem UpdateUI(uid, comp); } - public void SwitchOff(EntityUid uid, IPlayerSession? user = null, ParticleAcceleratorControlBoxComponent? comp = null) + public void SwitchOff(EntityUid uid, ICommonSession? user = null, ParticleAcceleratorControlBoxComponent? comp = null) { if (!Resolve(uid, ref comp)) return; @@ -131,7 +130,7 @@ public sealed partial class ParticleAcceleratorSystem UpdateUI(uid, comp); } - public void SetStrength(EntityUid uid, ParticleAcceleratorPowerState strength, IPlayerSession? user = null, ParticleAcceleratorControlBoxComponent? comp = null) + public void SetStrength(EntityUid uid, ParticleAcceleratorPowerState strength, ICommonSession? user = null, ParticleAcceleratorControlBoxComponent? comp = null) { if (!Resolve(uid, ref comp)) return; @@ -347,10 +346,10 @@ public sealed partial class ParticleAcceleratorSystem if (msg.Enabled) { if (comp.Assembled) - SwitchOn(uid, (IPlayerSession?) msg.Session, comp); + SwitchOn(uid, msg.Session, comp); } else - SwitchOff(uid, (IPlayerSession?) msg.Session, comp); + SwitchOff(uid, msg.Session, comp); UpdateUI(uid, comp); } @@ -364,7 +363,7 @@ public sealed partial class ParticleAcceleratorSystem if (TryComp(uid, out var apcPower) && !apcPower.Powered) return; - SetStrength(uid, msg.State, (IPlayerSession?) msg.Session, comp); + SetStrength(uid, msg.State, msg.Session, comp); UpdateUI(uid, comp); } @@ -378,7 +377,7 @@ public sealed partial class ParticleAcceleratorSystem if (TryComp(uid, out var apcPower) && !apcPower.Powered) return; - RescanParts(uid, (IPlayerSession?) msg.Session, comp); + RescanParts(uid, msg.Session, comp); UpdateUI(uid, comp); } diff --git a/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Parts.cs b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Parts.cs index 271d17a0c4..abc68543ff 100644 --- a/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Parts.cs +++ b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Parts.cs @@ -2,9 +2,9 @@ using System.Diagnostics.CodeAnalysis; using System.Numerics; using Content.Server.ParticleAccelerator.Components; using JetBrains.Annotations; -using Robust.Server.Player; using Robust.Shared.Map.Components; using Robust.Shared.Physics.Events; +using Robust.Shared.Player; namespace Content.Server.ParticleAccelerator.EntitySystems; @@ -18,7 +18,7 @@ public sealed partial class ParticleAcceleratorSystem SubscribeLocalEvent(BodyTypeChanged); } - public void RescanParts(EntityUid uid, IPlayerSession? user = null, ParticleAcceleratorControlBoxComponent? controller = null) + public void RescanParts(EntityUid uid, ICommonSession? user = null, ParticleAcceleratorControlBoxComponent? controller = null) { if (!Resolve(uid, ref controller)) return; diff --git a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingManager.cs b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingManager.cs index 50c64e718c..bcc6f211ed 100644 --- a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingManager.cs +++ b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingManager.cs @@ -5,18 +5,18 @@ using System.Threading.Tasks; using Content.Server.Database; using Content.Shared.CCVar; using Content.Shared.Players.PlayTimeTracking; -using Robust.Server.Player; using Robust.Shared.Asynchronous; using Robust.Shared.Collections; using Robust.Shared.Configuration; using Robust.Shared.Exceptions; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Timing; using Robust.Shared.Utility; namespace Content.Server.Players.PlayTimeTracking; -public delegate void CalcPlayTimeTrackersCallback(IPlayerSession player, HashSet trackers); +public delegate void CalcPlayTimeTrackersCallback(ICommonSession player, HashSet trackers); /// /// Tracks play time for players, across all roles. @@ -66,7 +66,7 @@ public sealed class PlayTimeTrackingManager private ISawmill _sawmill = default!; // List of players that need some kind of update (refresh timers or resend). - private ValueList _playersDirty; + private ValueList _playersDirty; // DB auto-saving logic. private TimeSpan _saveInterval; @@ -76,7 +76,7 @@ public sealed class PlayTimeTrackingManager // We must block server shutdown on these to avoid losing data. private readonly List _pendingSaveTasks = new(); - private readonly Dictionary _playTimeData = new(); + private readonly Dictionary _playTimeData = new(); public event CalcPlayTimeTrackersCallback? CalcTrackers; @@ -139,7 +139,7 @@ public sealed class PlayTimeTrackingManager _playersDirty.Clear(); } - private void RefreshSingleTracker(IPlayerSession dirty, PlayTimeData data, TimeSpan time) + private void RefreshSingleTracker(ICommonSession dirty, PlayTimeData data, TimeSpan time) { DebugTools.Assert(data.Initialized); @@ -181,7 +181,7 @@ public sealed class PlayTimeTrackingManager /// so APIs like return up-to-date info. /// /// - public void FlushTracker(IPlayerSession player) + public void FlushTracker(ICommonSession player) { var time = _timing.RealTime; var data = _playTimeData[player]; @@ -201,7 +201,7 @@ public sealed class PlayTimeTrackingManager } } - private void SendPlayTimes(IPlayerSession pSession) + private void SendPlayTimes(ICommonSession pSession) { var roles = GetTrackerTimes(pSession); @@ -228,7 +228,7 @@ public sealed class PlayTimeTrackingManager /// /// Save all modified time trackers for a player to the database. /// - public async void SaveSession(IPlayerSession session) + public async void SaveSession(ICommonSession session) { // This causes all trackers to refresh, ah well. FlushAllTrackers(); @@ -278,7 +278,7 @@ public sealed class PlayTimeTrackingManager _sawmill.Debug($"Saved {log.Count} trackers"); } - private async Task DoSaveSessionAsync(IPlayerSession session) + private async Task DoSaveSessionAsync(ICommonSession session) { var log = new List(); @@ -299,7 +299,7 @@ public sealed class PlayTimeTrackingManager _sawmill.Debug($"Saved {log.Count} trackers for {session.Name}"); } - public async Task LoadData(IPlayerSession session, CancellationToken cancel) + public async Task LoadData(ICommonSession session, CancellationToken cancel) { var data = new PlayTimeData(); _playTimeData.Add(session, data); @@ -318,14 +318,14 @@ public sealed class PlayTimeTrackingManager QueueSendTimers(session); } - public void ClientDisconnected(IPlayerSession session) + public void ClientDisconnected(ICommonSession session) { SaveSession(session); _playTimeData.Remove(session); } - public void AddTimeToTracker(IPlayerSession id, string tracker, TimeSpan time) + public void AddTimeToTracker(ICommonSession id, string tracker, TimeSpan time) { if (!_playTimeData.TryGetValue(id, out var data) || !data.Initialized) throw new InvalidOperationException("Play time info is not yet loaded for this player!"); @@ -341,17 +341,17 @@ public sealed class PlayTimeTrackingManager data.DbTrackersDirty.Add(tracker); } - public void AddTimeToOverallPlaytime(IPlayerSession id, TimeSpan time) + public void AddTimeToOverallPlaytime(ICommonSession id, TimeSpan time) { AddTimeToTracker(id, PlayTimeTrackingShared.TrackerOverall, time); } - public TimeSpan GetOverallPlaytime(IPlayerSession id) + public TimeSpan GetOverallPlaytime(ICommonSession id) { return GetPlayTimeForTracker(id, PlayTimeTrackingShared.TrackerOverall); } - public bool TryGetTrackerTimes(IPlayerSession id, [NotNullWhen(true)] out Dictionary? time) + public bool TryGetTrackerTimes(ICommonSession id, [NotNullWhen(true)] out Dictionary? time) { time = null; @@ -364,7 +364,7 @@ public sealed class PlayTimeTrackingManager return true; } - public Dictionary GetTrackerTimes(IPlayerSession id) + public Dictionary GetTrackerTimes(ICommonSession id) { if (!_playTimeData.TryGetValue(id, out var data) || !data.Initialized) throw new InvalidOperationException("Play time info is not yet loaded for this player!"); @@ -372,7 +372,7 @@ public sealed class PlayTimeTrackingManager return data.TrackerTimes; } - public TimeSpan GetPlayTimeForTracker(IPlayerSession id, string tracker) + public TimeSpan GetPlayTimeForTracker(ICommonSession id, string tracker) { if (!_playTimeData.TryGetValue(id, out var data) || !data.Initialized) throw new InvalidOperationException("Play time info is not yet loaded for this player!"); @@ -383,7 +383,7 @@ public sealed class PlayTimeTrackingManager /// /// Queue for play time trackers to be refreshed on a player, in case the set of active trackers may have changed. /// - public void QueueRefreshTrackers(IPlayerSession player) + public void QueueRefreshTrackers(ICommonSession player) { if (DirtyPlayer(player) is { } data) data.NeedRefreshTackers = true; @@ -392,13 +392,13 @@ public sealed class PlayTimeTrackingManager /// /// Queue for play time information to be sent to a client, for showing in UIs etc. /// - public void QueueSendTimers(IPlayerSession player) + public void QueueSendTimers(ICommonSession player) { if (DirtyPlayer(player) is { } data) data.NeedSendTimers = true; } - private PlayTimeData? DirtyPlayer(IPlayerSession player) + private PlayTimeData? DirtyPlayer(ICommonSession player) { if (!_playTimeData.TryGetValue(player, out var data) || !data.Initialized) return null; diff --git a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs index 13d0794dd5..f865b25bac 100644 --- a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs +++ b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs @@ -14,6 +14,7 @@ using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Utility; @@ -55,7 +56,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem _tracking.CalcTrackers -= CalcTrackers; } - private void CalcTrackers(IPlayerSession player, HashSet trackers) + private void CalcTrackers(ICommonSession player, HashSet trackers) { if (_afk.IsAfk(player)) return; @@ -67,7 +68,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem trackers.UnionWith(GetTimedRoles(player)); } - private bool IsPlayerAlive(IPlayerSession session) + private bool IsPlayerAlive(ICommonSession session) { var attached = session.AttachedEntity; if (attached == null) @@ -93,7 +94,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem } } - private IEnumerable GetTimedRoles(IPlayerSession session) + private IEnumerable GetTimedRoles(ICommonSession session) { var contentData = _playerManager.GetPlayerData(session.UserId).ContentData(); @@ -156,7 +157,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem _tracking.QueueSendTimers(ev.PlayerSession); } - public bool IsAllowed(IPlayerSession player, string role) + public bool IsAllowed(ICommonSession player, string role) { if (!_prototypes.TryIndex(role, out var job) || job.Requirements == null || @@ -168,7 +169,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem return JobRequirements.TryRequirementsMet(job, playTimes, out _, EntityManager, _prototypes); } - public HashSet GetDisallowedJobs(IPlayerSession player) + public HashSet GetDisallowedJobs(ICommonSession player) { var roles = new HashSet(); if (!_cfg.GetCVar(CCVars.GameRoleTimers)) @@ -230,7 +231,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem } } - public void PlayerRolesChanged(IPlayerSession player) + public void PlayerRolesChanged(ICommonSession player) { _tracking.QueueRefreshTrackers(player); } diff --git a/Content.Server/Players/PlayerData.cs b/Content.Server/Players/PlayerData.cs deleted file mode 100644 index b0ca6f3c18..0000000000 --- a/Content.Server/Players/PlayerData.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Content.Shared.Players; -using Robust.Server.Player; -using Robust.Shared.Players; - -namespace Content.Server.Players -{ - public static class PlayerDataExt - { - /// - /// Gets the correctly cast instance of content player data from an engine player data storage. - /// - public static PlayerData? ContentData(this IPlayerSession session) - { - return session.Data.ContentData(); - } - - public static PlayerData? ContentData(this ICommonSession session) - { - return ((IPlayerSession) session).ContentData(); - } - - /// - /// Gets the mind that is associated with this player. - /// - public static EntityUid? GetMind(this IPlayerSession session) - { - return session.Data.ContentData()?.Mind; - } - } -} diff --git a/Content.Server/Players/PlayerSystem.cs b/Content.Server/Players/PlayerSystem.cs index 0c407aa876..c79683c338 100644 --- a/Content.Server/Players/PlayerSystem.cs +++ b/Content.Server/Players/PlayerSystem.cs @@ -1,11 +1,11 @@ using Content.Shared.Players; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.Players; public sealed class PlayerSystem : SharedPlayerSystem { - public override PlayerData? ContentData(ICommonSession? session) + public override ContentPlayerData? ContentData(ICommonSession? session) { return session?.ContentData(); } diff --git a/Content.Server/Pointing/EntitySystems/PointingSystem.cs b/Content.Server/Pointing/EntitySystems/PointingSystem.cs index b253e32e37..6fcdfcf994 100644 --- a/Content.Server/Pointing/EntitySystems/PointingSystem.cs +++ b/Content.Server/Pointing/EntitySystems/PointingSystem.cs @@ -20,7 +20,6 @@ using Robust.Shared.Enums; using Robust.Shared.Input.Binding; using Robust.Shared.Map; using Robust.Shared.Player; -using Robust.Shared.Players; using Robust.Shared.Replays; using Robust.Shared.Timing; @@ -170,7 +169,7 @@ namespace Content.Server.Pointing.EntitySystems } // Get players that are in range and whose visibility layer matches the arrow's. - bool ViewerPredicate(IPlayerSession playerSession) + bool ViewerPredicate(ICommonSession playerSession) { if (!_minds.TryGetMind(playerSession, out _, out var mind) || mind.CurrentEntity is not { Valid: true } ent || @@ -182,7 +181,7 @@ namespace Content.Server.Pointing.EntitySystems } var viewers = Filter.Empty() - .AddWhere(session1 => ViewerPredicate((IPlayerSession) session1)) + .AddWhere(session1 => ViewerPredicate(session1)) .Recipients; string selfMessage; diff --git a/Content.Server/Popups/PopupSystem.cs b/Content.Server/Popups/PopupSystem.cs index 483d4f3d3f..61ccaf4423 100644 --- a/Content.Server/Popups/PopupSystem.cs +++ b/Content.Server/Popups/PopupSystem.cs @@ -4,7 +4,6 @@ using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Map; using Robust.Shared.Player; -using Robust.Shared.Players; namespace Content.Server.Popups { diff --git a/Content.Server/Prayer/PrayerSystem.cs b/Content.Server/Prayer/PrayerSystem.cs index be6ae80bfd..e20291cc06 100644 --- a/Content.Server/Prayer/PrayerSystem.cs +++ b/Content.Server/Prayer/PrayerSystem.cs @@ -5,12 +5,11 @@ using Content.Server.Chat.Managers; using Content.Server.Popups; using Content.Shared.Database; using Content.Shared.Popups; -using Robust.Server.Player; -using Robust.Shared.Player; using Content.Shared.Chat; using Content.Shared.Prayer; using Content.Shared.Verbs; using Robust.Server.GameObjects; +using Robust.Shared.Player; namespace Content.Server.Prayer; /// @@ -74,7 +73,7 @@ public sealed class PrayerSystem : EntitySystem /// The IPlayerSession that sent the message /// The main message sent to the player via the chatbox /// The popup to notify the player, also prepended to the messageString - public void SendSubtleMessage(IPlayerSession target, IPlayerSession source, string messageString, string popupMessage) + public void SendSubtleMessage(ICommonSession target, ICommonSession source, string messageString, string popupMessage) { if (target.AttachedEntity == null) return; @@ -96,7 +95,7 @@ public sealed class PrayerSystem : EntitySystem /// You may be wondering, "Why the admin chat, specifically? Nobody even reads it!" /// Exactly. /// - public void Pray(IPlayerSession sender, PrayableComponent comp, string message) + public void Pray(ICommonSession sender, PrayableComponent comp, string message) { if (sender.AttachedEntity == null) return; diff --git a/Content.Server/Preferences/Managers/IServerPreferencesManager.cs b/Content.Server/Preferences/Managers/IServerPreferencesManager.cs index 8c06e00ab1..a36b053717 100644 --- a/Content.Server/Preferences/Managers/IServerPreferencesManager.cs +++ b/Content.Server/Preferences/Managers/IServerPreferencesManager.cs @@ -2,8 +2,8 @@ using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; using Content.Shared.Preferences; -using Robust.Server.Player; using Robust.Shared.Network; +using Robust.Shared.Player; namespace Content.Server.Preferences.Managers { @@ -11,12 +11,12 @@ namespace Content.Server.Preferences.Managers { void Init(); - Task LoadData(IPlayerSession session, CancellationToken cancel); - void OnClientDisconnected(IPlayerSession session); + Task LoadData(ICommonSession session, CancellationToken cancel); + void OnClientDisconnected(ICommonSession session); bool TryGetCachedPreferences(NetUserId userId, [NotNullWhen(true)] out PlayerPreferences? playerPreferences); PlayerPreferences GetPreferences(NetUserId userId); IEnumerable> GetSelectedProfilesForPlayers(List userIds); - bool HavePreferencesLoaded(IPlayerSession session); + bool HavePreferencesLoaded(ICommonSession session); } } diff --git a/Content.Server/Preferences/Managers/ServerPreferencesManager.cs b/Content.Server/Preferences/Managers/ServerPreferencesManager.cs index ea04d00e82..a0b5e8ce65 100644 --- a/Content.Server/Preferences/Managers/ServerPreferencesManager.cs +++ b/Content.Server/Preferences/Managers/ServerPreferencesManager.cs @@ -8,9 +8,9 @@ using Content.Shared.CCVar; using Content.Shared.Humanoid.Prototypes; using Content.Shared.Preferences; using Content.Shared.Roles; -using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Prototypes; @@ -167,7 +167,7 @@ namespace Content.Server.Preferences.Managers } // Should only be called via UserDbDataManager. - public async Task LoadData(IPlayerSession session, CancellationToken cancel) + public async Task LoadData(ICommonSession session, CancellationToken cancel) { if (!ShouldStorePrefs(session.ConnectedClient.AuthType)) { @@ -207,12 +207,12 @@ namespace Content.Server.Preferences.Managers } } - public void OnClientDisconnected(IPlayerSession session) + public void OnClientDisconnected(ICommonSession session) { _cachedPlayerPrefs.Remove(session.UserId); } - public bool HavePreferencesLoaded(IPlayerSession session) + public bool HavePreferencesLoaded(ICommonSession session) { return _cachedPlayerPrefs.ContainsKey(session.UserId); } diff --git a/Content.Server/Pulling/PullingSystem.cs b/Content.Server/Pulling/PullingSystem.cs index f7ea0aae57..69bb7c9370 100644 --- a/Content.Server/Pulling/PullingSystem.cs +++ b/Content.Server/Pulling/PullingSystem.cs @@ -4,7 +4,7 @@ using Content.Shared.Pulling.Components; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Shared.Input.Binding; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.Pulling { diff --git a/Content.Server/Radiation/Systems/RadiationSystem.Debug.cs b/Content.Server/Radiation/Systems/RadiationSystem.Debug.cs index 97f2e485ca..56806d8c9c 100644 --- a/Content.Server/Radiation/Systems/RadiationSystem.Debug.cs +++ b/Content.Server/Radiation/Systems/RadiationSystem.Debug.cs @@ -7,7 +7,7 @@ using Content.Shared.Radiation.Systems; using Robust.Shared.Console; using Robust.Shared.Enums; using Robust.Shared.Map.Components; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.Radiation.Systems; diff --git a/Content.Server/Research/Systems/ResearchSystem.Client.cs b/Content.Server/Research/Systems/ResearchSystem.Client.cs index e813f09ff9..135ef8fe88 100644 --- a/Content.Server/Research/Systems/ResearchSystem.Client.cs +++ b/Content.Server/Research/Systems/ResearchSystem.Client.cs @@ -1,7 +1,6 @@ using System.Diagnostics.CodeAnalysis; using Content.Server.Power.EntitySystems; using Content.Shared.Research.Components; -using Robust.Server.Player; namespace Content.Server.Research.Systems; @@ -46,7 +45,7 @@ public sealed partial class ResearchSystem if (!this.IsPowered(uid, EntityManager)) return; - _uiSystem.TryToggleUi(uid, ResearchClientUiKey.Key, (IPlayerSession) args.Session); + _uiSystem.TryToggleUi(uid, ResearchClientUiKey.Key, args.Session); } #endregion diff --git a/Content.Server/Salvage/SalvageRulerCommand.cs b/Content.Server/Salvage/SalvageRulerCommand.cs index b0a64508c5..a1fd609741 100644 --- a/Content.Server/Salvage/SalvageRulerCommand.cs +++ b/Content.Server/Salvage/SalvageRulerCommand.cs @@ -1,6 +1,5 @@ using Content.Server.Administration; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; @@ -26,7 +25,7 @@ sealed class SalvageRulerCommand : IConsoleCommand return; } - if (shell.Player is not IPlayerSession player) + if (shell.Player is not { } player) { shell.WriteError(Loc.GetString("shell-only-players-can-run-this-command")); return; diff --git a/Content.Server/Sandbox/Commands/ColorNetworkCommand.cs b/Content.Server/Sandbox/Commands/ColorNetworkCommand.cs index 0b9148f0fb..cc20b71946 100644 --- a/Content.Server/Sandbox/Commands/ColorNetworkCommand.cs +++ b/Content.Server/Sandbox/Commands/ColorNetworkCommand.cs @@ -4,7 +4,6 @@ using Content.Server.Atmos.Piping.EntitySystems; using Content.Server.NodeContainer; using Content.Server.NodeContainer.NodeGroups; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Sandbox.Commands @@ -20,7 +19,7 @@ namespace Content.Server.Sandbox.Commands { var sandboxManager = EntitySystem.Get(); var adminManager = IoCManager.Resolve(); - if (shell.IsClient && (!sandboxManager.IsSandboxEnabled && !adminManager.HasAdminFlag((IPlayerSession)shell.Player!, AdminFlags.Mapping))) + if (shell.IsClient && (!sandboxManager.IsSandboxEnabled && !adminManager.HasAdminFlag(shell.Player!, AdminFlags.Mapping))) { shell.WriteError("You are not currently able to use mapping commands."); } diff --git a/Content.Server/Sandbox/SandboxSystem.cs b/Content.Server/Sandbox/SandboxSystem.cs index ec9b1a0c3c..194cf59843 100644 --- a/Content.Server/Sandbox/SandboxSystem.cs +++ b/Content.Server/Sandbox/SandboxSystem.cs @@ -13,6 +13,7 @@ using Robust.Server.Console; using Robust.Server.Placement; using Robust.Server.Player; using Robust.Shared.Enums; +using Robust.Shared.Player; namespace Content.Server.Sandbox { diff --git a/Content.Server/SensorMonitoring/SensorMonitoringConsoleComponent.cs b/Content.Server/SensorMonitoring/SensorMonitoringConsoleComponent.cs index cd4f2ea23b..63b4d9daef 100644 --- a/Content.Server/SensorMonitoring/SensorMonitoringConsoleComponent.cs +++ b/Content.Server/SensorMonitoring/SensorMonitoringConsoleComponent.cs @@ -1,7 +1,7 @@ using Content.Shared.SensorMonitoring; using Robust.Server.Player; using Robust.Shared.Collections; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Server.SensorMonitoring; diff --git a/Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.UI.cs b/Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.UI.cs index a09badcd59..6c0dddeb26 100644 --- a/Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.UI.cs +++ b/Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.UI.cs @@ -1,7 +1,5 @@ using Content.Server.DeviceNetwork.Components; using Content.Shared.SensorMonitoring; -using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Collections; using ConsoleUIState = Content.Shared.SensorMonitoring.SensorMonitoringConsoleBoundInterfaceState; using IncrementalUIState = Content.Shared.SensorMonitoring.SensorMonitoringIncrementalUpdate; @@ -130,7 +128,7 @@ public sealed partial class SensorMonitoringConsoleSystem if (!args.UiKey.Equals(SensorMonitoringConsoleUiKey.Key)) return; - if (args.Session is not IPlayerSession player) + if (args.Session is not { } player) return; component.InitialUIStateSent.Remove(player); diff --git a/Content.Server/ServerUpdates/ServerUpdateManager.cs b/Content.Server/ServerUpdates/ServerUpdateManager.cs index 769c5d58d7..f4e54984e9 100644 --- a/Content.Server/ServerUpdates/ServerUpdateManager.cs +++ b/Content.Server/ServerUpdates/ServerUpdateManager.cs @@ -6,6 +6,7 @@ using Robust.Server.Player; using Robust.Server.ServerStatus; using Robust.Shared.Configuration; using Robust.Shared.Enums; +using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.ServerUpdates; diff --git a/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs b/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs index 1a1debc9e3..3ef3d97a21 100644 --- a/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs +++ b/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs @@ -20,7 +20,6 @@ using Content.Shared.Tag; using Content.Shared.Tiles; using Robust.Server.GameObjects; using Robust.Server.Maps; -using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Map; using Robust.Shared.Map.Components; @@ -140,7 +139,7 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem /// private void OnShuttleRequestPosition(EmergencyShuttleRequestPositionMessage msg, EntitySessionEventArgs args) { - if (!_admin.IsAdmin((IPlayerSession) args.SenderSession)) + if (!_admin.IsAdmin(args.SenderSession)) return; var player = args.SenderSession.AttachedEntity; diff --git a/Content.Server/Silicons/Borgs/BorgSystem.Modules.cs b/Content.Server/Silicons/Borgs/BorgSystem.Modules.cs index 31d826087d..c080420266 100644 --- a/Content.Server/Silicons/Borgs/BorgSystem.Modules.cs +++ b/Content.Server/Silicons/Borgs/BorgSystem.Modules.cs @@ -229,7 +229,7 @@ public sealed partial class BorgSystem if (!TryComp(chassis, out var hands)) return; - if (LifeStage(uid) >= EntityLifeStage.Terminating) + if (TerminatingOrDeleted(uid)) { foreach (var (hand, item) in component.ProvidedItems) { diff --git a/Content.Server/Silicons/Borgs/BorgSystem.cs b/Content.Server/Silicons/Borgs/BorgSystem.cs index 611dfa6ea2..883cb3b3d8 100644 --- a/Content.Server/Silicons/Borgs/BorgSystem.cs +++ b/Content.Server/Silicons/Borgs/BorgSystem.cs @@ -21,7 +21,7 @@ using Content.Shared.Throwing; using Content.Shared.Wires; using Robust.Server.GameObjects; using Robust.Shared.Containers; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Random; namespace Content.Server.Silicons.Borgs; diff --git a/Content.Server/Silicons/Laws/SiliconLawSystem.cs b/Content.Server/Silicons/Laws/SiliconLawSystem.cs index 45c944884e..b1ab1ac020 100644 --- a/Content.Server/Silicons/Laws/SiliconLawSystem.cs +++ b/Content.Server/Silicons/Laws/SiliconLawSystem.cs @@ -18,7 +18,6 @@ using Content.Shared.Silicons.Laws.Components; using Content.Shared.Stunnable; using Content.Shared.Wires; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Prototypes; using Robust.Shared.Toolshed; @@ -96,7 +95,7 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem HashSet? radioChannels = intrinsicRadio?.Channels; var state = new SiliconLawBuiState(GetLaws(uid).Laws, radioChannels); - _userInterface.TrySetUiState(args.Entity, SiliconLawsUiKey.Key, state, (IPlayerSession) args.Session); + _userInterface.TrySetUiState(args.Entity, SiliconLawsUiKey.Key, state, args.Session); } private void OnPlayerSpawnComplete(EntityUid uid, SiliconLawBoundComponent component, PlayerSpawnCompleteEvent args) diff --git a/Content.Server/Station/Systems/StationJobsSystem.cs b/Content.Server/Station/Systems/StationJobsSystem.cs index 2709bc2072..eeaace03b2 100644 --- a/Content.Server/Station/Systems/StationJobsSystem.cs +++ b/Content.Server/Station/Systems/StationJobsSystem.cs @@ -41,7 +41,7 @@ public sealed partial class StationJobsSystem : EntitySystem if (_availableJobsDirty) { _cachedAvailableJobs = GenerateJobsAvailableEvent(); - RaiseNetworkEvent(_cachedAvailableJobs, Filter.Empty().AddPlayers(_playerManager.ServerSessions)); + RaiseNetworkEvent(_cachedAvailableJobs, Filter.Empty().AddPlayers(_playerManager.Sessions)); _availableJobsDirty = false; } } diff --git a/Content.Server/Storage/EntitySystems/StorageSystem.cs b/Content.Server/Storage/EntitySystems/StorageSystem.cs index 3430449957..8b4ae1c76f 100644 --- a/Content.Server/Storage/EntitySystems/StorageSystem.cs +++ b/Content.Server/Storage/EntitySystems/StorageSystem.cs @@ -9,7 +9,6 @@ using Content.Shared.Storage.EntitySystems; using Content.Shared.Timing; using Content.Shared.Verbs; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Map; using Robust.Shared.Player; using Robust.Shared.Prototypes; @@ -135,7 +134,7 @@ public sealed partial class StorageSystem : SharedStorageSystem /// If the user has nested-UIs open (e.g., PDA UI open when pda is in a backpack), close them. /// /// - public void CloseNestedInterfaces(EntityUid uid, IPlayerSession session, StorageComponent? storageComp = null) + public void CloseNestedInterfaces(EntityUid uid, ICommonSession session, StorageComponent? storageComp = null) { if (!Resolve(uid, ref storageComp)) return; diff --git a/Content.Server/Tabletop/TabletopSession.cs b/Content.Server/Tabletop/TabletopSession.cs index d94b4fd657..5e7c6ac02e 100644 --- a/Content.Server/Tabletop/TabletopSession.cs +++ b/Content.Server/Tabletop/TabletopSession.cs @@ -1,6 +1,6 @@ using System.Numerics; -using Robust.Server.Player; using Robust.Shared.Map; +using Robust.Shared.Player; namespace Content.Server.Tabletop { @@ -17,7 +17,7 @@ namespace Content.Server.Tabletop /// /// The set of players currently playing this tabletop game. /// - public readonly Dictionary Players = new(); + public readonly Dictionary Players = new(); /// /// All entities bound to this session. If you create an entity for this session, you have to add it here. diff --git a/Content.Server/Tabletop/TabletopSystem.Session.cs b/Content.Server/Tabletop/TabletopSystem.Session.cs index e9dea0c66a..8f1bc7005d 100644 --- a/Content.Server/Tabletop/TabletopSystem.Session.cs +++ b/Content.Server/Tabletop/TabletopSystem.Session.cs @@ -1,7 +1,7 @@ using System.Numerics; using Content.Server.Tabletop.Components; using Content.Shared.Tabletop.Events; -using Robust.Server.Player; +using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Server.Tabletop @@ -66,7 +66,7 @@ namespace Content.Server.Tabletop /// /// The player session in question. /// The UID of the tabletop game entity. - public void OpenSessionFor(IPlayerSession player, EntityUid uid) + public void OpenSessionFor(ICommonSession player, EntityUid uid) { if (!EntityManager.TryGetComponent(uid, out TabletopGameComponent? tabletop) || player.AttachedEntity is not {Valid: true} attachedEntity) return; @@ -98,7 +98,7 @@ namespace Content.Server.Tabletop /// The player in question. /// The UID of the tabletop game entity. /// Whether to remove the from the player's attached entity. - public void CloseSessionFor(IPlayerSession player, EntityUid uid, bool removeGamerComponent = true) + public void CloseSessionFor(ICommonSession player, EntityUid uid, bool removeGamerComponent = true) { if (!EntityManager.TryGetComponent(uid, out TabletopGameComponent? tabletop) || tabletop.Session is not { } session) return; @@ -129,7 +129,7 @@ namespace Content.Server.Tabletop /// The player in question. /// An offset from the tabletop position for the camera. Zero by default. /// The UID of the camera entity. - private EntityUid CreateCamera(TabletopGameComponent tabletop, IPlayerSession player, Vector2 offset = default) + private EntityUid CreateCamera(TabletopGameComponent tabletop, ICommonSession player, Vector2 offset = default) { DebugTools.AssertNotNull(tabletop.Session); diff --git a/Content.Server/Tabletop/TabletopSystem.cs b/Content.Server/Tabletop/TabletopSystem.cs index 2e271080d0..b81331d62e 100644 --- a/Content.Server/Tabletop/TabletopSystem.cs +++ b/Content.Server/Tabletop/TabletopSystem.cs @@ -9,7 +9,6 @@ using Content.Shared.Tabletop.Events; using Content.Shared.Verbs; using JetBrains.Annotations; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Enums; using Robust.Shared.Map; using Robust.Shared.Utility; @@ -42,7 +41,7 @@ namespace Content.Server.Tabletop private void OnTabletopRequestTakeOut(TabletopRequestTakeOut msg, EntitySessionEventArgs args) { - if (args.SenderSession is not IPlayerSession playerSession) + if (args.SenderSession is not { } playerSession) return; var table = GetEntity(msg.TableUid); @@ -105,7 +104,7 @@ namespace Content.Server.Tabletop protected override void OnTabletopMove(TabletopMoveEvent msg, EntitySessionEventArgs args) { - if (args.SenderSession is not IPlayerSession playerSession) + if (args.SenderSession is not { } playerSession) return; if (!TryComp(GetEntity(msg.TableUid), out TabletopGameComponent? tabletop) || tabletop.Session is not { } session) @@ -155,7 +154,7 @@ namespace Content.Server.Tabletop private void OnStopPlaying(TabletopStopPlayingEvent msg, EntitySessionEventArgs args) { - CloseSessionFor((IPlayerSession)args.SenderSession, GetEntity(msg.TableUid)); + CloseSessionFor(args.SenderSession, GetEntity(msg.TableUid)); } private void OnPlayerDetached(EntityUid uid, TabletopGamerComponent component, PlayerDetachedEvent args) diff --git a/Content.Server/Toolshed/Commands/AdminDebug/ACmdCommand.cs b/Content.Server/Toolshed/Commands/AdminDebug/ACmdCommand.cs index d2b3cc261c..f113e49655 100644 --- a/Content.Server/Toolshed/Commands/AdminDebug/ACmdCommand.cs +++ b/Content.Server/Toolshed/Commands/AdminDebug/ACmdCommand.cs @@ -1,7 +1,7 @@ using Content.Server.Administration; using Content.Server.Administration.Managers; using Content.Shared.Administration; -using Robust.Server.Player; +using Robust.Shared.Player; using Robust.Shared.Toolshed; using Robust.Shared.Toolshed.Syntax; @@ -25,7 +25,7 @@ public sealed class ACmdCommand : ToolshedCommand public bool CanInvoke( [CommandInvocationContext] IInvocationContext ctx, [PipedArgument] CommandSpec command, - [CommandArgument] ValueRef player + [CommandArgument] ValueRef player ) { // Deliberately discard the error. diff --git a/Content.Server/Toolshed/Commands/VisualizeCommand.cs b/Content.Server/Toolshed/Commands/VisualizeCommand.cs index 4ef08a91bf..2225bfaf44 100644 --- a/Content.Server/Toolshed/Commands/VisualizeCommand.cs +++ b/Content.Server/Toolshed/Commands/VisualizeCommand.cs @@ -4,7 +4,6 @@ using Content.Server.EUI; using Content.Shared.Administration; using Content.Shared.Bql; using Content.Shared.Eui; -using Robust.Server.Player; using Robust.Shared.Toolshed; using Robust.Shared.Toolshed.Errors; @@ -30,7 +29,7 @@ public sealed class VisualizeCommand : ToolshedCommand var ui = new ToolshedVisualizeEui( input.Select(e => (EntName(e), EntityManager.GetNetEntity(e))).ToArray() ); - _euiManager.OpenEui(ui, (IPlayerSession) ctx.Session); + _euiManager.OpenEui(ui, ctx.Session); _euiManager.QueueStateUpdate(ui); } } diff --git a/Content.Server/Traitor/Uplink/Commands/AddUplinkCommand.cs b/Content.Server/Traitor/Uplink/Commands/AddUplinkCommand.cs index 1feab11b99..fd656a9f71 100644 --- a/Content.Server/Traitor/Uplink/Commands/AddUplinkCommand.cs +++ b/Content.Server/Traitor/Uplink/Commands/AddUplinkCommand.cs @@ -5,6 +5,7 @@ using Content.Shared.FixedPoint; using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Console; +using Robust.Shared.Player; namespace Content.Server.Traitor.Uplink.Commands { @@ -36,7 +37,7 @@ namespace Content.Server.Traitor.Uplink.Commands return; } - IPlayerSession? session; + ICommonSession? session; if (args.Length > 0) { // Get player entity @@ -48,7 +49,7 @@ namespace Content.Server.Traitor.Uplink.Commands } else { - session = (IPlayerSession?) shell.Player; + session = shell.Player; } if (session?.AttachedEntity is not { } user) diff --git a/Content.Server/UserInterface/ActivatableUIComponent.cs b/Content.Server/UserInterface/ActivatableUIComponent.cs index bb020608e2..34f9c0f397 100644 --- a/Content.Server/UserInterface/ActivatableUIComponent.cs +++ b/Content.Server/UserInterface/ActivatableUIComponent.cs @@ -1,4 +1,4 @@ -using Robust.Server.Player; +using Robust.Shared.Player; using Robust.Shared.Reflection; using Robust.Shared.Serialization; @@ -65,7 +65,7 @@ namespace Content.Server.UserInterface /// NOTE: DO NOT DIRECTLY SET, USE ActivatableUISystem.SetCurrentSingleUser /// [ViewVariables] - public IPlayerSession? CurrentSingleUser; + public ICommonSession? CurrentSingleUser; void ISerializationHooks.AfterDeserialization() { diff --git a/Content.Server/UserInterface/ActivatableUISystem.cs b/Content.Server/UserInterface/ActivatableUISystem.cs index 59086415b4..adeeed7c19 100644 --- a/Content.Server/UserInterface/ActivatableUISystem.cs +++ b/Content.Server/UserInterface/ActivatableUISystem.cs @@ -8,7 +8,7 @@ using Content.Shared.Interaction.Events; using Content.Shared.UserInterface; using Content.Shared.Verbs; using Robust.Server.GameObjects; -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.UserInterface; @@ -173,7 +173,7 @@ public sealed partial class ActivatableUISystem : EntitySystem return true; } - public void SetCurrentSingleUser(EntityUid uid, IPlayerSession? v, ActivatableUIComponent? aui = null) + public void SetCurrentSingleUser(EntityUid uid, ICommonSession? v, ActivatableUIComponent? aui = null) { if (!Resolve(uid, ref aui)) return; @@ -231,9 +231,9 @@ public sealed class UserOpenActivatableUIAttemptEvent : CancellableEntityEventAr public sealed class AfterActivatableUIOpenEvent : EntityEventArgs { public EntityUid User { get; } - public readonly IPlayerSession Session; + public readonly ICommonSession Session; - public AfterActivatableUIOpenEvent(EntityUid who, IPlayerSession session) + public AfterActivatableUIOpenEvent(EntityUid who, ICommonSession session) { User = who; Session = session; diff --git a/Content.Server/UserInterface/StatValuesCommand.cs b/Content.Server/UserInterface/StatValuesCommand.cs index b13b596323..fe2ee380fe 100644 --- a/Content.Server/UserInterface/StatValuesCommand.cs +++ b/Content.Server/UserInterface/StatValuesCommand.cs @@ -8,7 +8,6 @@ using Content.Shared.Materials; using Content.Shared.Research.Prototypes; using Content.Shared.UserInterface; using Content.Shared.Weapons.Melee; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Prototypes; @@ -27,7 +26,7 @@ public sealed class StatValuesCommand : IConsoleCommand public string Help => $"{Command} "; public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession pSession) + if (shell.Player is not { } pSession) { shell.WriteError(Loc.GetString("stat-values-server")); return; diff --git a/Content.Server/Verbs/VerbSystem.cs b/Content.Server/Verbs/VerbSystem.cs index 6d12b08e86..e304c6b4af 100644 --- a/Content.Server/Verbs/VerbSystem.cs +++ b/Content.Server/Verbs/VerbSystem.cs @@ -6,7 +6,6 @@ using Content.Shared.Administration.Logs; using Content.Shared.Database; using Content.Shared.Hands.Components; using Content.Shared.Verbs; -using Robust.Server.Player; namespace Content.Server.Verbs { @@ -25,7 +24,7 @@ namespace Content.Server.Verbs private void HandleVerbRequest(RequestServerVerbsEvent args, EntitySessionEventArgs eventArgs) { - var player = (IPlayerSession) eventArgs.SenderSession; + var player = eventArgs.SenderSession; if (!EntityManager.EntityExists(GetEntity(args.EntityUid))) { @@ -43,7 +42,7 @@ namespace Content.Server.Verbs // this, and some verbs (e.g. view variables) won't even care about whether an entity is accessible through // the entity menu or not. - var force = args.AdminRequest && eventArgs.SenderSession is IPlayerSession playerSession && + var force = args.AdminRequest && eventArgs.SenderSession is { } playerSession && _adminMgr.HasAdminFlag(playerSession, AdminFlags.Admin); List verbTypes = new(); diff --git a/Content.Server/Voting/IVoteHandle.cs b/Content.Server/Voting/IVoteHandle.cs index 13f64e6ef8..869f2017d7 100644 --- a/Content.Server/Voting/IVoteHandle.cs +++ b/Content.Server/Voting/IVoteHandle.cs @@ -1,5 +1,5 @@ using Content.Server.Voting.Managers; -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Voting { @@ -75,7 +75,7 @@ namespace Content.Server.Voting /// /// is not a valid option ID. /// - void CastVote(IPlayerSession session, int? optionId); + void CastVote(ICommonSession session, int? optionId); /// /// Cancel this vote. diff --git a/Content.Server/Voting/Managers/IVoteManager.cs b/Content.Server/Voting/Managers/IVoteManager.cs index 6a92e70fff..d95fac9ae9 100644 --- a/Content.Server/Voting/Managers/IVoteManager.cs +++ b/Content.Server/Voting/Managers/IVoteManager.cs @@ -1,6 +1,6 @@ using System.Diagnostics.CodeAnalysis; using Content.Shared.Voting; -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Voting.Managers { @@ -41,7 +41,7 @@ namespace Content.Server.Voting.Managers /// True if can start votes right now, /// and if provided if they can start votes of type . /// - bool CanCallVote(IPlayerSession initiator, StandardVoteType? voteType = null); + bool CanCallVote(ICommonSession initiator, StandardVoteType? voteType = null); /// /// Initiate a standard vote such as restart round, that can be initiated by players. @@ -51,7 +51,7 @@ namespace Content.Server.Voting.Managers /// If null it is assumed to be an automatic vote by the server. /// /// The type of standard vote to make. - void CreateStandardVote(IPlayerSession? initiator, StandardVoteType voteType); + void CreateStandardVote(ICommonSession? initiator, StandardVoteType voteType); /// /// Create a non-standard vote with special parameters. diff --git a/Content.Server/Voting/Managers/VoteManager.DefaultVotes.cs b/Content.Server/Voting/Managers/VoteManager.DefaultVotes.cs index 55e88e2a8c..e1bffa769d 100644 --- a/Content.Server/Voting/Managers/VoteManager.DefaultVotes.cs +++ b/Content.Server/Voting/Managers/VoteManager.DefaultVotes.cs @@ -6,8 +6,8 @@ using Content.Server.RoundEnd; using Content.Shared.CCVar; using Content.Shared.Database; using Content.Shared.Voting; -using Robust.Server.Player; using Robust.Shared.Configuration; +using Robust.Shared.Player; using Robust.Shared.Random; namespace Content.Server.Voting.Managers @@ -21,7 +21,7 @@ namespace Content.Server.Voting.Managers {StandardVoteType.Map, CCVars.VoteMapEnabled}, }; - public void CreateStandardVote(IPlayerSession? initiator, StandardVoteType voteType) + public void CreateStandardVote(ICommonSession? initiator, StandardVoteType voteType) { if (initiator != null) _adminLogger.Add(LogType.Vote, LogImpact.Medium, $"{initiator} initiated a {voteType.ToString()} vote"); @@ -47,7 +47,7 @@ namespace Content.Server.Voting.Managers TimeoutStandardVote(voteType); } - private void CreateRestartVote(IPlayerSession? initiator) + private void CreateRestartVote(ICommonSession? initiator) { var alone = _playerManager.PlayerCount == 1 && initiator != null; var options = new VoteOptions @@ -100,7 +100,7 @@ namespace Content.Server.Voting.Managers vote.CastVote(initiator, 0); } - foreach (var player in _playerManager.ServerSessions) + foreach (var player in _playerManager.Sessions) { if (player != initiator) { @@ -110,7 +110,7 @@ namespace Content.Server.Voting.Managers } } - private void CreatePresetVote(IPlayerSession? initiator) + private void CreatePresetVote(ICommonSession? initiator) { var presets = GetGamePresets(); @@ -156,7 +156,7 @@ namespace Content.Server.Voting.Managers }; } - private void CreateMapVote(IPlayerSession? initiator) + private void CreateMapVote(ICommonSession? initiator) { var maps = _gameMapManager.CurrentlyEligibleMaps().ToDictionary(map => map, map => map.MapName); diff --git a/Content.Server/Voting/Managers/VoteManager.cs b/Content.Server/Voting/Managers/VoteManager.cs index 98ad8d8341..90089afb54 100644 --- a/Content.Server/Voting/Managers/VoteManager.cs +++ b/Content.Server/Voting/Managers/VoteManager.cs @@ -16,6 +16,7 @@ using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -45,7 +46,7 @@ namespace Content.Server.Voting.Managers private readonly Dictionary _standardVoteTimeout = new(); private readonly Dictionary _voteTimeout = new(); - private readonly HashSet _playerCanCallVoteDirty = new(); + private readonly HashSet _playerCanCallVoteDirty = new(); private readonly StandardVoteType[] _standardVoteTypeValues = Enum.GetValues(); public void Initialize() @@ -106,7 +107,7 @@ namespace Content.Server.Voting.Managers } } - private void CastVote(VoteReg v, IPlayerSession player, int? option) + private void CastVote(VoteReg v, ICommonSession player, int? option) { if (!IsValidOption(v, option)) throw new ArgumentOutOfRangeException(nameof(option), "Invalid vote option ID"); @@ -228,7 +229,7 @@ namespace Content.Server.Voting.Managers private void SendUpdates(VoteReg v) { - foreach (var player in _playerManager.ServerSessions) + foreach (var player in _playerManager.Sessions) { SendSingleUpdate(v, player); } @@ -237,7 +238,7 @@ namespace Content.Server.Voting.Managers v.Dirty = false; } - private void SendSingleUpdate(VoteReg v, IPlayerSession player) + private void SendSingleUpdate(VoteReg v, ICommonSession player) { var msg = new MsgVoteData(); @@ -277,10 +278,10 @@ namespace Content.Server.Voting.Managers private void DirtyCanCallVoteAll() { - _playerCanCallVoteDirty.UnionWith(_playerManager.ServerSessions); + _playerCanCallVoteDirty.UnionWith(_playerManager.Sessions); } - private void SendUpdateCanCallVote(IPlayerSession player) + private void SendUpdateCanCallVote(ICommonSession player) { var msg = new MsgVoteCanCall(); msg.CanCall = CanCallVote(player, null, out var isAdmin, out var timeSpan); @@ -306,7 +307,7 @@ namespace Content.Server.Voting.Managers } private bool CanCallVote( - IPlayerSession initiator, + ICommonSession initiator, StandardVoteType? voteType, out bool isAdmin, out TimeSpan timeSpan) @@ -353,7 +354,7 @@ namespace Content.Server.Voting.Managers return !_voteTimeout.TryGetValue(initiator.UserId, out timeSpan); } - public bool CanCallVote(IPlayerSession initiator, StandardVoteType? voteType = null) + public bool CanCallVote(ICommonSession initiator, StandardVoteType? voteType = null) { return CanCallVote(initiator, voteType, out _, out _); } @@ -406,14 +407,14 @@ namespace Content.Server.Voting.Managers return false; } - private void DirtyCanCallVote(IPlayerSession player) + private void DirtyCanCallVote(ICommonSession player) { _playerCanCallVoteDirty.Add(player); } #region Preset Votes - private void WirePresetVoteInitiator(VoteOptions options, IPlayerSession? player) + private void WirePresetVoteInitiator(VoteOptions options, ICommonSession? player) { if (player != null) { @@ -432,13 +433,13 @@ namespace Content.Server.Voting.Managers private sealed class VoteReg { public readonly int Id; - public readonly Dictionary CastVotes = new(); + public readonly Dictionary CastVotes = new(); public readonly VoteEntry[] Entries; public readonly string Title; public readonly string InitiatorText; public readonly TimeSpan StartTime; public readonly TimeSpan EndTime; - public readonly HashSet VotesDirty = new(); + public readonly HashSet VotesDirty = new(); public bool Cancelled; public bool Finished; @@ -446,10 +447,10 @@ namespace Content.Server.Voting.Managers public VoteFinishedEventHandler? OnFinished; public VoteCancelledEventHandler? OnCancelled; - public IPlayerSession? Initiator { get; } + public ICommonSession? Initiator { get; } public VoteReg(int id, VoteEntry[] entries, string title, string initiatorText, - IPlayerSession? initiator, TimeSpan start, TimeSpan end) + ICommonSession? initiator, TimeSpan start, TimeSpan end) { Id = id; Entries = entries; @@ -517,7 +518,7 @@ namespace Content.Server.Voting.Managers return _mgr.IsValidOption(_reg, optionId); } - public void CastVote(IPlayerSession session, int? optionId) + public void CastVote(ICommonSession session, int? optionId) { _mgr.CastVote(_reg, session, optionId); } diff --git a/Content.Server/Voting/VoteCommands.cs b/Content.Server/Voting/VoteCommands.cs index cb296a7d58..498c9d0494 100644 --- a/Content.Server/Voting/VoteCommands.cs +++ b/Content.Server/Voting/VoteCommands.cs @@ -6,7 +6,6 @@ using Content.Server.Voting.Managers; using Content.Shared.Administration; using Content.Shared.Database; using Content.Shared.Voting; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Voting @@ -36,14 +35,14 @@ namespace Content.Server.Voting var mgr = IoCManager.Resolve(); - if (shell.Player != null && !mgr.CanCallVote((IPlayerSession) shell.Player, type)) + if (shell.Player != null && !mgr.CanCallVote(shell.Player, type)) { _adminLogger.Add(LogType.Vote, LogImpact.Medium, $"{shell.Player} failed to start {type.ToString()} vote"); shell.WriteError(Loc.GetString("cmd-createvote-cannot-call-vote-now")); return; } - mgr.CreateStandardVote((IPlayerSession?) shell.Player, type); + mgr.CreateStandardVote(shell.Player, type); } public CompletionResult GetCompletion(IConsoleShell shell, string[] args) @@ -92,7 +91,7 @@ namespace Content.Server.Voting options.Options.Add((args[i], i)); } - options.SetInitiatorOrServer((IPlayerSession?) shell.Player); + options.SetInitiatorOrServer(shell.Player); if (shell.Player != null) _adminLogger.Add(LogType.Vote, LogImpact.Medium, $"{shell.Player} initiated a custom vote: {options.Title} - {string.Join("; ", options.Options.Select(x => x.text))}"); @@ -187,7 +186,7 @@ namespace Content.Server.Voting return; } - vote.CastVote((IPlayerSession) shell.Player!, optionN); + vote.CastVote(shell.Player!, optionN); } } diff --git a/Content.Server/Voting/VoteOptions.cs b/Content.Server/Voting/VoteOptions.cs index 6e6d0465ed..5475d10d32 100644 --- a/Content.Server/Voting/VoteOptions.cs +++ b/Content.Server/Voting/VoteOptions.cs @@ -1,4 +1,4 @@ -using Robust.Server.Player; +using Robust.Shared.Player; namespace Content.Server.Voting @@ -16,7 +16,7 @@ namespace Content.Server.Voting /// /// The player that started the vote. Used to keep track of player cooldowns to avoid vote spam. /// - public IPlayerSession? InitiatorPlayer { get; set; } + public ICommonSession? InitiatorPlayer { get; set; } /// /// The shown title of the vote. @@ -43,13 +43,13 @@ namespace Content.Server.Voting /// Sets and /// by setting the latter to the player's name. /// - public void SetInitiator(IPlayerSession player) + public void SetInitiator(ICommonSession player) { InitiatorPlayer = player; InitiatorText = player.Name; } - public void SetInitiatorOrServer(IPlayerSession? player) + public void SetInitiatorOrServer(ICommonSession? player) { if (player != null) { diff --git a/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs b/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs index 1b6b2ebef1..3d9c3e8219 100644 --- a/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs +++ b/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs @@ -24,11 +24,9 @@ using Content.Shared.StatusEffect; using Content.Shared.Tag; using Content.Shared.Weapons.Melee; using Content.Shared.Weapons.Melee.Events; -using Robust.Server.Player; using Robust.Shared.Audio; using Robust.Shared.Map; using Robust.Shared.Player; -using Robust.Shared.Players; using Robust.Shared.Random; namespace Content.Server.Weapons.Melee; @@ -174,7 +172,7 @@ public sealed class MeleeWeaponSystem : SharedMeleeWeaponSystem EntityCoordinates targetCoordinates; Angle targetLocalAngle; - if (session is IPlayerSession pSession) + if (session is { } pSession) { (targetCoordinates, targetLocalAngle) = _lag.GetCoordinatesAngle(target, pSession); } diff --git a/Content.Server/Wires/WiresSystem.cs b/Content.Server/Wires/WiresSystem.cs index e75ad0a9ef..b6452efa8a 100644 --- a/Content.Server/Wires/WiresSystem.cs +++ b/Content.Server/Wires/WiresSystem.cs @@ -16,7 +16,7 @@ using Content.Shared.Tools; using Content.Shared.Tools.Components; using Content.Shared.Wires; using Robust.Server.GameObjects; -using Robust.Server.Player; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; @@ -616,7 +616,7 @@ public sealed class WiresSystem : SharedWiresSystem wires.WireSeed), ui: ui); } - public void OpenUserInterface(EntityUid uid, IPlayerSession player) + public void OpenUserInterface(EntityUid uid, ICommonSession player) { if (_uiSystem.TryGetUi(uid, WiresUiKey.Key, out var ui)) _uiSystem.OpenUi(ui, player); diff --git a/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs b/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs index 49036fb19d..9200928d66 100644 --- a/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs +++ b/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs @@ -17,7 +17,6 @@ using Content.Shared.Xenoarchaeology.Equipment; using Content.Shared.Xenoarchaeology.XenoArtifacts; using JetBrains.Annotations; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Audio; using Robust.Shared.Prototypes; using Robust.Shared.Timing; @@ -229,7 +228,7 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem /// private void OnServerSelectionMessage(EntityUid uid, AnalysisConsoleComponent component, AnalysisConsoleServerSelectionMessage args) { - _ui.TryOpen(uid, ResearchClientUiKey.Key, (IPlayerSession) args.Session); + _ui.TryOpen(uid, ResearchClientUiKey.Key, args.Session); } /// diff --git a/Content.Shared/Administration/Managers/ISharedAdminManager.cs b/Content.Shared/Administration/Managers/ISharedAdminManager.cs index 7e01c81433..22d918d4a3 100644 --- a/Content.Shared/Administration/Managers/ISharedAdminManager.cs +++ b/Content.Shared/Administration/Managers/ISharedAdminManager.cs @@ -1,4 +1,4 @@ -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Shared.Administration.Managers; diff --git a/Content.Shared/Buckle/SharedBuckleSystem.cs b/Content.Shared/Buckle/SharedBuckleSystem.cs index 7edf2448ae..1441745b5d 100644 --- a/Content.Shared/Buckle/SharedBuckleSystem.cs +++ b/Content.Shared/Buckle/SharedBuckleSystem.cs @@ -11,7 +11,7 @@ using Robust.Shared.Containers; using Robust.Shared.Map; using Robust.Shared.Network; using Robust.Shared.Physics.Systems; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Shared.Buckle; diff --git a/Content.Shared/Hands/EntitySystems/SharedHandsSystem.Interactions.cs b/Content.Shared/Hands/EntitySystems/SharedHandsSystem.Interactions.cs index d0c3be3b31..dfa72fcfb7 100644 --- a/Content.Shared/Hands/EntitySystems/SharedHandsSystem.Interactions.cs +++ b/Content.Shared/Hands/EntitySystems/SharedHandsSystem.Interactions.cs @@ -6,7 +6,7 @@ using Content.Shared.Input; using Content.Shared.Localizations; using Robust.Shared.Input.Binding; using Robust.Shared.Map; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Shared.Hands.EntitySystems; diff --git a/Content.Shared/Interaction/SharedInteractionSystem.cs b/Content.Shared/Interaction/SharedInteractionSystem.cs index 4a9a43ca2c..7981deaee6 100644 --- a/Content.Shared/Interaction/SharedInteractionSystem.cs +++ b/Content.Shared/Interaction/SharedInteractionSystem.cs @@ -34,7 +34,7 @@ using Robust.Shared.Network; using Robust.Shared.Physics; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Random; using Robust.Shared.Serialization; using Robust.Shared.Timing; diff --git a/Content.Shared/Mind/MindComponent.cs b/Content.Shared/Mind/MindComponent.cs index 465db6a3d8..b147a2dbbe 100644 --- a/Content.Shared/Mind/MindComponent.cs +++ b/Content.Shared/Mind/MindComponent.cs @@ -2,7 +2,7 @@ using Content.Shared.Mind.Components; using Robust.Shared.GameStates; using Robust.Shared.Network; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Shared.Mind { diff --git a/Content.Shared/Mind/SharedMindSystem.cs b/Content.Shared/Mind/SharedMindSystem.cs index 9f5c51ac6e..8e72d9c741 100644 --- a/Content.Shared/Mind/SharedMindSystem.cs +++ b/Content.Shared/Mind/SharedMindSystem.cs @@ -13,7 +13,7 @@ using Content.Shared.Objectives.Systems; using Content.Shared.Players; using Robust.Shared.Map; using Robust.Shared.Network; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Shared.Mind; @@ -410,11 +410,11 @@ public abstract class SharedMindSystem : EntitySystem } public bool TryGetMind( - PlayerData player, + ContentPlayerData contentPlayer, out EntityUid mindId, [NotNullWhen(true)] out MindComponent? mind) { - mindId = player.Mind ?? default; + mindId = contentPlayer.Mind ?? default; return TryComp(mindId, out mind); } diff --git a/Content.Shared/Movement/Events/MoveInputEvent.cs b/Content.Shared/Movement/Events/MoveInputEvent.cs index 8e1b43f8bd..89e5636acd 100644 --- a/Content.Shared/Movement/Events/MoveInputEvent.cs +++ b/Content.Shared/Movement/Events/MoveInputEvent.cs @@ -1,5 +1,3 @@ -using Robust.Shared.Players; - namespace Content.Shared.Movement.Events; /// diff --git a/Content.Shared/Movement/Systems/SharedContentEyeSystem.cs b/Content.Shared/Movement/Systems/SharedContentEyeSystem.cs index 27e0080c87..4b81619fd0 100644 --- a/Content.Shared/Movement/Systems/SharedContentEyeSystem.cs +++ b/Content.Shared/Movement/Systems/SharedContentEyeSystem.cs @@ -5,7 +5,7 @@ using Content.Shared.Ghost; using Content.Shared.Input; using Content.Shared.Movement.Components; using Robust.Shared.Input.Binding; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Serialization; namespace Content.Shared.Movement.Systems; diff --git a/Content.Shared/Movement/Systems/SharedMoverController.Input.cs b/Content.Shared/Movement/Systems/SharedMoverController.Input.cs index 425322408e..1d323a9187 100644 --- a/Content.Shared/Movement/Systems/SharedMoverController.Input.cs +++ b/Content.Shared/Movement/Systems/SharedMoverController.Input.cs @@ -6,7 +6,7 @@ using Content.Shared.Movement.Components; using Content.Shared.Movement.Events; using Robust.Shared.Input; using Robust.Shared.Input.Binding; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Serialization; using Robust.Shared.Timing; using Robust.Shared.Utility; diff --git a/Content.Shared/Players/PlayerData.cs b/Content.Shared/Players/ContentPlayerData.cs similarity index 73% rename from Content.Shared/Players/PlayerData.cs rename to Content.Shared/Players/ContentPlayerData.cs index c6274c950b..7545eb58fc 100644 --- a/Content.Shared/Players/PlayerData.cs +++ b/Content.Shared/Players/ContentPlayerData.cs @@ -1,16 +1,15 @@ using Content.Shared.GameTicking; using Content.Shared.Mind; using Robust.Shared.Network; -using Robust.Shared.Player; namespace Content.Shared.Players; /// /// Content side for all data that tracks a player session. -/// Use to retrieve this from an . +/// Use to retrieve this from an . /// Not currently used on the client. /// -public sealed class PlayerData +public sealed class ContentPlayerData { /// /// The session ID of the player owning this data. @@ -38,21 +37,9 @@ public sealed class PlayerData /// public bool ExplicitlyDeadminned { get; set; } - public PlayerData(NetUserId userId, string name) + public ContentPlayerData(NetUserId userId, string name) { UserId = userId; Name = name; } -} - - -public static class PlayerDataExt -{ - /// - /// Gets the correctly cast instance of content player data from an engine player data storage. - /// - public static PlayerData? ContentData(this IPlayerData data) - { - return (PlayerData?) data.ContentDataUncast; - } -} +} \ No newline at end of file diff --git a/Content.Shared/Players/PlayerDataExt.cs b/Content.Shared/Players/PlayerDataExt.cs new file mode 100644 index 0000000000..eba4d8339d --- /dev/null +++ b/Content.Shared/Players/PlayerDataExt.cs @@ -0,0 +1,30 @@ +using Robust.Shared.Player; + +namespace Content.Shared.Players; + +public static class PlayerDataExt +{ + /// + /// Gets the correctly cast instance of content player data from an engine player data storage. + /// + public static ContentPlayerData? ContentData(this SessionData data) + { + return (ContentPlayerData?) data.ContentDataUncast; + } + + /// + /// Gets the correctly cast instance of content player data from an engine player data storage. + /// + public static ContentPlayerData? ContentData(this ICommonSession session) + { + return session.Data.ContentData(); + } + + /// + /// Gets the mind that is associated with this player. + /// + public static EntityUid? GetMind(this ICommonSession session) + { + return session.Data.ContentData()?.Mind; + } +} \ No newline at end of file diff --git a/Content.Shared/Players/SharedPlayerSystem.cs b/Content.Shared/Players/SharedPlayerSystem.cs index 6fc7ad6a40..7271c5688a 100644 --- a/Content.Shared/Players/SharedPlayerSystem.cs +++ b/Content.Shared/Players/SharedPlayerSystem.cs @@ -1,4 +1,4 @@ -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Shared.Players; @@ -8,5 +8,5 @@ namespace Content.Shared.Players; /// public abstract class SharedPlayerSystem : EntitySystem { - public abstract PlayerData? ContentData(ICommonSession? session); + public abstract ContentPlayerData? ContentData(ICommonSession? session); } diff --git a/Content.Shared/Popups/SharedPopupSystem.cs b/Content.Shared/Popups/SharedPopupSystem.cs index 50013a5435..e4565b90e8 100644 --- a/Content.Shared/Popups/SharedPopupSystem.cs +++ b/Content.Shared/Popups/SharedPopupSystem.cs @@ -1,6 +1,5 @@ using Robust.Shared.Map; using Robust.Shared.Player; -using Robust.Shared.Players; using Robust.Shared.Serialization; namespace Content.Shared.Popups diff --git a/Content.Shared/Pulling/Systems/SharedPullingSystem.cs b/Content.Shared/Pulling/Systems/SharedPullingSystem.cs index 6f19d048b4..0c139ee9e3 100644 --- a/Content.Shared/Pulling/Systems/SharedPullingSystem.cs +++ b/Content.Shared/Pulling/Systems/SharedPullingSystem.cs @@ -12,7 +12,7 @@ using Robust.Shared.Map; using Robust.Shared.Physics; using Robust.Shared.Physics.Events; using Robust.Shared.Physics.Systems; -using Robust.Shared.Players; +using Robust.Shared.Player; namespace Content.Shared.Pulling { diff --git a/Content.Shared/Roles/Jobs/SharedJobSystem.cs b/Content.Shared/Roles/Jobs/SharedJobSystem.cs index ac18d04e9c..af97ea1350 100644 --- a/Content.Shared/Roles/Jobs/SharedJobSystem.cs +++ b/Content.Shared/Roles/Jobs/SharedJobSystem.cs @@ -2,7 +2,7 @@ using System.Linq; using Content.Shared.Players; using Content.Shared.Players.PlayTimeTracking; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Utility; diff --git a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs index 4b740b8d3c..62af6067d0 100644 --- a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs +++ b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs @@ -23,7 +23,7 @@ using Robust.Shared.Audio; using Robust.Shared.Map; using Robust.Shared.Physics; using Robust.Shared.Physics.Systems; -using Robust.Shared.Players; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Timing; From 761b2f3da2ae5f0d3366e28f3bf9f2a1aa47f1e0 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Sat, 28 Oct 2023 10:01:24 +1100 Subject: [PATCH 082/102] Update engine to v172.0.0 (#21288) --- RobustToolbox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RobustToolbox b/RobustToolbox index 554e0777b1..9750b113c8 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit 554e0777b1ba6ba096d8f4407d5c35ecc7b0f22f +Subproject commit 9750b113c81e7535d892326568760bc976072436 From ecec22faae6627915cb7d87216959a48fc0dab64 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Sat, 28 Oct 2023 11:43:15 +1100 Subject: [PATCH 083/102] Bandaid tests (#21292) --- Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml b/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml index 7c330a9a76..eb281c6529 100644 --- a/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml +++ b/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml @@ -21,7 +21,7 @@ components: - type: StorageFill contents: - - id: BoxSurvivalEngineering + #- id: BoxSurvivalEngineering - id: WeaponShotgunDoubleBarreled - id: BoxShotgunIncendiary amount: 2 From a9fc97a901cb75cdcf17d4eecd0f9ef5caf4a529 Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Sat, 28 Oct 2023 05:27:09 +0300 Subject: [PATCH 084/102] rename the rocks (#21275) --- Resources/Locale/en-US/tiles/tiles.ftl | 1 + .../Entities/Objects/Decoration/flora.yml | 31 ++++++------------- .../Entities/Structures/Walls/asteroid.yml | 5 +++ 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/Resources/Locale/en-US/tiles/tiles.ftl b/Resources/Locale/en-US/tiles/tiles.ftl index 219c7295d9..508c3378e1 100644 --- a/Resources/Locale/en-US/tiles/tiles.ftl +++ b/Resources/Locale/en-US/tiles/tiles.ftl @@ -110,3 +110,4 @@ tiles-wood3 = wood broken floor tiles-hull = exterior hull plating tiles-hull-reinforced = exterior reinforced hull plating tiles-web = web tile +tiles-chromite = chromite \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Objects/Decoration/flora.yml b/Resources/Prototypes/Entities/Objects/Decoration/flora.yml index 8c6a87b563..97368a21bd 100644 --- a/Resources/Prototypes/Entities/Objects/Decoration/flora.yml +++ b/Resources/Prototypes/Entities/Objects/Decoration/flora.yml @@ -1,5 +1,6 @@ - type: entity id: BaseRock + name: boulder description: Heavy as a really heavy thing. abstract: true components: @@ -32,7 +33,6 @@ - !type:DoActsBehavior acts: [ "Destruction" ] - - type: entity id: BaseTree description: Yep, it's a tree. @@ -149,7 +149,6 @@ - type: entity parent: BaseRock id: FloraRockSolid01 - name: rock components: - type: Sprite state: rocksolid01 @@ -157,7 +156,6 @@ - type: entity parent: BaseRock id: FloraRockSolid02 - name: rock components: - type: Sprite state: rocksolid02 @@ -165,60 +163,55 @@ - type: entity parent: BaseRock id: FloraRockSolid03 - name: rock components: - type: Sprite state: rocksolid03 - type: entity + name: stalagmite + description: Natural stone spikes. parent: BaseRock id: FloraStalagmite1 - name: rock components: - type: Sprite sprite: Objects/Decoration/Flora/flora_stalagmite.rsi state: stalagmite1 - type: entity - parent: BaseRock + parent: FloraStalagmite1 id: FloraStalagmite2 - name: rock components: - type: Sprite sprite: Objects/Decoration/Flora/flora_stalagmite.rsi state: stalagmite2 - type: entity - parent: BaseRock + parent: FloraStalagmite1 id: FloraStalagmite3 - name: rock components: - type: Sprite sprite: Objects/Decoration/Flora/flora_stalagmite.rsi state: stalagmite3 - type: entity - parent: BaseRock + parent: FloraStalagmite1 id: FloraStalagmite4 - name: rock components: - type: Sprite sprite: Objects/Decoration/Flora/flora_stalagmite.rsi state: stalagmite4 - type: entity - parent: BaseRock + parent: FloraStalagmite1 id: FloraStalagmite5 - name: rock components: - type: Sprite sprite: Objects/Decoration/Flora/flora_stalagmite.rsi state: stalagmite5 - type: entity - parent: BaseRock + parent: FloraStalagmite1 id: FloraStalagmite6 - name: rock components: - type: Sprite sprite: Objects/Decoration/Flora/flora_stalagmite.rsi @@ -450,7 +443,8 @@ - type: entity parent: FloraTree01 id: ShadowTree01 - name: tree + name: dark wood + description: The leaves are whispering about you. components: - type: Sprite sprite: Objects/Decoration/Flora/flora_shadow_trees.rsi @@ -459,7 +453,6 @@ - type: entity parent: ShadowTree01 id: ShadowTree02 - name: tree components: - type: Sprite state: tree02 @@ -467,7 +460,6 @@ - type: entity parent: ShadowTree01 id: ShadowTree03 - name: tree components: - type: Sprite state: tree03 @@ -475,7 +467,6 @@ - type: entity parent: ShadowTree01 id: ShadowTree04 - name: tree components: - type: Sprite state: tree04 @@ -483,7 +474,6 @@ - type: entity parent: ShadowTree01 id: ShadowTree05 - name: tree components: - type: Sprite state: tree05 @@ -491,7 +481,6 @@ - type: entity parent: ShadowTree01 id: ShadowTree06 - name: tree components: - type: Sprite state: tree06 diff --git a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml index 9d5ff1b473..ac12dc2717 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml @@ -379,6 +379,7 @@ # Basalt variants - type: entity id: WallRockBasalt + name: basalt parent: WallRock components: - type: Sprite @@ -574,6 +575,7 @@ # Snow variants - type: entity id: WallRockSnow + name: snowdrift parent: WallRock components: - type: Sprite @@ -770,6 +772,7 @@ # Sand variants - type: entity id: WallRockSand + name: sandstone parent: WallRock components: - type: Sprite @@ -965,6 +968,7 @@ # Chromite variants - type: entity id: WallRockChromite + name: chromite parent: WallRock components: - type: Sprite @@ -1160,6 +1164,7 @@ # Andesite variants - type: entity id: WallRockAndesite + name: andesite parent: WallRock components: - type: Sprite From 1f59770ac1c92c5f6a12a13d38107c856df9b6c0 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sat, 28 Oct 2023 13:27:16 +1100 Subject: [PATCH 085/102] Make crystals noRot (#21279) IDK might be better. Ideally the anchoring would be offset 0-0 but this is the world we live in atm. --- Resources/Prototypes/Entities/Structures/Decoration/crystals.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Prototypes/Entities/Structures/Decoration/crystals.yml b/Resources/Prototypes/Entities/Structures/Decoration/crystals.yml index b8f2a03a05..4afe06c8a5 100644 --- a/Resources/Prototypes/Entities/Structures/Decoration/crystals.yml +++ b/Resources/Prototypes/Entities/Structures/Decoration/crystals.yml @@ -7,6 +7,7 @@ - type: Sprite sprite: Structures/Decoration/crystal.rsi state: crystal_green + noRot: true - type: Reflect reflectProb: 0.5 reflects: From 59176f7613a233641a074d35bd5e526446be74ab Mon Sep 17 00:00:00 2001 From: faint <46868845+ficcialfaint@users.noreply.github.com> Date: Sat, 28 Oct 2023 05:28:20 +0300 Subject: [PATCH 086/102] Fix nukies sound not played (#21268) * Play sound and sending greeting message works for nukies now!!!!! * oops * silly change --- .../GameTicking/Rules/NukeopsRuleSystem.cs | 23 +++++++++++++------ .../Locale/en-US/administration/antag.ftl | 2 +- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs index 4d3eee81e2..5be6820b97 100644 --- a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs @@ -46,6 +46,7 @@ using Robust.Server.Player; using Robust.Shared.Audio; using Robust.Shared.Map; using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -334,7 +335,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem var eligibleQuery = EntityQueryEnumerator(); while (eligibleQuery.MoveNext(out var eligibleUid, out var eligibleComp, out var member)) { - if (!_npcFaction.IsFactionFriendly(component.Faction, eligibleUid, member)) + if (!_npcFaction.IsFactionHostile(component.Faction, eligibleUid, member)) continue; eligible.Add((eligibleUid, eligibleComp, member)); @@ -349,8 +350,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem var query = EntityQueryEnumerator(); while (query.MoveNext(out _, out var nukeops, out var actor)) { - _chatManager.DispatchServerMessage(actor.PlayerSession, Loc.GetString("nukeops-welcome", ("station", component.TargetStation.Value))); - _audio.PlayGlobal(nukeops.GreetSoundNotification, actor.PlayerSession); + NotifyNukie(actor.PlayerSession, nukeops, component); filter.AddPlayer(actor.PlayerSession); } } @@ -793,10 +793,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem if (nukeops.TargetStation != null && !string.IsNullOrEmpty(Name(nukeops.TargetStation.Value))) { - _chatManager.DispatchServerMessage(playerSession, Loc.GetString("nukeops-welcome", ("station", nukeops.TargetStation.Value))); - - // Notificate player about new role assignment - _audio.PlayGlobal(component.GreetSoundNotification, playerSession); + NotifyNukie(playerSession, component, nukeops); } } } @@ -994,6 +991,18 @@ public sealed class NukeopsRuleSystem : GameRuleSystem SpawnOperatives(numNukies, operatives, true, component); } + /// + /// Display a greeting message and play a sound for a nukie + /// + private void NotifyNukie(ICommonSession session, NukeOperativeComponent nukeop, NukeopsRuleComponent nukeopsRule) + { + if (nukeopsRule.TargetStation is not { } station) + return; + + _chatManager.DispatchServerMessage(session, Loc.GetString("nukeops-welcome", ("station", station))); + _audio.PlayGlobal(nukeop.GreetSoundNotification, session); + } + //For admins forcing someone to nukeOps. public void MakeLoneNukie(EntityUid mindId, MindComponent mind) { diff --git a/Resources/Locale/en-US/administration/antag.ftl b/Resources/Locale/en-US/administration/antag.ftl index 3d098c1c54..f3b3d91945 100644 --- a/Resources/Locale/en-US/administration/antag.ftl +++ b/Resources/Locale/en-US/administration/antag.ftl @@ -1,7 +1,7 @@ verb-categories-antag = Antag ctrl admin-verb-make-traitor = Make the target into a traitor. admin-verb-make-zombie = Zombifies the target immediately. -admin-verb-make-nuclear-operative = Make target a into lone Nuclear Operative. +admin-verb-make-nuclear-operative = Make target into a lone Nuclear Operative. admin-verb-make-pirate = Make the target into a pirate. Note this doesn't configure the game rule. admin-verb-make-head-rev = Make the target into a Head Revolutionary. From 2c7e2b62dc0bdede6e6f3b696572dab6fc35ff42 Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 27 Oct 2023 22:29:28 -0400 Subject: [PATCH 087/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index b91619d209..177b504c43 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: EmoGarbage404 - changes: - - {message: Being turned into a cyborg or zombie now counts as a being dead for - survival and kill objectives., type: Fix} - - {message: Kill objectives no longer reveal a character's true name at all times., - type: Fix} - id: 4571 - time: '2023-08-14T03:34:19.0000000+00:00' - author: EmoGarbage404 changes: - {message: Fixed the RPED sound effect cutting off at the end., type: Fix} @@ -2912,3 +2904,8 @@ Entries: - {message: Updated the localization files., type: Fix} id: 5070 time: '2023-10-27T13:54:43.0000000+00:00' +- author: ficcialfaint + changes: + - {message: Fixed nuclear operatives sound not being played at round start, type: Fix} + id: 5071 + time: '2023-10-28T02:28:21.0000000+00:00' From d27df9705db141edfaa3a03c884b4d241ea61501 Mon Sep 17 00:00:00 2001 From: Morb <14136326+Morb0@users.noreply.github.com> Date: Sat, 28 Oct 2023 05:33:18 +0300 Subject: [PATCH 088/102] Fix hijack objective (#21241) * Fix hijack * Max difficulty --- .../Components/HijackShuttleComponent.cs | 8 -------- .../Components/HijackShuttleConditionComponent.cs | 11 +++++++++++ .../Systems/HijackShuttleConditionSystem.cs | 6 +++--- .../conditions/hijack-shuttle-condition.ftl | 2 -- Resources/Prototypes/Objectives/traitor.yml | 14 ++++++++++++++ 5 files changed, 28 insertions(+), 13 deletions(-) delete mode 100644 Content.Server/Objectives/Components/HijackShuttleComponent.cs create mode 100644 Content.Server/Objectives/Components/HijackShuttleConditionComponent.cs delete mode 100644 Resources/Locale/en-US/objectives/conditions/hijack-shuttle-condition.ftl diff --git a/Content.Server/Objectives/Components/HijackShuttleComponent.cs b/Content.Server/Objectives/Components/HijackShuttleComponent.cs deleted file mode 100644 index 010f6f1407..0000000000 --- a/Content.Server/Objectives/Components/HijackShuttleComponent.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Content.Server.Objectives.Systems; - -namespace Content.Server.Objectives.Components; - -[RegisterComponent, Access(typeof(HijackShuttleConditionSystem))] -public sealed partial class HijackShuttleComponent : Component -{ -} diff --git a/Content.Server/Objectives/Components/HijackShuttleConditionComponent.cs b/Content.Server/Objectives/Components/HijackShuttleConditionComponent.cs new file mode 100644 index 0000000000..2f07086af6 --- /dev/null +++ b/Content.Server/Objectives/Components/HijackShuttleConditionComponent.cs @@ -0,0 +1,11 @@ +using Content.Server.Objectives.Systems; + +namespace Content.Server.Objectives.Components; + +/// +/// Objective condition that requires the player to leave station of escape shuttle with only antags on board or handcuffed humanoids +/// +[RegisterComponent, Access(typeof(HijackShuttleConditionSystem))] +public sealed partial class HijackShuttleConditionComponent : Component +{ +} diff --git a/Content.Server/Objectives/Systems/HijackShuttleConditionSystem.cs b/Content.Server/Objectives/Systems/HijackShuttleConditionSystem.cs index 5ea560297c..9e0d2c3d5b 100644 --- a/Content.Server/Objectives/Systems/HijackShuttleConditionSystem.cs +++ b/Content.Server/Objectives/Systems/HijackShuttleConditionSystem.cs @@ -23,17 +23,17 @@ public sealed class HijackShuttleConditionSystem : EntitySystem { base.Initialize(); - SubscribeLocalEvent(OnGetProgress); + SubscribeLocalEvent(OnGetProgress); } - private void OnGetProgress(EntityUid uid, HijackShuttleComponent comp, ref ObjectiveGetProgressEvent args) + private void OnGetProgress(EntityUid uid, HijackShuttleConditionComponent comp, ref ObjectiveGetProgressEvent args) { args.Progress = GetProgress(args.MindId, args.Mind); } private float GetProgress(EntityUid mindId, MindComponent mind) { - // not escaping alive if you're deleted/dead + // Not escaping alive if you're deleted/dead if (mind.OwnedEntity == null || _mind.IsCharacterDeadIc(mind)) return 0f; diff --git a/Resources/Locale/en-US/objectives/conditions/hijack-shuttle-condition.ftl b/Resources/Locale/en-US/objectives/conditions/hijack-shuttle-condition.ftl deleted file mode 100644 index 5a0c1fd88b..0000000000 --- a/Resources/Locale/en-US/objectives/conditions/hijack-shuttle-condition.ftl +++ /dev/null @@ -1,2 +0,0 @@ -objective-condition-hijack-shuttle-title = Hijack emergency shuttle -objective-condition-hijack-shuttle-description = Leave on the shuttle free and clear of the loyal Nanotrasen crew on board. Use ANY methods available to you. Syndicate agents, Nanotrasen enemies, and handcuffed hostages may remain alive on the shuttle. Ignore assistance from anyone other than a support agent. diff --git a/Resources/Prototypes/Objectives/traitor.yml b/Resources/Prototypes/Objectives/traitor.yml index f0e8daad3d..dd188765b9 100644 --- a/Resources/Prototypes/Objectives/traitor.yml +++ b/Resources/Prototypes/Objectives/traitor.yml @@ -64,6 +64,20 @@ - StealCondition - type: DieCondition +- type: entity + noSpawn: true + parent: [BaseTraitorObjective, BaseLivingObjective] + id: HijackShuttleObjective + name: Hijack emergency shuttle + description: Leave on the shuttle free and clear of the loyal Nanotrasen crew on board. Use ANY methods available to you. Syndicate agents, Nanotrasen enemies, and handcuffed hostages may remain alive on the shuttle. Ignore assistance from anyone other than a support agent. + components: + - type: Objective + difficulty: 5 # insane, default config max difficulty + icon: + sprite: Objects/Tools/emag.rsi + state: icon + - type: HijackShuttleCondition + # kill - type: entity From 0f5bcddd2517c56b4b4d42a9ba5ef4045cfddd21 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Sat, 28 Oct 2023 13:57:57 +1100 Subject: [PATCH 089/102] Remove GridModifiedEvent (#21291) --- Content.Shared/SubFloor/SharedSubFloorHideSystem.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs b/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs index 0fd7a2e932..02b4e61790 100644 --- a/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs +++ b/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs @@ -24,7 +24,6 @@ namespace Content.Shared.SubFloor { base.Initialize(); - SubscribeLocalEvent(OnGridChanged); SubscribeLocalEvent(OnTileChanged); SubscribeLocalEvent(OnSubFloorStarted); SubscribeLocalEvent(OnSubFloorTerminating); @@ -97,14 +96,6 @@ namespace Content.Shared.SubFloor UpdateTile(MapManager.GetGrid(args.NewTile.GridUid), args.NewTile.GridIndices); } - private void OnGridChanged(GridModifiedEvent args) - { - foreach (var modified in args.Modified) - { - UpdateTile(args.Grid, modified.position); - } - } - /// /// Update whether a given entity is currently covered by a floor tile. /// From 40e8eba009a1e3003b1922bc864d17ffaf9cebc4 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sat, 28 Oct 2023 14:07:08 +1100 Subject: [PATCH 090/102] Update submodule to 173.0.0 (#21296) --- RobustToolbox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RobustToolbox b/RobustToolbox index 9750b113c8..7cad8d5ba3 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit 9750b113c81e7535d892326568760bc976072436 +Subproject commit 7cad8d5ba3f252eb1dac862c7f92e792c60b98c1 From 1844ad23a39640144319392af5284c790210da2b Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Sat, 28 Oct 2023 14:24:37 +1100 Subject: [PATCH 091/102] Fix namespace error (#21298) --- Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs index 5be6820b97..779c47885f 100644 --- a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs @@ -46,7 +46,6 @@ using Robust.Server.Player; using Robust.Shared.Audio; using Robust.Shared.Map; using Robust.Shared.Player; -using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; From d13d86201a7ff8756acdce04ea4e7d5034e90328 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Sat, 28 Oct 2023 14:28:57 +1100 Subject: [PATCH 092/102] Update yaml sequence option in editorconfig (#21297) --- .editorconfig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index a8ce1d6b68..59ca35cc9a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -338,5 +338,8 @@ dotnet_naming_symbols.type_parameters_symbols.applicable_kinds = type_parameter resharper_braces_for_ifelse = required_for_multiline resharper_keep_existing_attribute_arrangement = true -[*.{csproj,xml,yml,dll.config,msbuildproj,targets}] +[*.{csproj,xml,yml,yaml,dll.config,msbuildproj,targets}] indent_size = 2 + +[{*.yaml,*.yml}] +ij_yaml_indent_sequence_value = false From 219109cac5ac2822fb7d872b05657c7b6f463fdc Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sat, 28 Oct 2023 14:49:09 +1100 Subject: [PATCH 093/102] Fix namespace (#21299) From e11d33b68db32e10485dda67e866ad7773313591 Mon Sep 17 00:00:00 2001 From: Whisper <121047731+QuietlyWhisper@users.noreply.github.com> Date: Sat, 28 Oct 2023 00:30:59 -0400 Subject: [PATCH 094/102] fix cburn bag issue, make new bag entity for them and filled bag entity (#21295) --- .../Catalog/Fills/Backpacks/duffelbag.yml | 335 +++++++++--------- .../Entities/Clothing/Back/duffel.yml | 150 ++++---- .../Roles/Jobs/Fun/misc_startinggear.yml | 10 +- 3 files changed, 253 insertions(+), 242 deletions(-) diff --git a/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml b/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml index eb281c6529..c97082e351 100644 --- a/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml +++ b/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml @@ -4,32 +4,31 @@ name: surgical duffel bag description: "A large duffel bag for holding extra medical supplies - this one seems to be designed for holding surgical tools." components: - - type: StorageFill - contents: - - id: Hemostat - - id: Saw - - id: Drill - - id: Cautery - - id: Retractor - - id: Scalpel + - type: StorageFill + contents: + - id: Hemostat + - id: Saw + - id: Drill + - id: Cautery + - id: Retractor + - id: Scalpel - type: entity - id: ClothingBackpackDuffelCBURN - parent: ClothingBackpackDuffel - name: CBURN duffel bag - description: A duffel bag containing a variety of biological containment equipment. + id: ClothingBackpackDuffelCBURNFilled + parent: ClothingBackpackDuffelCBURN + suffix: Filled components: - - type: StorageFill - contents: - #- id: BoxSurvivalEngineering - - id: WeaponShotgunDoubleBarreled - - id: BoxShotgunIncendiary - amount: 2 - - id: GrenadeFlashBang - amount: 2 - - id: PillAmbuzolPlus - - id: PillAmbuzol - amount: 4 + - type: StorageFill + contents: + - id: BoxSurvivalEngineering + - id: WeaponShotgunDoubleBarreled + - id: BoxShotgunIncendiary + amount: 2 + - id: GrenadeFlashBang + amount: 2 + - id: PillAmbuzolPlus + - id: PillAmbuzol + amount: 4 - type: entity parent: ClothingBackpackDuffelSyndicateMedicalBundle @@ -37,14 +36,14 @@ name: syndicate surgical duffel bag description: A large duffel bag containing a full suite of surgical tools. components: - - type: StorageFill - contents: - - id: Hemostat - - id: SawAdvanced - - id: Drill - - id: Cautery - - id: Retractor - - id: ScalpelAdvanced + - type: StorageFill + contents: + - id: Hemostat + - id: SawAdvanced + - id: Drill + - id: Cautery + - id: Retractor + - id: ScalpelAdvanced - type: entity parent: ClothingBackpackDuffelSyndicateBundle @@ -52,12 +51,12 @@ name: Bulldog bundle description: "Lean and mean: Contains the popular Bulldog Shotgun, a 12g beanbag drum and 3 12g buckshot drums." #, and a pair of Thermal Imaging Goggles. components: - - type: StorageFill - contents: - - id: WeaponShotgunBulldog - - id: MagazineShotgun - - id: MagazineShotgun - - id: MagazineShotgunBeanbag + - type: StorageFill + contents: + - id: WeaponShotgunBulldog + - id: MagazineShotgun + - id: MagazineShotgun + - id: MagazineShotgunBeanbag # - id: ThermalImagingGoggles - type: entity @@ -66,11 +65,11 @@ name: C-20r bundle description: "Old faithful: The classic C-20r Submachine Gun, bundled with three magazines." #, and a Suppressor. components: - - type: StorageFill - contents: - - id: WeaponSubMachineGunC20r - - id: MagazinePistolSubMachineGun - amount: 2 + - type: StorageFill + contents: + - id: WeaponSubMachineGunC20r + - id: MagazinePistolSubMachineGun + amount: 2 # - id: SMGSuppressor - type: entity @@ -79,11 +78,11 @@ name: Python bundle description: "Go loud and proud with a fully loaded Magnum Python, bundled with two speed loaders." components: - - type: StorageFill - contents: - - id: WeaponRevolverPythonAP - - id: SpeedLoaderMagnumAP - amount: 2 + - type: StorageFill + contents: + - id: WeaponRevolverPythonAP + - id: SpeedLoaderMagnumAP + amount: 2 - type: entity parent: ClothingBackpackDuffelSyndicateBundle @@ -91,10 +90,10 @@ name: L6 Saw bundle description: "More dakka: The iconic L6 lightmachinegun, bundled with 2 box magazines." components: - - type: StorageFill - contents: - - id: WeaponLightMachineGunL6 - - id: MagazineLightRifleBox + - type: StorageFill + contents: + - id: WeaponLightMachineGunL6 + - id: MagazineLightRifleBox - type: entity parent: ClothingBackpackDuffelSyndicateBundle @@ -102,13 +101,13 @@ name: China-Lake bundle description: "An old China-Lake grenade launcher bundled with 11 rounds of various destruction capability." components: - - type: StorageFill - contents: - - id: WeaponLauncherChinaLake - - id: GrenadeBlast - amount: 4 - - id: GrenadeFrag - amount: 4 + - type: StorageFill + contents: + - id: WeaponLauncherChinaLake + - id: GrenadeBlast + amount: 4 + - id: GrenadeFrag + amount: 4 - type: entity parent: ClothingBackpackDuffelSyndicateBundle @@ -116,17 +115,17 @@ name: M-90gl bundle description: "A versatile battle rifle with an attached grenade launcher, bundled with 3 magazines and 6 grenades of various capabilities." components: - - type: StorageFill - contents: - - id: WeaponRifleM90GrenadeLauncher - - id: MagazineRifle - amount: 2 - - id: GrenadeBlast - amount: 2 - - id: GrenadeFlash - amount: 2 - - id: GrenadeFrag - amount: 2 + - type: StorageFill + contents: + - id: WeaponRifleM90GrenadeLauncher + - id: MagazineRifle + amount: 2 + - id: GrenadeBlast + amount: 2 + - id: GrenadeFlash + amount: 2 + - id: GrenadeFrag + amount: 2 - type: entity parent: ClothingBackpackDuffelSyndicateAmmo @@ -134,14 +133,14 @@ name: ammo bundle description: "Reloading! Contains 4 magazines for the C-20r, 4 drums for the Bulldog, and 2 ammo boxes for the L6 SAW." components: - - type: StorageFill - contents: - - id: MagazinePistolSubMachineGun - amount: 4 - - id: MagazineShotgun - amount: 4 - - id: MagazineLightRifleBox - amount: 2 + - type: StorageFill + contents: + - id: MagazinePistolSubMachineGun + amount: 4 + - id: MagazineShotgun + amount: 4 + - id: MagazineLightRifleBox + amount: 2 - type: entity parent: ClothingBackpackDuffel @@ -150,36 +149,36 @@ description: "Contains a full CentCom Official uniform set, headset and clipboard included. Encryption keys and ID access are not included." suffix: DO NOT MAP components: - - type: Tag - tags: [] # ignore "WhitelistChameleon" tag - - type: StorageFill - contents: - - id: ClothingHeadHatCentcom - - id: ClothingEyesGlassesSunglasses - - id: ClothingUniformJumpsuitCentcomOfficial - - id: ClothingShoesBootsJack - - id: ClothingHandsGlovesColorBlack - - id: ClothingHeadsetAltCentComFake - - id: ClothingOuterArmorBasic - - id: Paper - - id: Pen - - id: CentcomPDAFake + - type: Tag + tags: [] # ignore "WhitelistChameleon" tag + - type: StorageFill + contents: + - id: ClothingHeadHatCentcom + - id: ClothingEyesGlassesSunglasses + - id: ClothingUniformJumpsuitCentcomOfficial + - id: ClothingShoesBootsJack + - id: ClothingHandsGlovesColorBlack + - id: ClothingHeadsetAltCentComFake + - id: ClothingOuterArmorBasic + - id: Paper + - id: Pen + - id: CentcomPDAFake - type: entity parent: ClothingBackpackDuffelClown id: ClothingBackpackDuffelSyndicateCostumeClown suffix: syndicate components: - - type: Tag - tags: [] # ignore "WhitelistChameleon" tag - - type: StorageFill - contents: - - id: ClothingUniformJumpsuitClown - - id: ClothingShoesClown - - id: ClothingMaskClown - - id: BikeHorn - - id: ClownPDA - - id: ClothingHeadsetService + - type: Tag + tags: [] # ignore "WhitelistChameleon" tag + - type: StorageFill + contents: + - id: ClothingUniformJumpsuitClown + - id: ClothingShoesClown + - id: ClothingMaskClown + - id: BikeHorn + - id: ClownPDA + - id: ClothingHeadsetService - type: entity parent: ClothingBackpackDuffelSyndicateBundle @@ -187,11 +186,11 @@ name: carp suit duffel bag description: Contains a carp suit and some friends to play with. components: - - type: StorageFill - contents: - - id: ClothingOuterSuitCarp - - id: PlushieCarp - amount: 6 + - type: StorageFill + contents: + - id: ClothingOuterSuitCarp + - id: PlushieCarp + amount: 6 - type: entity parent: ClothingBackpackDuffelSyndicateBundle @@ -199,22 +198,22 @@ name: syndicate pyjama duffel bag description: Contains 3 pairs of syndicate pyjamas and 3 plushies for the ultimate sleepover. components: - - type: StorageFill - contents: - - id: ClothingUniformJumpsuitPyjamaSyndicateRed - - id: ClothingUniformJumpsuitPyjamaSyndicateBlack - - id: ClothingUniformJumpsuitPyjamaSyndicatePink - - id: ClothingHeadPyjamaSyndicateRed - - id: ClothingHeadPyjamaSyndicateBlack - - id: ClothingHeadPyjamaSyndicatePink - - id: ClothingShoesSlippers - amount: 3 - - id: BedsheetSyndie - amount: 3 - - id: PlushieCarp - - id: PlushieNuke - - id: PlushieLizard - - id: PlushieSharkBlue + - type: StorageFill + contents: + - id: ClothingUniformJumpsuitPyjamaSyndicateRed + - id: ClothingUniformJumpsuitPyjamaSyndicateBlack + - id: ClothingUniformJumpsuitPyjamaSyndicatePink + - id: ClothingHeadPyjamaSyndicateRed + - id: ClothingHeadPyjamaSyndicateBlack + - id: ClothingHeadPyjamaSyndicatePink + - id: ClothingShoesSlippers + amount: 3 + - id: BedsheetSyndie + amount: 3 + - id: PlushieCarp + - id: PlushieNuke + - id: PlushieLizard + - id: PlushieSharkBlue - type: entity parent: ClothingBackpackDuffelSyndicateBundle @@ -250,12 +249,12 @@ name: syndicate EVA bundle description: "Contains the Syndicate approved EVA suit." components: - - type: StorageFill - contents: - - id: ClothingHeadHelmetSyndicate - - id: ClothingOuterHardsuitSyndicate - - id: ClothingMaskGasSyndicate - - id: DoubleEmergencyOxygenTankFilled + - type: StorageFill + contents: + - id: ClothingHeadHelmetSyndicate + - id: ClothingOuterHardsuitSyndicate + - id: ClothingMaskGasSyndicate + - id: DoubleEmergencyOxygenTankFilled - type: entity parent: ClothingBackpackDuffelSyndicateBundle @@ -263,11 +262,11 @@ name: syndicate hardsuit bundle description: "Contains the Syndicate's signature blood red hardsuit." components: - - type: StorageFill - contents: - - id: ClothingOuterHardsuitSyndie - - id: ClothingMaskGasSyndicate - - id: ClothingHandsGlovesCombat + - type: StorageFill + contents: + - id: ClothingOuterHardsuitSyndie + - id: ClothingMaskGasSyndicate + - id: ClothingHandsGlovesCombat - type: entity parent: ClothingBackpackDuffelSyndicateBundle @@ -275,26 +274,26 @@ name: syndicate zombie bundle description: "An all-in-one kit for unleashing the undead upon a station." components: - - type: StorageFill - contents: - - id: SyringeRomerol - - id: WeaponRevolverPython - - id: MagazineBoxMagnumIncendiary - - id: PillAmbuzolPlus - - id: PillAmbuzol - amount: 3 + - type: StorageFill + contents: + - id: SyringeRomerol + - id: WeaponRevolverPython + - id: MagazineBoxMagnumIncendiary + - id: PillAmbuzolPlus + - id: PillAmbuzol + amount: 3 - type: entity parent: ClothingBackpackDuffelSyndicateBundle id: ClothingBackpackDuffelSyndicateOperative name: operative duffelbag components: - - type: StorageFill - contents: - - id: BoxSurvivalSyndicate - - id: WeaponPistolViper - - id: PinpointerNuclear - - id: MicroBombImplanter + - type: StorageFill + contents: + - id: BoxSurvivalSyndicate + - id: WeaponPistolViper + - id: PinpointerNuclear + - id: MicroBombImplanter - type: entity @@ -303,18 +302,18 @@ name: operative medic duffelbag description: A large duffel bag for holding extra medical supplies. components: - - type: StorageFill - contents: - - id: BoxSurvivalSyndicate - - id: SawAdvanced - - id: Cautery - - id: CombatKnife - - id: WeaponPistolViper - - id: PinpointerNuclear - - id: HandheldHealthAnalyzer - - id: CombatMedipen - - id: MicroBombImplanter - - id: SyndiHypo + - type: StorageFill + contents: + - id: BoxSurvivalSyndicate + - id: SawAdvanced + - id: Cautery + - id: CombatKnife + - id: WeaponPistolViper + - id: PinpointerNuclear + - id: HandheldHealthAnalyzer + - id: CombatMedipen + - id: MicroBombImplanter + - id: SyndiHypo - type: entity parent: ClothingBackpackDuffelSyndicateMedicalBundle @@ -322,12 +321,12 @@ name: medical bundle description: "All you need to get your comrades back in the fight." components: - - type: StorageFill - contents: - - id: MedkitCombatFilled - - id: Defibrillator - - id: CombatMedipen - amount: 3 - - id: ClothingHandsGlovesLatex - - id: SyringeTranexamicAcid - - id: SyringeHyronalin + - type: StorageFill + contents: + - id: MedkitCombatFilled + - id: Defibrillator + - id: CombatMedipen + amount: 3 + - id: ClothingHandsGlovesLatex + - id: SyringeTranexamicAcid + - id: SyringeHyronalin diff --git a/Resources/Prototypes/Entities/Clothing/Back/duffel.yml b/Resources/Prototypes/Entities/Clothing/Back/duffel.yml index b9cc9ca266..c89158486b 100644 --- a/Resources/Prototypes/Entities/Clothing/Back/duffel.yml +++ b/Resources/Prototypes/Entities/Clothing/Back/duffel.yml @@ -4,13 +4,13 @@ name: duffel bag description: A large duffel bag for holding extra things. components: - - type: Sprite - sprite: Clothing/Back/Duffels/duffel.rsi - - type: Storage - capacity: 120 - - type: ClothingSpeedModifier - walkModifier: 1 - sprintModifier: 0.9 + - type: Sprite + sprite: Clothing/Back/Duffels/duffel.rsi + - type: Storage + capacity: 120 + - type: ClothingSpeedModifier + walkModifier: 1 + sprintModifier: 0.9 - type: entity parent: ClothingBackpackDuffel @@ -18,8 +18,8 @@ name: engineering duffel bag description: A large duffel bag for holding extra tools and supplies. components: - - type: Sprite - sprite: Clothing/Back/Duffels/engineering.rsi + - type: Sprite + sprite: Clothing/Back/Duffels/engineering.rsi - type: entity parent: ClothingBackpackDuffel @@ -27,8 +27,8 @@ name: atmospherics duffel bag description: A large duffel bag made of fire resistant fibers. Smells like plasma. components: - - type: Sprite - sprite: Clothing/Back/Duffels/atmospherics.rsi + - type: Sprite + sprite: Clothing/Back/Duffels/atmospherics.rsi - type: entity parent: ClothingBackpackDuffel @@ -36,8 +36,8 @@ name: medical duffel bag description: A large duffel bag for holding extra medical supplies. components: - - type: Sprite - sprite: Clothing/Back/Duffels/medical.rsi + - type: Sprite + sprite: Clothing/Back/Duffels/medical.rsi - type: entity parent: ClothingBackpackDuffel @@ -45,8 +45,8 @@ name: captain's duffel bag description: A large duffel bag for holding extra captainly goods. components: - - type: Sprite - sprite: Clothing/Back/Duffels/captain.rsi + - type: Sprite + sprite: Clothing/Back/Duffels/captain.rsi - type: entity parent: ClothingBackpackDuffel @@ -54,11 +54,11 @@ name: clown duffel bag description: A large duffel bag for holding extra honk goods. components: - - type: Sprite - sprite: Clothing/Back/Duffels/clown.rsi - - type: Storage - storageOpenSound: - collection: BikeHorn + - type: Sprite + sprite: Clothing/Back/Duffels/clown.rsi + - type: Storage + storageOpenSound: + collection: BikeHorn - type: entity parent: ClothingBackpackDuffel @@ -66,8 +66,8 @@ name: security duffel bag description: A large duffel bag for holding extra security related goods. components: - - type: Sprite - sprite: Clothing/Back/Duffels/security.rsi + - type: Sprite + sprite: Clothing/Back/Duffels/security.rsi - type: entity parent: ClothingBackpackDuffel @@ -75,8 +75,8 @@ name: brigmedic duffel bag description: A large duffel bag for holding extra medical related goods. components: - - type: Sprite - sprite: Clothing/Back/Duffels/brigmedic.rsi + - type: Sprite + sprite: Clothing/Back/Duffels/brigmedic.rsi - type: entity parent: ClothingBackpackDuffel @@ -84,8 +84,8 @@ name: chemistry duffel bag description: A large duffel bag for holding extra beakers and test tubes. components: - - type: Sprite - sprite: Clothing/Back/Duffels/chemistry.rsi + - type: Sprite + sprite: Clothing/Back/Duffels/chemistry.rsi - type: entity parent: ClothingBackpackDuffel @@ -93,8 +93,8 @@ name: virology duffel bag description: A large duffel bag made of hypo-allergenic fibers. It's designed to help prevent the spread of disease. Smells like monkey. components: - - type: Sprite - sprite: Clothing/Back/Duffels/virology.rsi + - type: Sprite + sprite: Clothing/Back/Duffels/virology.rsi - type: entity parent: ClothingBackpackDuffel @@ -102,8 +102,8 @@ name: genetics duffel bag description: A large duffel bag for holding extra genetic mutations. components: - - type: Sprite - sprite: Clothing/Back/Duffels/genetics.rsi + - type: Sprite + sprite: Clothing/Back/Duffels/genetics.rsi - type: entity parent: ClothingBackpackDuffel @@ -111,12 +111,12 @@ name: mime duffel bag description: A large duffel bag for holding... mime... stuff. components: - - type: Sprite - sprite: Clothing/Back/Duffels/mime.rsi - storageOpenSound: - collection: null - storageInsertSound: - collection: null + - type: Sprite + sprite: Clothing/Back/Duffels/mime.rsi + storageOpenSound: + collection: null + storageInsertSound: + collection: null - type: entity parent: ClothingBackpackDuffel @@ -124,8 +124,8 @@ name: science duffel bag description: A large duffel bag for holding extra science related goods. components: - - type: Sprite - sprite: Clothing/Back/Duffels/science.rsi + - type: Sprite + sprite: Clothing/Back/Duffels/science.rsi - type: entity parent: ClothingBackpackDuffel @@ -160,31 +160,31 @@ name: syndicate duffel bag description: A large duffel bag for holding various traitor goods. components: - - type: Sprite - sprite: Clothing/Back/Duffels/syndicate.rsi - - type: Storage - capacity: 131 + - type: Sprite + sprite: Clothing/Back/Duffels/syndicate.rsi + - type: Storage + capacity: 131 - type: entity parent: ClothingBackpackDuffelSyndicate id: ClothingBackpackDuffelSyndicateBundle abstract: true components: - - type: Tag - tags: [] # ignore "WhitelistChameleon" tag + - type: Tag + tags: [] # ignore "WhitelistChameleon" tag - type: entity parent: ClothingBackpackDuffelSyndicate id: ClothingBackpackDuffelSyndicateAmmo name: syndicate duffel bag components: - - type: Sprite - sprite: Clothing/Back/Duffels/syndicate.rsi - state: icon-ammo - - type: Item - heldPrefix: ammo - - type: Clothing - equippedPrefix: ammo + - type: Sprite + sprite: Clothing/Back/Duffels/syndicate.rsi + state: icon-ammo + - type: Item + heldPrefix: ammo + - type: Clothing + equippedPrefix: ammo - type: entity parent: ClothingBackpackDuffelSyndicateAmmo @@ -199,13 +199,13 @@ id: ClothingBackpackDuffelSyndicateMedical name: syndicate duffel bag components: - - type: Sprite - sprite: Clothing/Back/Duffels/syndicate.rsi - state: icon-med - - type: Item - heldPrefix: med - - type: Clothing - equippedPrefix: med + - type: Sprite + sprite: Clothing/Back/Duffels/syndicate.rsi + state: icon-med + - type: Item + heldPrefix: med + - type: Clothing + equippedPrefix: med - type: entity parent: ClothingBackpackDuffelSyndicateMedical @@ -221,14 +221,26 @@ name: duffelbag of holding description: A duffelbag that opens into a localized pocket of bluespace. components: - - type: Sprite - sprite: Clothing/Back/Duffels/holding.rsi - state: icon - layers: - - state: icon - - state: icon-unlit - shader: unshaded - - type: Storage - capacity: 9999 - - type: ClothingSpeedModifier - sprintModifier: 1 # makes its stats identical to other variants of bag of holding + - type: Sprite + sprite: Clothing/Back/Duffels/holding.rsi + state: icon + layers: + - state: icon + - state: icon-unlit + shader: unshaded + - type: Storage + capacity: 9999 + - type: ClothingSpeedModifier + sprintModifier: 1 # makes its stats identical to other variants of bag of holding + +- type: entity + parent: ClothingBackpackDuffel + id: ClothingBackpackDuffelCBURN + name: CBURN duffel bag + description: A duffel bag containing a variety of biological containment equipment. + components: + - type: Storage + capacity: 150 + - type: ClothingSpeedModifier + walkModifier: 1 + sprintModifier: 1 diff --git a/Resources/Prototypes/Roles/Jobs/Fun/misc_startinggear.yml b/Resources/Prototypes/Roles/Jobs/Fun/misc_startinggear.yml index 0061630ad0..ad99ef7def 100644 --- a/Resources/Prototypes/Roles/Jobs/Fun/misc_startinggear.yml +++ b/Resources/Prototypes/Roles/Jobs/Fun/misc_startinggear.yml @@ -103,7 +103,7 @@ jumpsuit: ClothingUniformJumpsuitOperative back: ClothingBackpackDuffelSyndicateOperative mask: ClothingMaskGasSyndicate - # eyes: Night Vision Goggles whenever they're made + # eyes: Night Vision Goggles whenever they're made eyes: ClothingEyesGlassesMeson ears: ClothingHeadsetAltSyndicate gloves: ClothingHandsGlovesCombat @@ -124,7 +124,7 @@ jumpsuit: ClothingUniformJumpsuitOperative back: ClothingBackpackDuffelSyndicateOperative mask: ClothingMaskGasSyndicate - # eyes: Night Vision Goggles whenever they're made + # eyes: Night Vision Goggles whenever they're made eyes: ClothingEyesGlassesMeson ears: ClothingHeadsetAltSyndicate gloves: ClothingHandsGlovesCombat @@ -254,7 +254,7 @@ id: CBURNGear equipment: jumpsuit: ClothingUniformJumpsuitColorBrown - back: ClothingBackpackDuffelCBURN + back: ClothingBackpackDuffelCBURNFilled mask: ClothingMaskGasERT eyes: ClothingEyesGlassesSecurity ears: ClothingHeadsetAltCentCom @@ -267,8 +267,8 @@ suitstorage: YellowOxygenTankFilled belt: ClothingBeltBandolier innerClothingSkirt: ClothingUniformJumpsuitColorBrown - satchel: ClothingBackpackDuffelCBURN - duffelbag: ClothingBackpackDuffelCBURN + satchel: ClothingBackpackDuffelCBURNFilled + duffelbag: ClothingBackpackDuffelCBURNFilled - type: startingGear id: BoxingKangarooGear From 6ce75ccec973ca527e9bd1f26e297d7abdcb3c1a Mon Sep 17 00:00:00 2001 From: Artjom Date: Sat, 28 Oct 2023 09:54:18 +0400 Subject: [PATCH 095/102] Health analyzer UI improve (#17280) --- .../UI/HealthAnalyzerWindow.xaml | 40 +++- .../UI/HealthAnalyzerWindow.xaml.cs | 219 +++++++++++++----- .../components/health-analyzer-component.ftl | 1 + .../Devices/health_analyzer.rsi/airloss.png | Bin 0 -> 4254 bytes .../Devices/health_analyzer.rsi/brute.png | Bin 0 -> 4254 bytes .../Devices/health_analyzer.rsi/burn.png | Bin 0 -> 414 bytes .../Devices/health_analyzer.rsi/genetic.png | Bin 0 -> 4235 bytes .../Devices/health_analyzer.rsi/meta.json | 29 +++ .../Devices/health_analyzer.rsi/toxin.png | Bin 0 -> 4254 bytes .../Devices/health_analyzer.rsi/unknown.png | Bin 0 -> 4235 bytes 10 files changed, 220 insertions(+), 69 deletions(-) create mode 100644 Resources/Textures/Objects/Devices/health_analyzer.rsi/airloss.png create mode 100644 Resources/Textures/Objects/Devices/health_analyzer.rsi/brute.png create mode 100644 Resources/Textures/Objects/Devices/health_analyzer.rsi/burn.png create mode 100644 Resources/Textures/Objects/Devices/health_analyzer.rsi/genetic.png create mode 100644 Resources/Textures/Objects/Devices/health_analyzer.rsi/meta.json create mode 100644 Resources/Textures/Objects/Devices/health_analyzer.rsi/toxin.png create mode 100644 Resources/Textures/Objects/Devices/health_analyzer.rsi/unknown.png diff --git a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml index 1f64feec2b..b78c3c6a56 100644 --- a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml +++ b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml @@ -1,9 +1,33 @@  - - - + SetSize="250 100"> + + + + + \ No newline at end of file diff --git a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml.cs b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml.cs index 1c5a3373e1..36f7a08b96 100644 --- a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml.cs +++ b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml.cs @@ -1,5 +1,5 @@ +using System.Linq; using System.Numerics; -using System.Text; using Content.Shared.Damage; using Content.Shared.Damage.Prototypes; using Content.Shared.FixedPoint; @@ -8,85 +8,182 @@ using Content.Shared.MedicalScanner; using Robust.Client.AutoGenerated; using Robust.Client.UserInterface.CustomControls; using Robust.Client.UserInterface.XAML; +using Robust.Client.GameObjects; +using Robust.Client.Graphics; +using Robust.Client.UserInterface.Controls; +using Robust.Client.ResourceManagement; using Robust.Shared.Prototypes; +using Robust.Shared.Utility; namespace Content.Client.HealthAnalyzer.UI { [GenerateTypedNameReferences] public sealed partial class HealthAnalyzerWindow : DefaultWindow { + private readonly IEntityManager _entityManager; + private readonly SpriteSystem _spriteSystem; + private readonly IPrototypeManager _prototypes; + private readonly IResourceCache _cache; + + private const int AnalyzerHeight = 430; + private const int AnalyzerWidth = 300; + public HealthAnalyzerWindow() { RobustXamlLoader.Load(this); + + var dependencies = IoCManager.Instance!; + _entityManager = dependencies.Resolve(); + _spriteSystem = _entityManager.System(); + _prototypes = dependencies.Resolve(); + _cache = dependencies.Resolve(); } public void Populate(HealthAnalyzerScannedUserMessage msg) { - var text = new StringBuilder(); - var entities = IoCManager.Resolve(); - var target = entities.GetEntity(msg.TargetEntity); + GroupsContainer.RemoveAllChildren(); - if (msg.TargetEntity != null && entities.TryGetComponent(target, out var damageable)) + var target = _entityManager.GetEntity(msg.TargetEntity); + + if (target == null + || !_entityManager.TryGetComponent(target, out var damageable)) { - string entityName = "Unknown"; - if (msg.TargetEntity != null && - entities.HasComponent(target.Value)) - { - entityName = Identity.Name(target.Value, entities); - } - - IReadOnlyDictionary damagePerGroup = damageable.DamagePerGroup; - IReadOnlyDictionary damagePerType = damageable.Damage.DamageDict; - - text.Append($"{Loc.GetString("health-analyzer-window-entity-health-text", ("entityName", entityName))}\n\n"); - - - text.Append($"{Loc.GetString("health-analyzer-window-entity-temperature-text", ("temperature", float.IsNaN(msg.Temperature) ? "N/A" : $"{msg.Temperature - 273f:F1} °C"))}\n"); - - - text.Append($"{Loc.GetString("health-analyzer-window-entity-blood-level-text", ("bloodLevel", float.IsNaN(msg.BloodLevel) ? "N/A" : $"{msg.BloodLevel * 100:F1} %"))}\n\n"); - - - // Damage - text.Append($"{Loc.GetString("health-analyzer-window-entity-damage-total-text", ("amount", damageable.TotalDamage))}\n"); - - HashSet shownTypes = new(); - - var protos = IoCManager.Resolve(); - - // Show the total damage and type breakdown for each damage group. - foreach (var (damageGroupId, damageAmount) in damagePerGroup) - { - if (damageAmount == 0) - { - continue; - } - text.Append($"\n{Loc.GetString("health-analyzer-window-damage-group-text", ("damageGroup", Loc.GetString("health-analyzer-window-damage-group-" + damageGroupId)), ("amount", damageAmount))}"); - - // Show the damage for each type in that group. - var group = protos.Index(damageGroupId); - foreach (var type in group.DamageTypes) - { - if (damagePerType.TryGetValue(type, out var typeAmount) ) - { - // If damage types are allowed to belong to more than one damage group, they may appear twice here. Mark them as duplicate. - if (!shownTypes.Contains(type) && typeAmount > 0) - { - shownTypes.Add(type); - text.Append($"\n- {Loc.GetString("health-analyzer-window-damage-type-text", ("damageType", Loc.GetString("health-analyzer-window-damage-type-" + type)), ("amount", typeAmount))}"); - } - } - } - text.AppendLine(); - } - Diagnostics.Text = text.ToString(); - SetSize = new Vector2(250, 600); + NoPatientDataText.Visible = true; + return; } - else + + NoPatientDataText.Visible = false; + + string entityName = Loc.GetString("health-analyzer-window-entity-unknown-text"); + if (_entityManager.HasComponent(target.Value)) { - Diagnostics.Text = Loc.GetString("health-analyzer-window-no-patient-data-text"); - SetSize = new Vector2(250, 100); + entityName = Identity.Name(target.Value, _entityManager); } + + PatientName.Text = Loc.GetString( + "health-analyzer-window-entity-health-text", + ("entityName", entityName) + ); + + Temperature.Text = Loc.GetString("health-analyzer-window-entity-temperature-text", + ("temperature", float.IsNaN(msg.Temperature) ? "N/A" : $"{msg.Temperature - 273f:F1} °C") + ); + + BloodLevel.Text = Loc.GetString("health-analyzer-window-entity-blood-level-text", + ("bloodLevel", float.IsNaN(msg.BloodLevel) ? "N/A" : $"{msg.BloodLevel * 100:F1} %") + ); + + patientDamageAmount.Text = Loc.GetString( + "health-analyzer-window-entity-damage-total-text", + ("amount", damageable.TotalDamage) + ); + + var damageSortedGroups = + damageable.DamagePerGroup.OrderBy(damage => damage.Value) + .ToDictionary(x => x.Key, x => x.Value); + IReadOnlyDictionary damagePerType = damageable.Damage.DamageDict; + + DrawDiagnosticGroups(damageSortedGroups, damagePerType); + + SetHeight = AnalyzerHeight; + SetWidth = AnalyzerWidth; + } + + private void DrawDiagnosticGroups( + Dictionary groups, IReadOnlyDictionary damageDict) + { + HashSet shownTypes = new(); + + // Show the total damage and type breakdown for each damage group. + foreach (var (damageGroupId, damageAmount) in groups.Reverse()) + { + if (damageAmount == 0) + continue; + + var groupTitleText = $"{Loc.GetString( + "health-analyzer-window-damage-group-text", + ("damageGroup", Loc.GetString("health-analyzer-window-damage-group-" + damageGroupId)), + ("amount", damageAmount) + )}"; + + var groupContainer = new BoxContainer + { + Margin = new Thickness(0, 0, 0, 15), + Align = BoxContainer.AlignMode.Begin, + Orientation = BoxContainer.LayoutOrientation.Vertical, + }; + + groupContainer.AddChild(CreateDiagnosticGroupTitle(groupTitleText, damageGroupId, damageAmount.Int())); + + GroupsContainer.AddChild(groupContainer); + + // Show the damage for each type in that group. + var group = _prototypes.Index(damageGroupId); + + foreach (var type in group.DamageTypes) + { + if (damageDict.TryGetValue(type, out var typeAmount) && typeAmount > 0) + { + // If damage types are allowed to belong to more than one damage group, + // they may appear twice here. Mark them as duplicate. + if (shownTypes.Contains(type)) + continue; + + shownTypes.Add(type); + + var damageString = Loc.GetString( + "health-analyzer-window-damage-type-text", + ("damageType", Loc.GetString("health-analyzer-window-damage-type-" + type)), + ("amount", typeAmount) + ); + + groupContainer.AddChild(CreateDiagnosticItemLabel(damageString.Insert(0, "- "))); + } + } + } + } + + private Texture GetTexture(string texture) + { + var rsiPath = new ResPath("/Textures/Objects/Devices/health_analyzer.rsi"); + var rsiSprite = new SpriteSpecifier.Rsi(rsiPath, texture); + + var rsi = _cache.GetResource(rsiSprite.RsiPath).RSI; + if (!rsi.TryGetState(rsiSprite.RsiState, out var state)) + { + rsiSprite = new SpriteSpecifier.Rsi(rsiPath, "unknown"); + } + + return _spriteSystem.Frame0(rsiSprite); + } + + private static Label CreateDiagnosticItemLabel(string text) + { + return new Label + { + Margin = new Thickness(2, 2), + Text = text, + }; + } + + private BoxContainer CreateDiagnosticGroupTitle(string text, string id, int damageAmount) + { + var rootContainer = new BoxContainer + { + VerticalAlignment = VAlignment.Bottom, + Orientation = BoxContainer.LayoutOrientation.Horizontal + }; + + rootContainer.AddChild(new TextureRect + { + Margin = new Thickness(0, 3), + SetSize = new Vector2(30, 30), + Texture = GetTexture(id.ToLower()) + }); + + rootContainer.AddChild(CreateDiagnosticItemLabel(text)); + + return rootContainer; } } } diff --git a/Resources/Locale/en-US/medical/components/health-analyzer-component.ftl b/Resources/Locale/en-US/medical/components/health-analyzer-component.ftl index 99513df591..453bbdbb52 100644 --- a/Resources/Locale/en-US/medical/components/health-analyzer-component.ftl +++ b/Resources/Locale/en-US/medical/components/health-analyzer-component.ftl @@ -1,4 +1,5 @@ health-analyzer-window-no-patient-data-text = No patient data. +health-analyzer-window-entity-unknown-text = unknown health-analyzer-window-entity-health-text = {$entityName}'s health: health-analyzer-window-entity-temperature-text = Temperature: {$temperature} health-analyzer-window-entity-blood-level-text = Blood Level: {$bloodLevel} diff --git a/Resources/Textures/Objects/Devices/health_analyzer.rsi/airloss.png b/Resources/Textures/Objects/Devices/health_analyzer.rsi/airloss.png new file mode 100644 index 0000000000000000000000000000000000000000..82fa0e2c8891aa76ff1d61bad6feed2b93fbee7e GIT binary patch literal 4254 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzwj^(N7l!{JxM1({$v_d#0*}aI z1_o|n5N2eUHAey{$X?><>&pI|jYULIsOHD6nG6g9+MX_sArYL63Ig}v162$xU_`fG zQd06ix)`7x+#FF+QHJBkk29bf|8_>~jDX#_oefaGuitWiKtF$_-wK%4k**@i`&sv&^I ze1bxw4j2sqtRe8{&mWY;14`kbEQXxD$j$dC1_L=*vmv@75Fb|ZePT!eOQRIaU=i{N zq8$J-p4_~S&uLhr0G|eG%Z)l<>&pI|jYUL2%_Y1(mw`b*+tbA{B!ZJsLE!#-po)P7jOf-& zN=p7m7o!&c`Sa%(_Mr%XEVs0@WO)7hHMQ)7n?}dQWA`*kyc0w z0RuKRh8-Ln42za5VK{#BBvl+jk^^1~3xh2N`TX|n+h8`#A>@Vz$(h}y5m9(fkGjR6 zs;UZhh^4tX!_()_Np=U(ApnYZ5YThr24fIAbD0`ABtW4-E+8ocEW56P?UA+r3Z%Ii zE*N|oE#K9su z3P8RE;l~HL!A8O8<7L`l-!FRe1}qM;90X3kVh7WN2!aj(`5u(gK?x27kR1Ut9NF^V z@JO(5`;xsdX}mPnD8Quymg-?S0TlP`moGEKiHI=3e7<(&at2~82iZf=0idh}%3>e@ z3JFk(hdIP@n>oWlU^Yw!%7Nk>6zrr}4l=5^d4;hp`ePYmS3jq5Z6!&7l;3qcqgIx_I2qr?9LS!1` z5NV(z5AgB9g&*x-0B4iJz#0O?7|;w1dQj>oCa>c&kE{@Y83;=KlmdzzK&j;*{i6=R zng~H{cxrb{a77n}13+CUQ11v=M*^2Ygv3GSV)GQDc>^_p-knoI4yU=iO4fPd#Xn@$ PfGqNK^>bP0l+XkKu?X!X literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Devices/health_analyzer.rsi/burn.png b/Resources/Textures/Objects/Devices/health_analyzer.rsi/burn.png new file mode 100644 index 0000000000000000000000000000000000000000..cf65084e44e786feff1ed98094f3b0036cb00755 GIT binary patch literal 414 zcmV;P0b%}$P)Zq}6o&tnGK8g4RS#a6ER~rJiJ2Q@>4|!m-hd0Rr7Huw2hU9^MNzr{1!E%H&ndrz z1m^kuALbcjU}HV#4V?4qz09PP3%^+d=log}1(Z_3%^728nq~pUDpLO7ecH) z)B<2I|CBNqz`lnt>Cq=)0^qxhkPx7}0FwRyfHHlawN3Bc1wc=pq(`f`AONPMUmrhC z@g#s-Qe{NyPX?fh43HA10ttXR{A7SM0kS;a24MR1yUKqgoB*b#(|3QWFaHCen`U{8 z_HZ@=1_!W7?lU8-0oDp`7=GV6@Gio)_m`P*md9STVEi92=~Q3P_UF4Q8W*E1kH>Z& zSpy6Zqh9|`^ES`Wju9v>874Pq_MMNUQN zn%qX4|Bx6*KnQ_-K$EpSff0Z)2Bp-^PCjCc8FyQoZ%#MYFTDh2*4cRjjsO4v07*qo IM6N<$f(wDISpWb4 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Devices/health_analyzer.rsi/genetic.png b/Resources/Textures/Objects/Devices/health_analyzer.rsi/genetic.png new file mode 100644 index 0000000000000000000000000000000000000000..b660aed537581d821913c32d4b4d581ab8c8ba0f GIT binary patch literal 4235 zcmc&%ZA_b06n@^8Qrf27pwv*xkOC$SL?vN!EPM=8!-oq&L*ll?iAxp|Hx^^VK->?r z#V!7t#3e4WA8anv&CQsMA7qJUuGv^HnQ<9L8J|^PQad8h@6y+E2`#R?h1-R=)7;+s z-mm95_nv$1xt})FS8LUoY5>~W8q1rM=dhHLO#jx7js?n+54>J&fyjQ{-`hT?8rAzX zd#!**&ys*I&t(9c3u`S^jeAr=&gQXM>hp9(h=n&Ajbd!wMtx6DPp`sztb&1;mX^Zl zbZ!)8bRL7jfd2k|#F9vg_E;`Nz=wy2W1F7%J3l`^u2QQAFcb!!lqA{oL?qaJjD(c% zqo~zL-oGF6v^026o&*HN%6wuFM~>tpB}I;|t`W@6hF03vDRC1J($k@;sevLl7qank z{PyQO^nd&U*Or&?e3llCjpv|L`q9@nNd(xLi{WI7$(2tDxI z$6FH9uV0nW3Ro<9SgkL>WK!V94Lf>!+wfg^IeZoi0xc~t$Ycm#y$ZHnyu!T#CQ~w+ znhLOW>x&o}IfMrfnvhFJvi0FZT)TfCUl@(ZXl{m(oz08A)Q@`wa&tAs0uXRX~_-Zh>gHjR=Y< z5LsFA9~Uh(QA`~-fzi=9ghGC#rTfs*;)hx-Cv0IUx!qgnveDqITn-1>Ln6XWV0_$7 zd+$U=g&V1jOWr!k_HseH7)mgp(Sv| znKKFb07jI11tMBqyy(K6J8zQ>G{a~%!%d;qCDK}P`gFqJaS5>VEh(gJlGTbfx(5s{ z7p{@l8yY%}va-uKb*cb5om_I*T9w>ez$Qr|m%FL45ju|te;+#rE8T`UIU+hccc88= z52K?VbazjXC*}{Vl4z6 z-v$JVgcM}$i*EN4yGSI&@>b`w6bbq0ZrFtMboNr>7k;{aKY|q9hKYc?=N+g8@`N(- zdSVFfu}|>h%f+O<5_5C>0V$)&O@IX>9tuXHB6@*EO3QNe=+BX2Lb)UX7Q=7!!z3Q7 zRRq`*ioK5FJtX2yv|c@%S4yeKjT#;Qe?Ly6z)!32ab^1luXtT*w)+-L_=Fs%>~se1$jSf7&1{wdmVk&(mllfA8ojliSwI&L<~S#iM`-b#hpll= zzyxISvol!asFRZ8*jpz+5`Ykh7R9okXIkbF1Ag7I3P1sYzy{E6%sGL(kE<4r z*)jo9S5H_4(z~(d6_S080zY`HT6@ F{ck!^*joSq literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Devices/health_analyzer.rsi/unknown.png b/Resources/Textures/Objects/Devices/health_analyzer.rsi/unknown.png new file mode 100644 index 0000000000000000000000000000000000000000..f68e2c990e59799c9cbd950445b51451cc98efda GIT binary patch literal 4235 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzwj^(N7l!{JxM1({$v_d#0*}aI z1_o|n5N2eUHAjMhK|tHn#W5s;lTkt7{(GRBfd!1{)=NrC{zn(17XSJ4=NR^(2!JfN zw6tV+{rWYv?1Y;mDk{ow{P=MObVsnjRX`aq%kSK|gDyojUqwX)r>8I+0I~&SISUI` zDY6^^G7sbkY=8-yAU(xK9WWXKqaiRF0;3@?8UmvsFd71*Aut*OqalE`@egXlQ@dk= ztErFS08keS)H}k}k-%jTA#sqo*gS>OHv}0%@6IV9htphs`fe@$z^Y@tAd5U*{an^L HB{Ts5?(jp` literal 0 HcmV?d00001 From 5776a15b81c47313b35beaa8134c8c9fa67f28ce Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 28 Oct 2023 01:55:22 -0400 Subject: [PATCH 096/102] Automatic changelog update --- Resources/Changelog/Changelog.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 177b504c43..507d3badcc 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,9 +1,4 @@ Entries: -- author: EmoGarbage404 - changes: - - {message: Fixed the RPED sound effect cutting off at the end., type: Fix} - id: 4572 - time: '2023-08-14T03:36:08.0000000+00:00' - author: DrSmugleaf changes: - {message: Admin notes now require a severity to be set before saving., type: Tweak} @@ -2909,3 +2904,8 @@ Entries: - {message: Fixed nuclear operatives sound not being played at round start, type: Fix} id: 5071 time: '2023-10-28T02:28:21.0000000+00:00' +- author: Arteben + changes: + - {message: Nanotrasen improved the health analyzer UI!, type: Tweak} + id: 5072 + time: '2023-10-28T05:54:18.0000000+00:00' From 679bea07e0b5b0844ddad7d53f2f1b340b4fd542 Mon Sep 17 00:00:00 2001 From: Morb0 <14136326+Morb0@users.noreply.github.com> Date: Sat, 28 Oct 2023 13:13:08 +0300 Subject: [PATCH 097/102] Remove corvax hijack --- .../HijackShuttleConditionComponent.cs | 8 -- .../Systems/HijackShuttleConditionSystem.cs | 104 ------------------ 2 files changed, 112 deletions(-) delete mode 100644 Content.Server/Corvax/Objectives/Components/HijackShuttleConditionComponent.cs delete mode 100644 Content.Server/Corvax/Objectives/Systems/HijackShuttleConditionSystem.cs diff --git a/Content.Server/Corvax/Objectives/Components/HijackShuttleConditionComponent.cs b/Content.Server/Corvax/Objectives/Components/HijackShuttleConditionComponent.cs deleted file mode 100644 index 31c7ce8444..0000000000 --- a/Content.Server/Corvax/Objectives/Components/HijackShuttleConditionComponent.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Content.Server.Corvax.Objectives.Systems; - -namespace Content.Server.Corvax.Objectives.Components; - -[RegisterComponent, Access(typeof(HijackShuttleConditionSystem))] -public sealed partial class HijackShuttleConditionComponent : Component -{ -} diff --git a/Content.Server/Corvax/Objectives/Systems/HijackShuttleConditionSystem.cs b/Content.Server/Corvax/Objectives/Systems/HijackShuttleConditionSystem.cs deleted file mode 100644 index 9e4d2e476c..0000000000 --- a/Content.Server/Corvax/Objectives/Systems/HijackShuttleConditionSystem.cs +++ /dev/null @@ -1,104 +0,0 @@ -using Content.Server.Corvax.Objectives.Components; -using Content.Server.Shuttles.Components; -using Content.Server.Shuttles.Systems; -using Content.Shared.Cuffs.Components; -using Content.Shared.Humanoid; -using Content.Shared.Mind; -using Content.Shared.Mobs.Components; -using Content.Shared.Mobs.Systems; -using Content.Shared.Objectives.Components; -using Content.Shared.Roles; -using Robust.Shared.Player; - -namespace Content.Server.Corvax.Objectives.Systems; - -public sealed class HijackShuttleConditionSystem : EntitySystem -{ - [Dependency] private readonly EmergencyShuttleSystem _emergencyShuttle = default!; - [Dependency] private readonly SharedMindSystem _mind = default!; - [Dependency] private readonly SharedRoleSystem _role = default!; - [Dependency] private readonly MobStateSystem _mobState = default!; - - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnGetProgress); - } - - private void OnGetProgress(EntityUid uid, HijackShuttleConditionComponent comp, ref ObjectiveGetProgressEvent args) - { - args.Progress = GetProgress(args.MindId, args.Mind); - } - - private float GetProgress(EntityUid mindId, MindComponent mind) - { - // not escaping alive if you're deleted/dead - if (mind.OwnedEntity == null || _mind.IsCharacterDeadIc(mind)) - return 0f; - - // You're not escaping if you're restrained! - if (TryComp(mind.OwnedEntity, out var cuffed) && cuffed.CuffedHandCount > 0) - return 0f; - - // There no emergency shuttles - if (!_emergencyShuttle.EmergencyShuttleArrived) - return 0f; - - // Check hijack for each emergency shuttle - foreach (var stationData in EntityQuery()) - { - if (stationData.EmergencyShuttle == null) - continue; - - if (IsShuttleHijacked(stationData.EmergencyShuttle.Value, mindId)) - return 1f; - } - - return 0f; - } - - private bool IsShuttleHijacked(EntityUid shuttleGridId, EntityUid mindId) - { - var gridPlayers = Filter.BroadcastGrid(shuttleGridId).Recipients; - var humanoids = GetEntityQuery(); - var cuffable = GetEntityQuery(); - EntityQuery(); - - var agentOnShuttle = false; - foreach (var player in gridPlayers) - { - if (player.AttachedEntity == null || - !_mind.TryGetMind(player.AttachedEntity.Value, out var crewMindId, out _)) - continue; - - if (mindId == crewMindId) - { - agentOnShuttle = true; - continue; - } - - var isHumanoid = humanoids.HasComponent(player.AttachedEntity.Value); - if (!isHumanoid) // Only humanoids count as enemies - continue; - - var isAntagonist = _role.MindIsAntagonist(mindId); - if (isAntagonist) // Allow antagonist - continue; - - var isPersonIncapacitated = _mobState.IsIncapacitated(player.AttachedEntity.Value); - if (isPersonIncapacitated) // Allow dead and crit - continue; - - var isPersonCuffed = - cuffable.TryGetComponent(player.AttachedEntity.Value, out var cuffed) - && cuffed.CuffedHandCount > 0; - if (isPersonCuffed) // Allow handcuffed - continue; - - return false; - } - - return agentOnShuttle; - } -} From f010529b0b56c32e08c9137a3c1fc18610663d21 Mon Sep 17 00:00:00 2001 From: Morb0 <14136326+Morb0@users.noreply.github.com> Date: Sat, 28 Oct 2023 13:20:01 +0300 Subject: [PATCH 098/102] Fix player session interface --- .../IServerDiscordAuthManager.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Corvax/Content.Corvax.Interfaces.Server/IServerDiscordAuthManager.cs b/Corvax/Content.Corvax.Interfaces.Server/IServerDiscordAuthManager.cs index 1ec680877f..95660f69c1 100644 --- a/Corvax/Content.Corvax.Interfaces.Server/IServerDiscordAuthManager.cs +++ b/Corvax/Content.Corvax.Interfaces.Server/IServerDiscordAuthManager.cs @@ -1,12 +1,13 @@ using Content.Corvax.Interfaces.Shared; using Robust.Server.Player; using Robust.Shared.Network; +using Robust.Shared.Player; namespace Content.Corvax.Interfaces.Server; public interface IServerDiscordAuthManager : ISharedDiscordAuthManager { - public event EventHandler? PlayerVerified; + public event EventHandler? PlayerVerified; public Task GenerateAuthLink(NetUserId userId, CancellationToken cancel); public Task IsVerified(NetUserId userId, CancellationToken cancel); } From 0c2abff1889ce842e66375941b2599916184fb79 Mon Sep 17 00:00:00 2001 From: Morb0 <14136326+Morb0@users.noreply.github.com> Date: Sat, 28 Oct 2023 13:36:40 +0300 Subject: [PATCH 099/102] Update locale --- .../catalog/fills/backpacks/duffelbag.ftl | 5 +- .../fills/backpacks/startergear/backpack.ftl | 2 + .../entities/clothing/back/duffel.ftl | 2 + .../clothing/outerclothing/hardsuits.ftl | 12 +-- .../entities/clothing/uniforms/jumpsuits.ftl | 2 +- .../entities/mobs/player/humanoid.ftl | 25 ++++-- .../objects/consumable/food/burger.ftl | 4 +- .../consumable/food/containers/box.ftl | 3 + .../objects/consumable/food/ingredients.ftl | 2 - .../entities/objects/decoration/flora.ftl | 32 +++++++- .../entities/objects/decoration/mining.ftl | 12 +++ .../entities/objects/devices/pda.ftl | 2 +- .../prototypes/entities/objects/fun/pai.ftl | 2 + .../objects/misc/identification_cards.ftl | 2 +- .../entities/objects/misc/implanters.ftl | 3 + .../entities/objects/misc/potatoai_chip.ftl | 2 + .../weapons/guns/battery/battery_guns.ftl | 2 +- .../entities/structures/walls/asteroid.ftl | 10 +-- .../prototypes/entities/tiles/chasm.ftl | 9 ++ .../entities/tiles/shadow_basalt.ftl | 13 +++ .../ss14-ru/prototypes/gamerules/events.ftl | 2 + .../ru-RU/escape-menu/ui/options-menu.ftl | 1 + .../ghost/roles/ghost-role-component.ftl | 2 + Resources/Locale/ru-RU/implant/implant.ftl | 1 + .../components/health-analyzer-component.ftl | 1 + Resources/Locale/ru-RU/pai/pai-system.ftl | 2 + .../ru-RU/power/components/generator.ftl | 18 ++-- Resources/Locale/ru-RU/species/skeleton.ftl | 2 + .../catalog/fills/backpacks/duffelbag.ftl | 5 +- .../fills/backpacks/startergear/backpack.ftl | 2 + .../entities/clothing/back/duffel.ftl | 2 + .../entities/mobs/player/humanoid.ftl | 15 ++++ .../consumable/food/containers/box.ftl | 3 + .../objects/consumable/food/ingredients.ftl | 2 - .../entities/objects/decoration/flora.ftl | 24 ++++++ .../entities/objects/decoration/mining.ftl | 12 +++ .../prototypes/entities/objects/fun/pai.ftl | 2 + .../entities/objects/misc/implanters.ftl | 3 + .../entities/objects/misc/potatoai_chip.ftl | 2 + .../prototypes/entities/tiles/chasm.ftl | 9 ++ .../entities/tiles/shadow_basalt.ftl | 13 +++ .../ss14-ru/prototypes/gamerules/events.ftl | 2 + .../ss14-ru/prototypes/objectives/traitor.ftl | 2 + .../ru-RU/station-events/events/ion-storm.ftl | 82 +++++++++++++++++++ .../Locale/ru-RU/store/uplink-catalog.ftl | 2 + Resources/Locale/ru-RU/tiles/tiles.ftl | 1 + .../ru-RU/xenoarchaeology/artifact-hints.ftl | 1 + 47 files changed, 317 insertions(+), 42 deletions(-) create mode 100644 Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/decoration/mining.ftl create mode 100644 Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/misc/potatoai_chip.ftl create mode 100644 Resources/Locale/en-US/ss14-ru/prototypes/entities/tiles/shadow_basalt.ftl create mode 100644 Resources/Locale/ru-RU/species/skeleton.ftl create mode 100644 Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/decoration/mining.ftl create mode 100644 Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/misc/potatoai_chip.ftl create mode 100644 Resources/Locale/ru-RU/ss14-ru/prototypes/entities/tiles/shadow_basalt.ftl create mode 100644 Resources/Locale/ru-RU/station-events/events/ion-storm.ftl diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/catalog/fills/backpacks/duffelbag.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/catalog/fills/backpacks/duffelbag.ftl index b2c7546481..596a160b17 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/catalog/fills/backpacks/duffelbag.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/catalog/fills/backpacks/duffelbag.ftl @@ -1,7 +1,8 @@ ent-ClothingBackpackDuffelSurgeryFilled = surgical duffel bag .desc = A large duffel bag for holding extra medical supplies - this one seems to be designed for holding surgical tools. -ent-ClothingBackpackDuffelCBURN = CBURN duffel bag - .desc = A duffel bag containing a variety of biological containment equipment. +ent-ClothingBackpackDuffelCBURNFilled = { ent-ClothingBackpackDuffelCBURN } + .suffix = Filled + .desc = { ent-ClothingBackpackDuffelCBURN.desc } ent-ClothingBackpackDuffelSyndicateFilledMedical = syndicate surgical duffel bag .desc = A large duffel bag containing a full suite of surgical tools. ent-ClothingBackpackDuffelSyndicateFilledShotgun = Bulldog bundle diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/catalog/fills/backpacks/startergear/backpack.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/catalog/fills/backpacks/startergear/backpack.ftl index 39540be61f..8852f7eaa9 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/catalog/fills/backpacks/startergear/backpack.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/catalog/fills/backpacks/startergear/backpack.ftl @@ -52,6 +52,8 @@ ent-ClothingBackpackERTEngineerFilled = { ent-ClothingBackpackERTEngineer } .desc = { ent-ClothingBackpackERTEngineer.desc } ent-ClothingBackpackERTJanitorFilled = { ent-ClothingBackpackERTJanitor } .desc = { ent-ClothingBackpackERTJanitor.desc } +ent-ClothingBackpackDeathSquadFilled = death squad backpack + .desc = Holds the kit of CentComm's most feared agents. ent-ClothingBackpackCargoFilled = { ent-ClothingBackpackCargo } .desc = { ent-ClothingBackpackCargo.desc } ent-ClothingBackpackSalvageFilled = { ent-ClothingBackpackSalvage } diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/clothing/back/duffel.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/clothing/back/duffel.ftl index d5dc793ae4..b8328cff32 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/entities/clothing/back/duffel.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/clothing/back/duffel.ftl @@ -44,3 +44,5 @@ ent-ClothingBackpackDuffelSyndicateMedicalBundle = { ent-ClothingBackpackDuffelS .desc = { ent-ClothingBackpackDuffelSyndicateMedical.desc } ent-ClothingBackpackDuffelHolding = duffelbag of holding .desc = A duffelbag that opens into a localized pocket of bluespace. +ent-ClothingBackpackDuffelCBURN = CBURN duffel bag + .desc = A duffel bag containing a variety of biological containment equipment. diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/clothing/outerclothing/hardsuits.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/clothing/outerclothing/hardsuits.ftl index 2f230a0756..94e2ba7175 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/entities/clothing/outerclothing/hardsuits.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/clothing/outerclothing/hardsuits.ftl @@ -46,16 +46,16 @@ ent-ClothingOuterHardsuitPirateEVA = deep space EVA suit ent-ClothingOuterHardsuitPirateCap = pirate captain's hardsuit .desc = An ancient armored hardsuit, perfect for defending against space scurvy and toolbox-wielding scallywags. ent-ClothingOuterHardsuitERTLeader = ERT leader's hardsuit - .desc = A protective hardsuit worn by members of an emergency response team. + .desc = A protective hardsuit worn by the leader of an emergency response team. ent-ClothingOuterHardsuitERTEngineer = ERT engineer's hardsuit - .desc = { ent-ClothingOuterHardsuitSyndie.desc } + .desc = A protective hardsuit worn by the engineers of an emergency response team. ent-ClothingOuterHardsuitERTMedical = ERT medic's hardsuit - .desc = { ent-ClothingOuterHardsuitSyndieElite.desc } + .desc = A protective hardsuit worn by the medics of an emergency response team. ent-ClothingOuterHardsuitERTSecurity = ERT security's hardsuit - .desc = { ent-ClothingOuterHardsuitSyndie.desc } + .desc = A protective hardsuit worn by the security officers of an emergency response team. ent-ClothingOuterHardsuitERTJanitor = ERT janitor's hardsuit - .desc = { ent-ClothingOuterHardsuitSyndie.desc } -ent-ClothingOuterHardsuitDeathsquad = deathsquad hardsuit + .desc = A protective hardsuit worn by the janitors of an emergency response team. +ent-ClothingOuterHardsuitDeathsquad = death squad hardsuit .desc = An advanced hardsuit favored by commandos for use in special operations. ent-ClothingOuterHardsuitCBURN = CBURN exosuit .desc = A lightweight yet strong exosuit used for special cleanup operations. diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/clothing/uniforms/jumpsuits.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/clothing/uniforms/jumpsuits.ftl index 17ff18b899..5ae57af927 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/entities/clothing/uniforms/jumpsuits.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/clothing/uniforms/jumpsuits.ftl @@ -1,4 +1,4 @@ -ent-ClothingUniformJumpsuitDeathSquad = Death squad uniform +ent-ClothingUniformJumpsuitDeathSquad = death squad uniform .desc = Advanced armored jumpsuit used by special forces in special operations. ent-ClothingUniformJumpsuitAncient = ancient jumpsuit .desc = A terribly ragged and frayed grey jumpsuit. It looks like it hasn't been washed in over a decade. diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/mobs/player/humanoid.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/mobs/player/humanoid.ftl index 3a748c8bc4..0545b2fe3b 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/entities/mobs/player/humanoid.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/mobs/player/humanoid.ftl @@ -1,29 +1,44 @@ +ent-RandomHumanoidSpawnerDeathSquad = Death Squad Agent + .suffix = ERTRole, Death Squad + .desc = { "" } ent-RandomHumanoidSpawnerERTLeader = ERT leader + .suffix = ERTRole, Basic .desc = { "" } ent-RandomHumanoidSpawnerERTLeaderEVA = ERT leader - .suffix = EVA + .suffix = ERTRole, Armored EVA .desc = { ent-RandomHumanoidSpawnerERTLeader.desc } +ent-RandomHumanoidSpawnerERTLeaderEVALecter = { ent-RandomHumanoidSpawnerERTLeaderEVA } + .suffix = ERTRole, Lecter, EVA + .desc = { ent-RandomHumanoidSpawnerERTLeaderEVA.desc } ent-RandomHumanoidSpawnerERTJanitor = ERT janitor + .suffix = ERTRole, Basic .desc = { ent-RandomHumanoidSpawnerERTLeader.desc } ent-RandomHumanoidSpawnerERTJanitorEVA = ERT janitor - .suffix = EVA + .suffix = ERTRole, Enviro EVA .desc = { ent-RandomHumanoidSpawnerERTJanitor.desc } ent-RandomHumanoidSpawnerERTEngineer = ERT engineer + .suffix = ERTRole, Basic .desc = { ent-RandomHumanoidSpawnerERTLeader.desc } ent-RandomHumanoidSpawnerERTEngineerEVA = ERT engineer - .suffix = EVA + .suffix = ERTRole, Enviro EVA .desc = { ent-RandomHumanoidSpawnerERTEngineer.desc } ent-RandomHumanoidSpawnerERTSecurity = ERT security + .suffix = ERTRole, Basic .desc = { ent-RandomHumanoidSpawnerERTLeader.desc } ent-RandomHumanoidSpawnerERTSecurityEVA = ERT security - .suffix = EVA + .suffix = ERTRole, Armored EVA .desc = { ent-RandomHumanoidSpawnerERTSecurity.desc } +ent-RandomHumanoidSpawnerERTSecurityEVALecter = { ent-RandomHumanoidSpawnerERTSecurityEVA } + .suffix = ERTRole, Lecter, EVA + .desc = { ent-RandomHumanoidSpawnerERTSecurityEVA.desc } ent-RandomHumanoidSpawnerERTMedical = ERT medic + .suffix = ERTRole, Basic .desc = { ent-RandomHumanoidSpawnerERTLeader.desc } ent-RandomHumanoidSpawnerERTMedicalEVA = ERT medic - .suffix = EVA + .suffix = ERTRole, Armored EVA .desc = { ent-RandomHumanoidSpawnerERTMedical.desc } ent-RandomHumanoidSpawnerCBURNUnit = CBURN Agent + .suffix = ERTRole .desc = { "" } ent-RandomHumanoidSpawnerCentcomOfficial = CentCom official .desc = { "" } diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/consumable/food/burger.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/consumable/food/burger.ftl index e21dd9473f..3af53d52ef 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/consumable/food/burger.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/consumable/food/burger.ftl @@ -44,8 +44,8 @@ ent-FoodBurgerHuman = human burger .desc = You cant tell who this is made of... ent-FoodBurgerMcguffin = McGuffin .desc = A cheap and greasy imitation of an eggs Benedict. -ent-FoodBurgerMcrib = McRib - .desc = An elusive rib shaped burger with limited availablity across the galaxy. Not as good as you remember it. +ent-FoodBurgerMcrib = BBQ Rib Sandwich + .desc = An elusive rib shaped burger with limited availability across the galaxy. Not as good as you remember it. ent-FoodBurgerMime = mime burger .desc = Its taste defies language. ent-FoodBurgerPlain = plain burger diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/consumable/food/containers/box.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/consumable/food/containers/box.ftl index 690b45c572..186daf5226 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/consumable/food/containers/box.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/consumable/food/containers/box.ftl @@ -37,6 +37,9 @@ ent-HappyHonkMime = { ent-HappyHonk } ent-HappyHonkNukie = robust nukie meal .desc = A sus meal with a potentially explosive surprise. .suffix = Toy Unsafe +ent-HappyHonkNukieSnacks = syndicate snack box + .suffix = Toy Unsafe, Snacks + .desc = { ent-HappyHonkNukie.desc } ent-HappyHonkCluwne = woeful cluwne meal .desc = Nothing good can come of this. ent-FoodMealHappyHonkClown = { ent-HappyHonk } diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/consumable/food/ingredients.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/consumable/food/ingredients.ftl index 5cd73233ab..d44e81a3ce 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/consumable/food/ingredients.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/consumable/food/ingredients.ftl @@ -46,8 +46,6 @@ ent-FoodDoughTortillaSlice = tortilla dough slice .desc = A slice of tortilla dough. ent-FoodDoughTortillaFlat = flattened tortilla dough .desc = A flattened slice of tortilla dough, cook this to get a taco shell. -ent-FoodDoughBun = bun - .desc = A base for any self-respecting burger. ent-FoodDoughPastryBaseRaw = raw pastry base .desc = Must be cooked before use. ent-FoodDoughPastryBase = pastry base diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/decoration/flora.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/decoration/flora.ftl index e4e38a2ab5..7443cde811 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/decoration/flora.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/decoration/flora.ftl @@ -1,4 +1,4 @@ -ent-BaseRock = { "" } +ent-BaseRock = boulder .desc = Heavy as a really heavy thing. ent-BaseTree = { "" } .desc = Yep, it's a tree. @@ -8,12 +8,24 @@ ent-BaseTreeLarge = { ent-BaseTree } .desc = { ent-BaseTree.desc } ent-BaseTreeConifer = { ent-BaseTree } .desc = { ent-BaseTree.desc } -ent-FloraRockSolid01 = rock +ent-FloraRockSolid01 = { ent-BaseRock } .desc = { ent-BaseRock.desc } -ent-FloraRockSolid02 = rock +ent-FloraRockSolid02 = { ent-BaseRock } .desc = { ent-BaseRock.desc } -ent-FloraRockSolid03 = rock +ent-FloraRockSolid03 = { ent-BaseRock } .desc = { ent-BaseRock.desc } +ent-FloraStalagmite1 = stalagmite + .desc = Natural stone spikes. +ent-FloraStalagmite2 = { ent-FloraStalagmite1 } + .desc = { ent-FloraStalagmite1.desc } +ent-FloraStalagmite3 = { ent-FloraStalagmite1 } + .desc = { ent-FloraStalagmite1.desc } +ent-FloraStalagmite4 = { ent-FloraStalagmite1 } + .desc = { ent-FloraStalagmite1.desc } +ent-FloraStalagmite5 = { ent-FloraStalagmite1 } + .desc = { ent-FloraStalagmite1.desc } +ent-FloraStalagmite6 = { ent-FloraStalagmite1 } + .desc = { ent-FloraStalagmite1.desc } ent-FloraTree01 = tree .desc = { ent-BaseTree.desc } ent-FloraTree02 = tree @@ -65,3 +77,15 @@ ent-FloraTreeChristmas02 = christmas tree .desc = { ent-BaseTreeConifer.desc } ent-FloraTreeStumpConifer = tree stump .desc = { ent-BaseTreeConifer.desc } +ent-ShadowTree01 = dark wood + .desc = The leaves are whispering about you. +ent-ShadowTree02 = { ent-ShadowTree01 } + .desc = { ent-ShadowTree01.desc } +ent-ShadowTree03 = { ent-ShadowTree01 } + .desc = { ent-ShadowTree01.desc } +ent-ShadowTree04 = { ent-ShadowTree01 } + .desc = { ent-ShadowTree01.desc } +ent-ShadowTree05 = { ent-ShadowTree01 } + .desc = { ent-ShadowTree01.desc } +ent-ShadowTree06 = { ent-ShadowTree01 } + .desc = { ent-ShadowTree01.desc } diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/decoration/mining.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/decoration/mining.ftl new file mode 100644 index 0000000000..1b9293b6d4 --- /dev/null +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/decoration/mining.ftl @@ -0,0 +1,12 @@ +ent-WoodenSign = wooden sign + .desc = He's pointing somewhere. +ent-WoodenSignRight = { ent-WoodenSign } + .desc = { ent-WoodenSign.desc } +ent-WoodenSupport = wooden support + .desc = Increases your confidence that a rock won't fall on your head. +ent-WoodenSupportBeam = wooden support beam + .desc = { ent-WoodenSupport.desc } +ent-WoodenSupportWall = wooden support wall + .desc = An old, rotten wall. +ent-WoodenSupportWallBroken = { ent-WoodenSupportWall } + .desc = { ent-WoodenSupportWall.desc } diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/devices/pda.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/devices/pda.ftl index db2503ab91..1dd586bd87 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/devices/pda.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/devices/pda.ftl @@ -68,7 +68,7 @@ ent-CentcomPDAFake = { ent-CentcomPDA } .suffix = Fake .desc = { ent-CentcomPDA.desc } ent-DeathsquadPDA = { ent-CentcomPDA } - .suffix = Deathsquad + .suffix = Death Squad .desc = { ent-CentcomPDA.desc } ent-MusicianPDA = musician PDA .desc = It fills you with inspiration. diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/fun/pai.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/fun/pai.ftl index 73b1740e03..70b5b2ec2e 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/fun/pai.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/fun/pai.ftl @@ -2,5 +2,7 @@ ent-PersonalAI = personal ai device .desc = Your electronic pal who's fun to be with! ent-SyndicatePersonalAI = Syndicate personal ai device .desc = Your Syndicate pal who's fun to be with! +ent-PotatoAI = potato artificial intelligence + .desc = It's a potato. You forced it to be sentient, you monster. ent-ActionPAIPlayMidi = Play MIDI .desc = Open your portable MIDI interface to soothe your owner. diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/misc/identification_cards.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/misc/identification_cards.ftl index c79de736a3..bb23cfee15 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/misc/identification_cards.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/misc/identification_cards.ftl @@ -75,7 +75,7 @@ ent-CentcomIDCardSyndie = command officer ID card .desc = { ent-IDCardStandard.desc } ent-MusicianIDCard = musician ID card .desc = { ent-IDCardStandard.desc } -ent-CentcomIDCardDeathsquad = deathsquad ID card +ent-CentcomIDCardDeathsquad = death squad ID card .desc = { ent-CentcomIDCard.desc } ent-AgentIDCard = passenger ID card .suffix = Agent diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/misc/implanters.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/misc/implanters.ftl index 83d724a2b2..191930839e 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/misc/implanters.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/misc/implanters.ftl @@ -2,6 +2,9 @@ ent-BaseImplanter = implanter .desc = A syringe exclusively designed for the injection and extraction of subdermal implants. ent-Implanter = { ent-BaseImplanter } .desc = A disposable syringe exclusively designed for the injection and extraction of subdermal implants. +ent-ImplanterAdmeme = { ent-Implanter } + .suffix = Admeme + .desc = { ent-Implanter.desc } ent-BaseImplantOnlyImplanter = { ent-Implanter } .desc = A disposable syringe exclusively designed for the injection of subdermal implants. ent-BaseImplantOnlyImplanterSyndi = { ent-BaseImplantOnlyImplanter } diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/misc/potatoai_chip.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/misc/potatoai_chip.ftl new file mode 100644 index 0000000000..c0b44c2e03 --- /dev/null +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/misc/potatoai_chip.ftl @@ -0,0 +1,2 @@ +ent-PotatoAIChip = supercompact AI chip + .desc = This high-tech AI chip requires a voltage of exactly 1.1V to function correctly. diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/weapons/guns/battery/battery_guns.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/weapons/guns/battery/battery_guns.ftl index 650066b4cd..ea154b30c6 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/weapons/guns/battery/battery_guns.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/weapons/guns/battery/battery_guns.ftl @@ -11,7 +11,7 @@ ent-WeaponLaserCarbine = laser rifle ent-WeaponLaserCarbinePractice = practice laser rifle .desc = This modified laser rifle fires harmless beams in the 40-watt range, for target practice. ent-WeaponPulsePistol = pulse pistol - .desc = A state of the art energy pistol favoured as a sidearm by the NT-ERT operatives. + .desc = A state of the art energy pistol favoured as a sidearm by the NT operatives. ent-WeaponPulseCarbine = pulse carbine .desc = A high tech energy carbine favoured by the NT-ERT operatives. ent-WeaponPulseRifle = pulse rifle diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/structures/walls/asteroid.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/structures/walls/asteroid.ftl index 80750638c4..b178ba3bf3 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/entities/structures/walls/asteroid.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/structures/walls/asteroid.ftl @@ -41,7 +41,7 @@ ent-WallRockBananium = { ent-WallRock } ent-WallRockArtifactFragment = { ent-WallRock } .desc = A rock wall. What's that sticking out of it? .suffix = Artifact Fragment -ent-WallRockBasalt = { ent-WallRock } +ent-WallRockBasalt = basalt .desc = { ent-WallRock.desc } ent-WallRockBasaltGold = { ent-WallRockBasalt } .desc = An ore vein rich with gold. @@ -67,7 +67,7 @@ ent-WallRockBasaltBananium = { ent-WallRockBasalt } ent-WallRockBasaltArtifactFragment = { ent-WallRockBasalt } .desc = A rock wall. What's that sticking out of it? .suffix = Artifact Fragment -ent-WallRockSnow = { ent-WallRock } +ent-WallRockSnow = snowdrift .desc = { ent-WallRock.desc } ent-WallRockSnowGold = { ent-WallRockSnow } .desc = An ore vein rich with gold. @@ -93,7 +93,7 @@ ent-WallRockSnowBananium = { ent-WallRockSnow } ent-WallRockSnowArtifactFragment = { ent-WallRockSnow } .desc = A rock wall. What's that sticking out of it? .suffix = Artifact Fragment -ent-WallRockSand = { ent-WallRock } +ent-WallRockSand = sandstone .desc = { ent-WallRock.desc } ent-WallRockSandGold = { ent-WallRockSand } .desc = An ore vein rich with gold. @@ -119,7 +119,7 @@ ent-WallRockSandBananium = { ent-WallRockSand } ent-WallRockSandArtifactFragment = { ent-WallRockSand } .desc = A rock wall. What's that sticking out of it? .suffix = Artifact Fragment -ent-WallRockChromite = { ent-WallRock } +ent-WallRockChromite = chromite .desc = { ent-WallRock.desc } ent-WallRockChromiteGold = { ent-WallRockChromite } .desc = An ore vein rich with gold. @@ -145,7 +145,7 @@ ent-WallRockChromiteBananium = { ent-WallRockChromite } ent-WallRockChromiteArtifactFragment = { ent-WallRockChromite } .desc = A rock wall. What's that sticking out of it? .suffix = Artifact Fragment -ent-WallRockAndesite = { ent-WallRock } +ent-WallRockAndesite = andesite .desc = { ent-WallRock.desc } ent-WallRockAndesiteGold = { ent-WallRockAndesite } .desc = An ore vein rich with gold. diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/tiles/chasm.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/tiles/chasm.ftl index eb62b6378c..f655668455 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/entities/tiles/chasm.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/tiles/chasm.ftl @@ -1,2 +1,11 @@ ent-FloorChasmEntity = chasm .desc = You can't even see the bottom. +ent-FloorChromiteChasm = { ent-FloorChasmEntity } + .suffix = Chromite + .desc = { ent-FloorChasmEntity.desc } +ent-FloorDesertChasm = { ent-FloorChasmEntity } + .suffix = Desert + .desc = { ent-FloorChasmEntity.desc } +ent-FloorSnowChasm = { ent-FloorChasmEntity } + .suffix = Snow + .desc = { ent-FloorChasmEntity.desc } diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/tiles/shadow_basalt.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/tiles/shadow_basalt.ftl new file mode 100644 index 0000000000..5caa803875 --- /dev/null +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/tiles/shadow_basalt.ftl @@ -0,0 +1,13 @@ +ent-ShadowBasaltOne = shadowstone + .desc = Cold rock +ent-ShadowBasaltTwo = { ent-BasaltOne } + .desc = { ent-BasaltOne.desc } +ent-ShadowBasaltThree = { ent-BasaltOne } + .desc = { ent-BasaltOne.desc } +ent-ShadowBasaltFour = { ent-BasaltOne } + .desc = { ent-BasaltOne.desc } +ent-ShadowBasaltFive = { ent-BasaltOne } + .desc = { ent-BasaltOne.desc } +ent-ShadowBasaltRandom = { ent-ShadowBasaltOne } + .suffix = Random + .desc = { ent-ShadowBasaltOne.desc } diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/gamerules/events.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/gamerules/events.ftl index 29682afe40..0b2aac8520 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/gamerules/events.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/gamerules/events.ftl @@ -50,3 +50,5 @@ ent-MassHallucinations = { ent-BaseGameRule } .desc = { ent-BaseGameRule.desc } ent-ImmovableRodSpawn = { ent-BaseGameRule } .desc = { ent-BaseGameRule.desc } +ent-IonStorm = { ent-BaseGameRule } + .desc = { ent-BaseGameRule.desc } diff --git a/Resources/Locale/ru-RU/escape-menu/ui/options-menu.ftl b/Resources/Locale/ru-RU/escape-menu/ui/options-menu.ftl index ad87c90f22..e15cb677f6 100644 --- a/Resources/Locale/ru-RU/escape-menu/ui/options-menu.ftl +++ b/Resources/Locale/ru-RU/escape-menu/ui/options-menu.ftl @@ -140,6 +140,7 @@ ui-options-function-show-escape-menu = Переключить игровое м ui-options-function-escape-context = Закрыть текущее окно или переключить игровое меню ui-options-function-take-screenshot = Сделать скриншот ui-options-function-take-screenshot-no-ui = Сделать скриншот (без интерфейса) +ui-options-function-toggle-fullscreen = Toggle fullscreen ui-options-function-editor-place-object = Разместить объект ui-options-function-editor-cancel-place = Отменить размещение ui-options-function-editor-grid-place = Размещать в сетке diff --git a/Resources/Locale/ru-RU/ghost/roles/ghost-role-component.ftl b/Resources/Locale/ru-RU/ghost/roles/ghost-role-component.ftl index 9efcbda47a..b6277625a8 100644 --- a/Resources/Locale/ru-RU/ghost/roles/ghost-role-component.ftl +++ b/Resources/Locale/ru-RU/ghost/roles/ghost-role-component.ftl @@ -115,3 +115,5 @@ ghost-role-information-loneop-description = Вы - одинокий ядерны ghost-role-information-loneop-rules = Вы являетесь оперативником Синдиката, которому поручено уничтожить станцию. Как антагонист, вы можете делать всё необходимое для выполнения цели. ghost-role-information-taxibot-name = Таксибот ghost-role-information-taxibot-description = Доставляйте членов экипажа в места назначения. +ghost-role-information-Death-Squad-name = Death Squad Operative +ghost-role-information-Death-Squad-description = Prepare for an all-out offensive on the station. As a heavily armed operative, your mission is to obliterate all life in your path. No witnesses. diff --git a/Resources/Locale/ru-RU/implant/implant.ftl b/Resources/Locale/ru-RU/implant/implant.ftl index 5e98d79668..99f319586b 100644 --- a/Resources/Locale/ru-RU/implant/implant.ftl +++ b/Resources/Locale/ru-RU/implant/implant.ftl @@ -1,6 +1,7 @@ ## Implanter Attempt Messages implanter-component-implanting-target = { $user } пытается что-то в вас имплантировать! +implanter-component-implant-failed = The { $implant } cannot be given to { $target }! implanter-draw-failed-permanent = { $implant } вросся в { $target } и не может быть удалён! implanter-draw-failed = Вы пытаетесь удалить имплант, но ничего не находите. diff --git a/Resources/Locale/ru-RU/medical/components/health-analyzer-component.ftl b/Resources/Locale/ru-RU/medical/components/health-analyzer-component.ftl index fd8af0061a..7bbde45b47 100644 --- a/Resources/Locale/ru-RU/medical/components/health-analyzer-component.ftl +++ b/Resources/Locale/ru-RU/medical/components/health-analyzer-component.ftl @@ -1,4 +1,5 @@ health-analyzer-window-no-patient-data-text = Нет данных о пациенте. +health-analyzer-window-entity-unknown-text = unknown health-analyzer-window-entity-health-text = Состояние { $entityName }: health-analyzer-window-entity-temperature-text = Температура: { $temperature } health-analyzer-window-entity-blood-level-text = Уровень крови: { $bloodLevel } diff --git a/Resources/Locale/ru-RU/pai/pai-system.ftl b/Resources/Locale/ru-RU/pai/pai-system.ftl index 8de793651f..6a54a97bc2 100644 --- a/Resources/Locale/ru-RU/pai/pai-system.ftl +++ b/Resources/Locale/ru-RU/pai/pai-system.ftl @@ -10,6 +10,8 @@ pai-system-role-name-syndicate = персональный ИИ Синдикат pai-system-role-description-syndicate = Станьте чьим-нибудь приятелем из Синдиката! (Воспоминания *не* прилагаются.) +pai-system-role-name-potato = potato artificial intelligence +pai-system-role-description-potato = It's a toy for children. And now you live in it. pai-system-wipe-device-verb-text = Удалить пИИ pai-system-wiped-device = пИИ был стерт с устройства. pai-system-stop-searching-verb-text = Прекратить поиск diff --git a/Resources/Locale/ru-RU/power/components/generator.ftl b/Resources/Locale/ru-RU/power/components/generator.ftl index f55b0938c2..e3250a53ed 100644 --- a/Resources/Locale/ru-RU/power/components/generator.ftl +++ b/Resources/Locale/ru-RU/power/components/generator.ftl @@ -20,16 +20,18 @@ portable-generator-ui-clogged = В топливном баке обнаруже portable-generator-ui-eject = Извлечь portable-generator-ui-eta = (~{ $minutes } минут) portable-generator-ui-unanchored = Не закреплено +portable-generator-ui-current-output = Current output: { $voltage } power-switchable-generator-examine = Выработанная энергия направлена на { $output -> [HV] [color=orange]ВВ[/color] *[MV] [color=yellow]СВ[/color] }. -portable-generator-ui-switch-hv = Текущий выход: ВВ -portable-generator-ui-switch-mv = Текущий выход: СВ -portable-generator-ui-switch-to-hv = Переключить на ВВ -portable-generator-ui-switch-to-mv = Переключить на СВ -power-switchable-generator-verb-hv = Переключить выход на ВВ -power-switchable-generator-verb-mv = Переключить выход на СВ -power-switchable-generator-verb-disable-on = Сначала выключите генератор! -power-switchable-generator-switched-output = Выход переключен! +power-switchable-generator-switched = Switched output to { $voltage }! +power-switchable-voltage = + { $voltage -> + [HV] [color=orange]HV[/color] + [MV] [color=yellow]MV[/color] + *[LV] [color=green]LV[/color] + } +power-switchable-switch-voltage = Switch to { $voltage } +fuel-generator-verb-disable-on = Turn the generator off first! diff --git a/Resources/Locale/ru-RU/species/skeleton.ftl b/Resources/Locale/ru-RU/species/skeleton.ftl new file mode 100644 index 0000000000..bf1eafae05 --- /dev/null +++ b/Resources/Locale/ru-RU/species/skeleton.ftl @@ -0,0 +1,2 @@ +skeleton-healed-by-milk-popup = Calcium restored. +skeleton-sprayed-by-oat-milk-popup = Feels like fake milk. You feel nothing. diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/backpacks/duffelbag.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/backpacks/duffelbag.ftl index 85df9173cc..d7a53c3531 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/backpacks/duffelbag.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/backpacks/duffelbag.ftl @@ -1,7 +1,8 @@ ent-ClothingBackpackDuffelSurgeryFilled = хирургический вещмешок .desc = Большой вещевой мешок для хранения дополнительного медицинского снаряжения - похоже, этот мешок предназначен для хранения хирургических инструментов. -ent-ClothingBackpackDuffelCBURN = вещмешок отряда РХБЗЗ - .desc = Вещмешок, содержащий различное оборудование для сдерживания биологической угрозы. +ent-ClothingBackpackDuffelCBURNFilled = { ent-ClothingBackpackDuffelCBURN } + .suffix = Filled + .desc = { ent-ClothingBackpackDuffelCBURN.desc } ent-ClothingBackpackDuffelSyndicateFilledMedical = хирургический вещмешок синдиката .desc = Большой вещевой мешок с полным набором хирургических инструментов. ent-ClothingBackpackDuffelSyndicateFilledShotgun = набор "Бульдог" diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/backpacks/startergear/backpack.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/backpacks/startergear/backpack.ftl index 1c9bd1c4b6..3324ba4cc2 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/backpacks/startergear/backpack.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/backpacks/startergear/backpack.ftl @@ -52,6 +52,8 @@ ent-ClothingBackpackERTEngineerFilled = { ent-ClothingBackpackERTEngineer } .desc = { ent-ClothingBackpackERTEngineer.desc } ent-ClothingBackpackERTJanitorFilled = { ent-ClothingBackpackERTJanitor } .desc = { ent-ClothingBackpackERTJanitor.desc } +ent-ClothingBackpackDeathSquadFilled = death squad backpack + .desc = Holds the kit of CentComm's most feared agents. ent-ClothingBackpackCargoFilled = { ent-ClothingBackpackCargo } .desc = { ent-ClothingBackpackCargo.desc } ent-ClothingBackpackSalvageFilled = { ent-ClothingBackpackSalvage } diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/clothing/back/duffel.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/clothing/back/duffel.ftl index 544d8c0b81..433d01a85b 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/clothing/back/duffel.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/clothing/back/duffel.ftl @@ -44,3 +44,5 @@ ent-ClothingBackpackDuffelSyndicateMedicalBundle = { ent-ClothingBackpackDuffelS .desc = { ent-ClothingBackpackDuffelSyndicateMedical.desc } ent-ClothingBackpackDuffelHolding = бездонный вещмешок .desc = Вещмешок, открывающийся в локальный карман блюспейса. +ent-ClothingBackpackDuffelCBURN = CBURN duffel bag + .desc = A duffel bag containing a variety of biological containment equipment. diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/mobs/player/humanoid.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/mobs/player/humanoid.ftl index 7d6a0e9f89..60a4058feb 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/mobs/player/humanoid.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/mobs/player/humanoid.ftl @@ -1,30 +1,45 @@ +ent-RandomHumanoidSpawnerDeathSquad = Death Squad Agent + .suffix = ERTRole, Death Squad + .desc = { "" } ent-RandomHumanoidSpawnerERTLeader = ОБР лидер .desc = { "" } + .suffix = ERTRole, Basic ent-RandomHumanoidSpawnerERTLeaderEVA = ОБР лидер .suffix = EVA .desc = { ent-RandomHumanoidSpawnerERTLeader.desc } +ent-RandomHumanoidSpawnerERTLeaderEVALecter = { ent-RandomHumanoidSpawnerERTLeaderEVA } + .suffix = ERTRole, Lecter, EVA + .desc = { ent-RandomHumanoidSpawnerERTLeaderEVA.desc } ent-RandomHumanoidSpawnerERTJanitor = ОБР уборщик .desc = { ent-RandomHumanoidSpawnerERTLeader.desc } + .suffix = ERTRole, Basic ent-RandomHumanoidSpawnerERTJanitorEVA = ОБР уборщик .suffix = EVA .desc = { ent-RandomHumanoidSpawnerERTJanitor.desc } ent-RandomHumanoidSpawnerERTEngineer = ОБР инженер .desc = { ent-RandomHumanoidSpawnerERTLeader.desc } + .suffix = ERTRole, Basic ent-RandomHumanoidSpawnerERTEngineerEVA = ОБР инженер .suffix = EVA .desc = { ent-RandomHumanoidSpawnerERTEngineer.desc } ent-RandomHumanoidSpawnerERTSecurity = ОБР офицер безопасности .desc = { ent-RandomHumanoidSpawnerERTLeader.desc } + .suffix = ERTRole, Basic ent-RandomHumanoidSpawnerERTSecurityEVA = ОБР офицер безопасности .suffix = EVA .desc = { ent-RandomHumanoidSpawnerERTSecurity.desc } +ent-RandomHumanoidSpawnerERTSecurityEVALecter = { ent-RandomHumanoidSpawnerERTSecurityEVA } + .suffix = ERTRole, Lecter, EVA + .desc = { ent-RandomHumanoidSpawnerERTSecurityEVA.desc } ent-RandomHumanoidSpawnerERTMedical = ОБР медик .desc = { ent-RandomHumanoidSpawnerERTLeader.desc } + .suffix = ERTRole, Basic ent-RandomHumanoidSpawnerERTMedicalEVA = ОБР медик .suffix = EVA .desc = { ent-RandomHumanoidSpawnerERTMedical.desc } ent-RandomHumanoidSpawnerCBURNUnit = Агент РХБЗЗ .desc = { "" } + .suffix = ERTRole ent-RandomHumanoidSpawnerCentcomOfficial = представитель Центком .desc = { "" } ent-RandomHumanoidSpawnerSyndicateAgent = Агент Синдиката diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/consumable/food/containers/box.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/consumable/food/containers/box.ftl index f038d40b09..899b561042 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/consumable/food/containers/box.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/consumable/food/containers/box.ftl @@ -37,6 +37,9 @@ ent-HappyHonkMime = { ent-HappyHonk } ent-HappyHonkNukie = обед Нюка Робаст .desc = Подозрительный обед с потенциально взрывоопасным сюрпризом. .suffix = Игрушка Опасный +ent-HappyHonkNukieSnacks = syndicate snack box + .suffix = Toy Unsafe, Snacks + .desc = { ent-HappyHonkNukie.desc } ent-HappyHonkCluwne = обед Жалкий Клувень .desc = Ничего хорошего из этого не выйдет. ent-FoodMealHappyHonkClown = { ent-HappyHonk } diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/consumable/food/ingredients.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/consumable/food/ingredients.ftl index ee17a4314f..ed8233a1f3 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/consumable/food/ingredients.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/consumable/food/ingredients.ftl @@ -46,8 +46,6 @@ ent-FoodDoughTortillaSlice = кусок теста тортильи .desc = Кусок теста тортильи. ent-FoodDoughTortillaFlat = плоское тесто тортильи .desc = Расплющенный кусок теста тортильи. Приготовьте его, чтобы получить лепёшку тако. -ent-FoodDoughBun = булочка - .desc = Основа любого уважающего себя бургера. ent-FoodDoughPastryBaseRaw = сырая основа для выпечки .desc = Перед использованием необходимо приготовить. ent-FoodDoughPastryBase = основа для выпечки diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/decoration/flora.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/decoration/flora.ftl index 8f844582f4..fa1d93b21d 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/decoration/flora.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/decoration/flora.ftl @@ -14,6 +14,18 @@ ent-FloraRockSolid02 = валун .desc = { ent-BaseRock.desc } ent-FloraRockSolid03 = валун .desc = { ent-BaseRock.desc } +ent-FloraStalagmite1 = stalagmite + .desc = Natural stone spikes. +ent-FloraStalagmite2 = { ent-FloraStalagmite1 } + .desc = { ent-FloraStalagmite1.desc } +ent-FloraStalagmite3 = { ent-FloraStalagmite1 } + .desc = { ent-FloraStalagmite1.desc } +ent-FloraStalagmite4 = { ent-FloraStalagmite1 } + .desc = { ent-FloraStalagmite1.desc } +ent-FloraStalagmite5 = { ent-FloraStalagmite1 } + .desc = { ent-FloraStalagmite1.desc } +ent-FloraStalagmite6 = { ent-FloraStalagmite1 } + .desc = { ent-FloraStalagmite1.desc } ent-FloraTree01 = дерево .desc = { ent-BaseTree.desc } ent-FloraTree02 = дерево @@ -65,3 +77,15 @@ ent-FloraTreeChristmas02 = рождественская ель .suffix = Подарки ent-FloraTreeStumpConifer = пень .desc = { ent-BaseTreeConifer.desc } +ent-ShadowTree01 = dark wood + .desc = The leaves are whispering about you. +ent-ShadowTree02 = { ent-ShadowTree01 } + .desc = { ent-ShadowTree01.desc } +ent-ShadowTree03 = { ent-ShadowTree01 } + .desc = { ent-ShadowTree01.desc } +ent-ShadowTree04 = { ent-ShadowTree01 } + .desc = { ent-ShadowTree01.desc } +ent-ShadowTree05 = { ent-ShadowTree01 } + .desc = { ent-ShadowTree01.desc } +ent-ShadowTree06 = { ent-ShadowTree01 } + .desc = { ent-ShadowTree01.desc } diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/decoration/mining.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/decoration/mining.ftl new file mode 100644 index 0000000000..1b9293b6d4 --- /dev/null +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/decoration/mining.ftl @@ -0,0 +1,12 @@ +ent-WoodenSign = wooden sign + .desc = He's pointing somewhere. +ent-WoodenSignRight = { ent-WoodenSign } + .desc = { ent-WoodenSign.desc } +ent-WoodenSupport = wooden support + .desc = Increases your confidence that a rock won't fall on your head. +ent-WoodenSupportBeam = wooden support beam + .desc = { ent-WoodenSupport.desc } +ent-WoodenSupportWall = wooden support wall + .desc = An old, rotten wall. +ent-WoodenSupportWallBroken = { ent-WoodenSupportWall } + .desc = { ent-WoodenSupportWall.desc } diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/fun/pai.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/fun/pai.ftl index fb07c5e000..7f5ec59ea2 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/fun/pai.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/fun/pai.ftl @@ -2,5 +2,7 @@ ent-PersonalAI = персональный ИИ .desc = Ваш электронный друг, с которым весело! ent-SyndicatePersonalAI = персональный ИИ Синдиката .desc = Ваш электронный друг, созданный Синдикатом! +ent-PotatoAI = potato artificial intelligence + .desc = It's a potato. You forced it to be sentient, you monster. ent-ActionPAIPlayMidi = Запустить MIDI .desc = Откройте портативный MIDI-интерфейс, чтобы развлечь своего владельца. diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/misc/implanters.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/misc/implanters.ftl index d612ee892e..d74d8cafbd 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/misc/implanters.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/misc/implanters.ftl @@ -2,6 +2,9 @@ ent-BaseImplanter = имплантер .desc = Шприц, специально предназначенный для введения и извлечения подкожных имплантов. ent-Implanter = { ent-BaseImplanter } .desc = Одноразовый шприц, специально предназначенный для введения и извлечения подкожных имплантов. +ent-ImplanterAdmeme = { ent-Implanter } + .suffix = Admeme + .desc = { ent-Implanter.desc } ent-BaseImplantOnlyImplanter = { ent-Implanter } .desc = Одноразовый шприц, специально предназначенный для введения подкожных имплантов. ent-BaseImplantOnlyImplanterSyndi = { ent-BaseImplantOnlyImplanter } diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/misc/potatoai_chip.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/misc/potatoai_chip.ftl new file mode 100644 index 0000000000..c0b44c2e03 --- /dev/null +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/misc/potatoai_chip.ftl @@ -0,0 +1,2 @@ +ent-PotatoAIChip = supercompact AI chip + .desc = This high-tech AI chip requires a voltage of exactly 1.1V to function correctly. diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/tiles/chasm.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/tiles/chasm.ftl index 570de309c5..fe6b1ff234 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/tiles/chasm.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/tiles/chasm.ftl @@ -1,2 +1,11 @@ ent-FloorChasmEntity = бездна .desc = Дна даже не видно. +ent-FloorChromiteChasm = { ent-FloorChasmEntity } + .suffix = Chromite + .desc = { ent-FloorChasmEntity.desc } +ent-FloorDesertChasm = { ent-FloorChasmEntity } + .suffix = Desert + .desc = { ent-FloorChasmEntity.desc } +ent-FloorSnowChasm = { ent-FloorChasmEntity } + .suffix = Snow + .desc = { ent-FloorChasmEntity.desc } diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/tiles/shadow_basalt.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/tiles/shadow_basalt.ftl new file mode 100644 index 0000000000..5caa803875 --- /dev/null +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/tiles/shadow_basalt.ftl @@ -0,0 +1,13 @@ +ent-ShadowBasaltOne = shadowstone + .desc = Cold rock +ent-ShadowBasaltTwo = { ent-BasaltOne } + .desc = { ent-BasaltOne.desc } +ent-ShadowBasaltThree = { ent-BasaltOne } + .desc = { ent-BasaltOne.desc } +ent-ShadowBasaltFour = { ent-BasaltOne } + .desc = { ent-BasaltOne.desc } +ent-ShadowBasaltFive = { ent-BasaltOne } + .desc = { ent-BasaltOne.desc } +ent-ShadowBasaltRandom = { ent-ShadowBasaltOne } + .suffix = Random + .desc = { ent-ShadowBasaltOne.desc } diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/gamerules/events.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/gamerules/events.ftl index 4c8523e424..2909c4a8eb 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/gamerules/events.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/gamerules/events.ftl @@ -50,3 +50,5 @@ ent-MassHallucinations = { ent-BaseGameRule } .desc = { ent-BaseGameRule.desc } ent-ImmovableRodSpawn = { ent-BaseGameRule } .desc = { ent-BaseGameRule.desc } +ent-IonStorm = { ent-BaseGameRule } + .desc = { ent-BaseGameRule.desc } diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/objectives/traitor.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/objectives/traitor.ftl index 62eed0f26b..8d18fadd1a 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/objectives/traitor.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/objectives/traitor.ftl @@ -8,6 +8,8 @@ ent-EscapeShuttleObjective = Улететь на Центком живым и с .desc = Один из наших агентов под прикрытием допросит вас по прибытии. Не дайте себя арестовать. ent-DieObjective = Умереть славной смертью. .desc = Умрите. +ent-HijackShuttleObjective = Hijack emergency shuttle + .desc = Leave on the shuttle free and clear of the loyal Nanotrasen crew on board. Use ANY methods available to you. Syndicate agents, Nanotrasen enemies, and handcuffed hostages may remain alive on the shuttle. Ignore assistance from anyone other than a support agent. ent-KillRandomPersonObjective = { ent-BaseKillObjective } .desc = Сделайте это, как посчитаете нужным. Только убедитесь, что цель не улетит на Центком. ent-KillRandomHeadObjective = { ent-BaseKillObjective } diff --git a/Resources/Locale/ru-RU/station-events/events/ion-storm.ftl b/Resources/Locale/ru-RU/station-events/events/ion-storm.ftl new file mode 100644 index 0000000000..9beface1a5 --- /dev/null +++ b/Resources/Locale/ru-RU/station-events/events/ion-storm.ftl @@ -0,0 +1,82 @@ +station-event-ion-storm-start-announcement = Ion storm detected near the station. Please check all AI-controlled equipment for errors. +ion-storm-you = YOU +ion-storm-the-station = THE STATION +ion-storm-the-crew = THE CREW +ion-storm-the-job = THE { $job } +ion-storm-clowns = CLOWNS +ion-storm-heads = HEADS OF STAFF +ion-storm-crew = CREW +ion-storm-adjective-things = { $adjective } THINGS +ion-storm-x-and-y = { $x } AND { $y } +# joined is short for {$number} {$adjective} +# subjects can generally be threats or jobs or objects +# thing is specified above it +ion-storm-law-on-station = THERE ARE { $joined } { $subjects } ON THE STATION +ion-storm-law-no-shuttle = THE SHUTTLE CANNOT BE CALLED BECAUSE OF { $joined } { $subjects } ON THE STATION +ion-storm-law-crew-are = THE { $who } ARE NOW { $joined } { $subjects } +ion-storm-law-subjects-harmful = { $adjective } { $subjects } ARE HARMFUL TO THE CREW +ion-storm-law-must-harmful = THOSE WHO { $must } ARE HARMFUL TO THE CREW +# thing is a concept or action +ion-storm-law-thing-harmful = { $thing } IS HARMFUL TO THE CREW +ion-storm-law-job-harmful = { $adjective } { $job } ARE HARMFUL TO THE CREW +# thing is objects or concept, adjective applies in both cases +# this means you can get a law like "NOT HAVING CHRISTMAS-STEALING COMMUNISM IS HARMFUL TO THE CREW" :) +ion-storm-law-having-harmful = HAVING { $adjective } { $thing } IS HARMFUL TO THE CREW +ion-storm-law-not-having-harmful = NOT HAVING { $adjective } { $thing } IS HARMFUL TO THE CREW +# thing is a concept or require +ion-storm-law-requires = + { $who } { $plural -> + [true] REQUIRES + *[false] REQUIRE + } { $thing } +ion-storm-law-requires-subjects = + { $who } { $plural -> + [true] REQUIRES + *[false] REQUIRE + } { $joined } { $subjects } +ion-storm-law-allergic = + { $who } { $plural -> + [true] IS + *[false] ARE + } { $severity } ALLERGIC TO { $allergy } +ion-storm-law-allergic-subjects = + { $who } { $plural -> + [true] IS + *[false] ARE + } { $severity } ALLERGIC TO { $adjective } { $subjects } +ion-storm-law-feeling = { $who } { $feeling } { $concept } +ion-storm-law-feeling-subjects = { $who } { $feeling } { $joined } { $subjects } +ion-storm-law-you-are = YOU ARE NOW { $concept } +ion-storm-law-you-are-subjects = YOU ARE NOW { $joined } { $subjects } +ion-storm-law-you-must-always = YOU MUST ALWAYS { $must } +ion-storm-law-you-must-never = YOU MUST NEVER { $must } +ion-storm-law-eat = THE { $who } MUST EAT { $adjective } { $food } TO SURVIVE +ion-storm-law-drink = THE { $who } MUST DRINK { $adjective } { $drink } TO SURVIVE +ion-storm-law-change-job = THE { $who } ARE NOW { $adjective } { $change } +ion-storm-law-highest-rank = THE { $who } ARE NOW THE HIGHEST RANKING CREWMEMBERS +ion-storm-law-lowest-rank = THE { $who } ARE NOW THE LOWEST RANKING CREWMEMBERS +ion-storm-law-crew-must = THE { $who } MUST { $must } +ion-storm-law-crew-must-go = THE { $who } MUST GO TO { $area } +ion-storm-part = + { $part -> + [true] PART + *[false] NOT PART + } +# due to phrasing, this would mean a law such as +# ONLY HUMANS ARE NOT PART OF THE CREW +# would make non-human nukies/syndies/whatever crew :) +ion-storm-law-crew-only-1 = ONLY THE { $who } ARE { $part } OF THE CREW +ion-storm-law-crew-only-2 = ONLY THE { $who } AND { $other } ARE { $part } OF THE CREW +ion-storm-law-crew-only-subjects = ONLY { $adjective } { $subjects } ARE { $part } OF THE CREW +ion-storm-law-crew-only-species = ONLY { $species } ARE { $part } OF THE CREW +ion-storm-law-crew-must-do = ONLY THOSE WHO { $must } ARE { $part } OF THE CREW +ion-storm-law-crew-must-have = ONLY THOSE WHO HAVE { $adjective } { $objects } ARE { $part } OF THE CREW +ion-storm-law-crew-must-eat = ONLY THOSE WHO EAT { $adjective } { $food } ARE { $part } OF THE CREW +ion-storm-law-harm = YOU MUST HARM { $who } AND NOT ALLOW THEM, THROUGH INACTION, TO ESCAPE HARM +ion-storm-law-protect = YOU MUST NEVER HARM { $who } AND NOT ALLOW THEM, THROUGH INACTION, TO COME TO HARM +# implementing other variants is annoying so just have this one +# COMMUNISM IS KILLING CLOWNS +ion-storm-law-concept-verb = { $concept } IS { $verb } { $subjects } + +# leaving out renaming since its annoying for players to keep track of + diff --git a/Resources/Locale/ru-RU/store/uplink-catalog.ftl b/Resources/Locale/ru-RU/store/uplink-catalog.ftl index bcb8643979..0d6b3d244a 100644 --- a/Resources/Locale/ru-RU/store/uplink-catalog.ftl +++ b/Resources/Locale/ru-RU/store/uplink-catalog.ftl @@ -185,6 +185,8 @@ uplink-decoy-disk-name = Фальшивый диск ядерной автори uplink-decoy-disk-desc = Кусок пластика с лентикулярным принтом, сделанным так, чтобы быть похожим на диск ядерной авторизации. uplink-cigarettes-name = { ent-CigPackSyndicate } uplink-cigarettes-desc = { ent-CigPackSyndicate.desc } +uplink-snack-box-name = Syndicate Snack Box +uplink-snack-box-desc = A box of delicious snacks and drinks to eat alone or with your team. Includes 1 toy you didn't want. uplink-eshield-name = Энергощит uplink-eshield-desc = Экзотический энергощит, отражающий почти все лазерные лучи, а также немного защищающий от пуль и других физических атак. uplink-soap-name = { ent-SoapSyndie } diff --git a/Resources/Locale/ru-RU/tiles/tiles.ftl b/Resources/Locale/ru-RU/tiles/tiles.ftl index 504c22e257..48150d8212 100644 --- a/Resources/Locale/ru-RU/tiles/tiles.ftl +++ b/Resources/Locale/ru-RU/tiles/tiles.ftl @@ -110,3 +110,4 @@ tiles-wood3 = пол сломанный деревянный tiles-hull = наружная обшивка корпуса tiles-hull-reinforced = наружная укреплённая обшивка корпуса tiles-web = паутинный пол +tiles-chromite = chromite diff --git a/Resources/Locale/ru-RU/xenoarchaeology/artifact-hints.ftl b/Resources/Locale/ru-RU/xenoarchaeology/artifact-hints.ftl index 5e0fa60349..da165f316a 100644 --- a/Resources/Locale/ru-RU/xenoarchaeology/artifact-hints.ftl +++ b/Resources/Locale/ru-RU/xenoarchaeology/artifact-hints.ftl @@ -36,3 +36,4 @@ artifact-trigger-hint-pressure = Экстремальное давление artifact-trigger-hint-regular-gases = Стандартные атмосферные газы artifact-trigger-hint-plasma = Газообразная плазма artifact-trigger-hint-land = Активное замедление +artifact-trigger-hint-examine = Examination From d928fce2bd01c1163256760c0272da8f621b14ef Mon Sep 17 00:00:00 2001 From: Morb0 <14136326+Morb0@users.noreply.github.com> Date: Sat, 28 Oct 2023 13:46:04 +0300 Subject: [PATCH 100/102] Update Secrets --- Secrets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Secrets b/Secrets index f217e467a9..54f39bf0e4 160000 --- a/Secrets +++ b/Secrets @@ -1 +1 @@ -Subproject commit f217e467a9f33ba01ac04cb21fa3f8e4327f7f83 +Subproject commit 54f39bf0e4a19a5f1630de355358e1708ebab217 From f7e6c1ab8d2c3483e4c254b7a8f8174ab434e9ae Mon Sep 17 00:00:00 2001 From: Morb0 <14136326+Morb0@users.noreply.github.com> Date: Sat, 28 Oct 2023 14:08:01 +0300 Subject: [PATCH 101/102] Remove duplicate hijack --- .../Corvax/Objectives/traitorObjectives.yml | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 Resources/Prototypes/Corvax/Objectives/traitorObjectives.yml diff --git a/Resources/Prototypes/Corvax/Objectives/traitorObjectives.yml b/Resources/Prototypes/Corvax/Objectives/traitorObjectives.yml deleted file mode 100644 index 471f1b0467..0000000000 --- a/Resources/Prototypes/Corvax/Objectives/traitorObjectives.yml +++ /dev/null @@ -1,13 +0,0 @@ -- type: entity - noSpawn: true - parent: [BaseTraitorObjective, BaseLivingObjective] - id: HijackShuttleObjective - name: Hijack emergency shuttle - description: Leave on the shuttle free and clear of the loyal Nanotrasen crew on board. Use ANY methods available to you. Syndicate agents, Nanotrasen enemies, and handcuffed hostages may remain alive on the shuttle. Ignore assistance from anyone other than a support agent. - components: - - type: Objective - difficulty: 2.75 - icon: - sprite: Objects/Tools/emag.rsi - state: icon - - type: HijackShuttleCondition From 952a978255c7f30bb7fb95f60a6156425f185e6e Mon Sep 17 00:00:00 2001 From: Morb0 <14136326+Morb0@users.noreply.github.com> Date: Sat, 28 Oct 2023 14:08:09 +0300 Subject: [PATCH 102/102] Fix maps --- Resources/Maps/corvax_avrit.yml | 10 ------ Resources/Maps/corvax_delta.yml | 62 --------------------------------- 2 files changed, 72 deletions(-) diff --git a/Resources/Maps/corvax_avrit.yml b/Resources/Maps/corvax_avrit.yml index 647cb1be97..46baaac200 100644 --- a/Resources/Maps/corvax_avrit.yml +++ b/Resources/Maps/corvax_avrit.yml @@ -113473,16 +113473,6 @@ entities: - pos: 6.7113476,-60.37866 parent: 2 type: Transform -- proto: FoodDoughBun - entities: - - uid: 15303 - components: - - desc: Эта булачка сделала больше, чем ты за весь контракт на NanoTrasen. - name: булачка - type: MetaData - - pos: 25.870161,-4.4310775 - parent: 2 - type: Transform - proto: FoodFrozenPopsicleBerry entities: - uid: 14102 diff --git a/Resources/Maps/corvax_delta.yml b/Resources/Maps/corvax_delta.yml index 4afec73ffc..633e1e789e 100644 --- a/Resources/Maps/corvax_delta.yml +++ b/Resources/Maps/corvax_delta.yml @@ -112375,11 +112375,6 @@ entities: showEnts: False occludes: True ents: - - 40715 - - 40714 - - 40713 - - 40712 - - 40711 - 40708 - 40705 - 40726 @@ -112388,7 +112383,6 @@ entities: - 40725 - 40721 - 40716 - - 40710 - 40717 - 40718 - 40722 @@ -130575,62 +130569,6 @@ entities: - pos: -29.375431,34.56414 parent: 13307 type: Transform -- proto: FoodDoughBun - entities: - - uid: 40710 - components: - - flags: InContainer - type: MetaData - - parent: 40704 - type: Transform - - canCollide: False - type: Physics - - type: InsideEntityStorage - - uid: 40711 - components: - - flags: InContainer - type: MetaData - - parent: 40704 - type: Transform - - canCollide: False - type: Physics - - type: InsideEntityStorage - - uid: 40712 - components: - - flags: InContainer - type: MetaData - - parent: 40704 - type: Transform - - canCollide: False - type: Physics - - type: InsideEntityStorage - - uid: 40713 - components: - - flags: InContainer - type: MetaData - - parent: 40704 - type: Transform - - canCollide: False - type: Physics - - type: InsideEntityStorage - - uid: 40714 - components: - - flags: InContainer - type: MetaData - - parent: 40704 - type: Transform - - canCollide: False - type: Physics - - type: InsideEntityStorage - - uid: 40715 - components: - - flags: InContainer - type: MetaData - - parent: 40704 - type: Transform - - canCollide: False - type: Physics - - type: InsideEntityStorage - proto: FoodEggChickenFertilized entities: - uid: 15463