1
0

AdminVerbSystem.Smites.cs 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929
  1. using System.Threading;
  2. using Content.Server.Administration.Commands;
  3. using Content.Server.Administration.Components;
  4. using Content.Server.Atmos.Components;
  5. using Content.Server.Atmos.EntitySystems;
  6. using Content.Server.Body.Components;
  7. using Content.Server.Body.Systems;
  8. using Content.Server.Electrocution;
  9. using Content.Server.Explosion.EntitySystems;
  10. using Content.Server.GhostKick;
  11. using Content.Server.Medical;
  12. using Content.Server.Nutrition.EntitySystems;
  13. using Content.Server.Pointing.Components;
  14. using Content.Server.Polymorph.Systems;
  15. using Content.Server.Popups;
  16. using Content.Server.Speech.Components;
  17. using Content.Server.Storage.Components;
  18. using Content.Server.Storage.EntitySystems;
  19. using Content.Server.Tabletop;
  20. using Content.Server.Tabletop.Components;
  21. using Content.Shared.Administration;
  22. using Content.Shared.Administration.Components;
  23. using Content.Shared.Body.Components;
  24. using Content.Shared.Body.Part;
  25. using Content.Shared.Clumsy;
  26. using Content.Shared.Clothing.Components;
  27. using Content.Shared.Cluwne;
  28. using Content.Shared.Damage;
  29. using Content.Shared.Damage.Systems;
  30. using Content.Shared.Database;
  31. using Content.Shared.Electrocution;
  32. using Content.Shared.Interaction.Components;
  33. using Content.Shared.Inventory;
  34. using Content.Shared.Mobs;
  35. using Content.Shared.Mobs.Components;
  36. using Content.Shared.Mobs.Systems;
  37. using Content.Shared.Movement.Components;
  38. using Content.Shared.Movement.Systems;
  39. using Content.Shared.Nutrition.Components;
  40. using Content.Shared.Popups;
  41. using Content.Shared.Slippery;
  42. using Content.Shared.Tabletop.Components;
  43. using Content.Shared.Tools.Systems;
  44. using Content.Shared.Verbs;
  45. using Robust.Shared.Map;
  46. using Robust.Shared.Map.Components;
  47. using Robust.Shared.Physics;
  48. using Robust.Shared.Physics.Components;
  49. using Robust.Shared.Physics.Systems;
  50. using Robust.Shared.Player;
  51. using Robust.Shared.Random;
  52. using Robust.Shared.Utility;
  53. using Timer = Robust.Shared.Timing.Timer;
  54. namespace Content.Server.Administration.Systems;
  55. public sealed partial class AdminVerbSystem
  56. {
  57. [Dependency] private readonly IRobustRandom _random = default!;
  58. [Dependency] private readonly BloodstreamSystem _bloodstreamSystem = default!;
  59. [Dependency] private readonly BodySystem _bodySystem = default!;
  60. [Dependency] private readonly CreamPieSystem _creamPieSystem = default!;
  61. [Dependency] private readonly ElectrocutionSystem _electrocutionSystem = default!;
  62. [Dependency] private readonly EntityStorageSystem _entityStorageSystem = default!;
  63. [Dependency] private readonly ExplosionSystem _explosionSystem = default!;
  64. [Dependency] private readonly FixtureSystem _fixtures = default!;
  65. [Dependency] private readonly FlammableSystem _flammableSystem = default!;
  66. [Dependency] private readonly GhostKickManager _ghostKickManager = default!;
  67. [Dependency] private readonly SharedGodmodeSystem _sharedGodmodeSystem = default!;
  68. [Dependency] private readonly InventorySystem _inventorySystem = default!;
  69. [Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifierSystem = default!;
  70. [Dependency] private readonly PolymorphSystem _polymorphSystem = default!;
  71. [Dependency] private readonly MobThresholdSystem _mobThresholdSystem = default!;
  72. [Dependency] private readonly PopupSystem _popupSystem = default!;
  73. [Dependency] private readonly SharedPhysicsSystem _physics = default!;
  74. [Dependency] private readonly TabletopSystem _tabletopSystem = default!;
  75. [Dependency] private readonly VomitSystem _vomitSystem = default!;
  76. [Dependency] private readonly WeldableSystem _weldableSystem = default!;
  77. [Dependency] private readonly SharedContentEyeSystem _eyeSystem = default!;
  78. [Dependency] private readonly SharedTransformSystem _transformSystem = default!;
  79. [Dependency] private readonly SuperBonkSystem _superBonkSystem = default!;
  80. [Dependency] private readonly SlipperySystem _slipperySystem = default!;
  81. // All smite verbs have names so invokeverb works.
  82. private void AddSmiteVerbs(GetVerbsEvent<Verb> args)
  83. {
  84. if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
  85. return;
  86. var player = actor.PlayerSession;
  87. if (!_adminManager.HasAdminFlag(player, AdminFlags.Fun))
  88. return;
  89. // 1984.
  90. if (HasComp<MapComponent>(args.Target) || HasComp<MapGridComponent>(args.Target))
  91. return;
  92. var explodeName = Loc.GetString("admin-smite-explode-name").ToLowerInvariant();
  93. Verb explode = new()
  94. {
  95. Text = explodeName,
  96. Category = VerbCategory.Smite,
  97. Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/smite.svg.192dpi.png")),
  98. Act = () =>
  99. {
  100. var coords = _transformSystem.GetMapCoordinates(args.Target);
  101. Timer.Spawn(_gameTiming.TickPeriod,
  102. () => _explosionSystem.QueueExplosion(coords, ExplosionSystem.DefaultExplosionPrototypeId,
  103. 4, 1, 2, args.Target, maxTileBreak: 0), // it gibs, damage doesn't need to be high.
  104. CancellationToken.None);
  105. _bodySystem.GibBody(args.Target);
  106. },
  107. Impact = LogImpact.Extreme,
  108. Message = string.Join(": ", explodeName, Loc.GetString("admin-smite-explode-description")) // we do this so the description tells admins the Text to run it via console.
  109. };
  110. args.Verbs.Add(explode);
  111. var chessName = Loc.GetString("admin-smite-chess-dimension-name").ToLowerInvariant();
  112. Verb chess = new()
  113. {
  114. Text = chessName,
  115. Category = VerbCategory.Smite,
  116. Icon = new SpriteSpecifier.Rsi(new("/Textures/Objects/Fun/Tabletop/chessboard.rsi"), "chessboard"),
  117. Act = () =>
  118. {
  119. _sharedGodmodeSystem.EnableGodmode(args.Target); // So they don't suffocate.
  120. EnsureComp<TabletopDraggableComponent>(args.Target);
  121. RemComp<PhysicsComponent>(args.Target); // So they can be dragged around.
  122. var xform = Transform(args.Target);
  123. _popupSystem.PopupEntity(Loc.GetString("admin-smite-chess-self"), args.Target,
  124. args.Target, PopupType.LargeCaution);
  125. _popupSystem.PopupCoordinates(
  126. Loc.GetString("admin-smite-chess-others", ("name", args.Target)), xform.Coordinates,
  127. Filter.PvsExcept(args.Target), true, PopupType.MediumCaution);
  128. var board = Spawn("ChessBoard", xform.Coordinates);
  129. var session = _tabletopSystem.EnsureSession(Comp<TabletopGameComponent>(board));
  130. xform.Coordinates = _transformSystem.ToCoordinates(session.Position);
  131. _transformSystem.SetWorldRotationNoLerp((args.Target, xform), Angle.Zero);
  132. },
  133. Impact = LogImpact.Extreme,
  134. Message = string.Join(": ", chessName, Loc.GetString("admin-smite-chess-dimension-description"))
  135. };
  136. args.Verbs.Add(chess);
  137. if (TryComp<FlammableComponent>(args.Target, out var flammable))
  138. {
  139. var flamesName = Loc.GetString("admin-smite-set-alight-name").ToLowerInvariant();
  140. Verb flames = new()
  141. {
  142. Text = flamesName,
  143. Category = VerbCategory.Smite,
  144. Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/Alerts/Fire/fire.png")),
  145. Act = () =>
  146. {
  147. // Fuck you. Burn Forever.
  148. flammable.FireStacks = flammable.MaximumFireStacks;
  149. _flammableSystem.Ignite(args.Target, args.User);
  150. var xform = Transform(args.Target);
  151. _popupSystem.PopupEntity(Loc.GetString("admin-smite-set-alight-self"), args.Target,
  152. args.Target, PopupType.LargeCaution);
  153. _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-set-alight-others", ("name", args.Target)), xform.Coordinates,
  154. Filter.PvsExcept(args.Target), true, PopupType.MediumCaution);
  155. },
  156. Impact = LogImpact.Extreme,
  157. Message = string.Join(": ", flamesName, Loc.GetString("admin-smite-set-alight-description"))
  158. };
  159. args.Verbs.Add(flames);
  160. }
  161. var monkeyName = Loc.GetString("admin-smite-monkeyify-name").ToLowerInvariant();
  162. Verb monkey = new()
  163. {
  164. Text = monkeyName,
  165. Category = VerbCategory.Smite,
  166. Icon = new SpriteSpecifier.Rsi(new("/Textures/Mobs/Animals/monkey.rsi"), "monkey"),
  167. Act = () =>
  168. {
  169. _polymorphSystem.PolymorphEntity(args.Target, "AdminMonkeySmite");
  170. },
  171. Impact = LogImpact.Extreme,
  172. Message = string.Join(": ", monkeyName, Loc.GetString("admin-smite-monkeyify-description"))
  173. };
  174. args.Verbs.Add(monkey);
  175. var disposalBinName = Loc.GetString("admin-smite-garbage-can-name").ToLowerInvariant();
  176. Verb disposalBin = new()
  177. {
  178. Text = disposalBinName,
  179. Category = VerbCategory.Smite,
  180. Icon = new SpriteSpecifier.Rsi(new("/Textures/Structures/Piping/disposal.rsi"), "disposal"),
  181. Act = () =>
  182. {
  183. _polymorphSystem.PolymorphEntity(args.Target, "AdminDisposalsSmite");
  184. },
  185. Impact = LogImpact.Extreme,
  186. Message = string.Join(": ", disposalBinName, Loc.GetString("admin-smite-garbage-can-description"))
  187. };
  188. args.Verbs.Add(disposalBin);
  189. if (TryComp<DamageableComponent>(args.Target, out var damageable) &&
  190. HasComp<MobStateComponent>(args.Target))
  191. {
  192. var hardElectrocuteName = Loc.GetString("admin-smite-electrocute-name").ToLowerInvariant();
  193. Verb hardElectrocute = new()
  194. {
  195. Text = hardElectrocuteName,
  196. Category = VerbCategory.Smite,
  197. Icon = new SpriteSpecifier.Rsi(new("/Textures/Clothing/Hands/Gloves/Color/yellow.rsi"), "icon"),
  198. Act = () =>
  199. {
  200. int damageToDeal;
  201. if (!_mobThresholdSystem.TryGetThresholdForState(args.Target, MobState.Critical, out var criticalThreshold))
  202. {
  203. // We can't crit them so try killing them.
  204. if (!_mobThresholdSystem.TryGetThresholdForState(args.Target, MobState.Dead,
  205. out var deadThreshold))
  206. return;// whelp.
  207. damageToDeal = deadThreshold.Value.Int() - (int)damageable.TotalDamage;
  208. }
  209. else
  210. {
  211. damageToDeal = criticalThreshold.Value.Int() - (int)damageable.TotalDamage;
  212. }
  213. if (damageToDeal <= 0)
  214. damageToDeal = 100; // murder time.
  215. if (_inventorySystem.TryGetSlots(args.Target, out var slotDefinitions))
  216. {
  217. foreach (var slot in slotDefinitions)
  218. {
  219. if (!_inventorySystem.TryGetSlotEntity(args.Target, slot.Name, out var slotEnt))
  220. continue;
  221. RemComp<InsulatedComponent>(slotEnt.Value); // Fry the gloves.
  222. }
  223. }
  224. _electrocutionSystem.TryDoElectrocution(args.Target, null, damageToDeal,
  225. TimeSpan.FromSeconds(30), refresh: true, ignoreInsulation: true);
  226. },
  227. Impact = LogImpact.Extreme,
  228. Message = string.Join(": ", hardElectrocuteName, Loc.GetString("admin-smite-electrocute-description"))
  229. };
  230. args.Verbs.Add(hardElectrocute);
  231. }
  232. if (TryComp<CreamPiedComponent>(args.Target, out var creamPied))
  233. {
  234. var creamPieName = Loc.GetString("admin-smite-creampie-name").ToLowerInvariant();
  235. Verb creamPie = new()
  236. {
  237. Text = creamPieName,
  238. Category = VerbCategory.Smite,
  239. Icon = new SpriteSpecifier.Rsi(new("/Textures/Objects/Consumable/Food/Baked/pie.rsi"), "plain-slice"),
  240. Act = () =>
  241. {
  242. _creamPieSystem.SetCreamPied(args.Target, creamPied, true);
  243. },
  244. Impact = LogImpact.Extreme,
  245. Message = string.Join(": ", creamPieName, Loc.GetString("admin-smite-creampie-description"))
  246. };
  247. args.Verbs.Add(creamPie);
  248. }
  249. if (TryComp<BloodstreamComponent>(args.Target, out var bloodstream))
  250. {
  251. var bloodRemovalName = Loc.GetString("admin-smite-remove-blood-name").ToLowerInvariant();
  252. Verb bloodRemoval = new()
  253. {
  254. Text = bloodRemovalName,
  255. Category = VerbCategory.Smite,
  256. Icon = new SpriteSpecifier.Rsi(new("/Textures/Fluids/tomato_splat.rsi"), "puddle-1"),
  257. Act = () =>
  258. {
  259. _bloodstreamSystem.SpillAllSolutions(args.Target, bloodstream);
  260. var xform = Transform(args.Target);
  261. _popupSystem.PopupEntity(Loc.GetString("admin-smite-remove-blood-self"), args.Target,
  262. args.Target, PopupType.LargeCaution);
  263. _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-remove-blood-others", ("name", args.Target)), xform.Coordinates,
  264. Filter.PvsExcept(args.Target), true, PopupType.MediumCaution);
  265. },
  266. Impact = LogImpact.Extreme,
  267. Message = string.Join(": ", bloodRemovalName, Loc.GetString("admin-smite-remove-blood-description"))
  268. };
  269. args.Verbs.Add(bloodRemoval);
  270. }
  271. // bobby...
  272. if (TryComp<BodyComponent>(args.Target, out var body))
  273. {
  274. var vomitOrgansName = Loc.GetString("admin-smite-vomit-organs-name").ToLowerInvariant();
  275. Verb vomitOrgans = new()
  276. {
  277. Text = vomitOrgansName,
  278. Category = VerbCategory.Smite,
  279. Icon = new SpriteSpecifier.Rsi(new("/Textures/Fluids/vomit_toxin.rsi"), "vomit_toxin-1"),
  280. Act = () =>
  281. {
  282. _vomitSystem.Vomit(args.Target, -1000, -1000); // You feel hollow!
  283. var organs = _bodySystem.GetBodyOrganEntityComps<TransformComponent>((args.Target, body));
  284. var baseXform = Transform(args.Target);
  285. foreach (var organ in organs)
  286. {
  287. if (HasComp<BrainComponent>(organ.Owner) || HasComp<EyeComponent>(organ.Owner))
  288. continue;
  289. _transformSystem.PlaceNextTo((organ.Owner, organ.Comp1), (args.Target, baseXform));
  290. }
  291. _popupSystem.PopupEntity(Loc.GetString("admin-smite-vomit-organs-self"), args.Target,
  292. args.Target, PopupType.LargeCaution);
  293. _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-vomit-organs-others", ("name", args.Target)), baseXform.Coordinates,
  294. Filter.PvsExcept(args.Target), true, PopupType.MediumCaution);
  295. },
  296. Impact = LogImpact.Extreme,
  297. Message = string.Join(": ", vomitOrgansName, Loc.GetString("admin-smite-vomit-organs-description"))
  298. };
  299. args.Verbs.Add(vomitOrgans);
  300. var handsRemovalName = Loc.GetString("admin-smite-remove-hands-name").ToLowerInvariant();
  301. Verb handsRemoval = new()
  302. {
  303. Text = handsRemovalName,
  304. Category = VerbCategory.Smite,
  305. Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/AdminActions/remove-hands.png")),
  306. Act = () =>
  307. {
  308. var baseXform = Transform(args.Target);
  309. foreach (var part in _bodySystem.GetBodyChildrenOfType(args.Target, BodyPartType.Hand))
  310. {
  311. _transformSystem.AttachToGridOrMap(part.Id);
  312. }
  313. _popupSystem.PopupEntity(Loc.GetString("admin-smite-remove-hands-self"), args.Target,
  314. args.Target, PopupType.LargeCaution);
  315. _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-remove-hands-other", ("name", args.Target)), baseXform.Coordinates,
  316. Filter.PvsExcept(args.Target), true, PopupType.Medium);
  317. },
  318. Impact = LogImpact.Extreme,
  319. Message = string.Join(": ", handsRemovalName, Loc.GetString("admin-smite-remove-hands-description"))
  320. };
  321. args.Verbs.Add(handsRemoval);
  322. var handRemovalName = Loc.GetString("admin-smite-remove-hand-name").ToLowerInvariant();
  323. Verb handRemoval = new()
  324. {
  325. Text = handRemovalName,
  326. Category = VerbCategory.Smite,
  327. Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/AdminActions/remove-hand.png")),
  328. Act = () =>
  329. {
  330. var baseXform = Transform(args.Target);
  331. foreach (var part in _bodySystem.GetBodyChildrenOfType(args.Target, BodyPartType.Hand, body))
  332. {
  333. _transformSystem.AttachToGridOrMap(part.Id);
  334. break;
  335. }
  336. _popupSystem.PopupEntity(Loc.GetString("admin-smite-remove-hands-self"), args.Target,
  337. args.Target, PopupType.LargeCaution);
  338. _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-remove-hands-other", ("name", args.Target)), baseXform.Coordinates,
  339. Filter.PvsExcept(args.Target), true, PopupType.Medium);
  340. },
  341. Impact = LogImpact.Extreme,
  342. Message = string.Join(": ", handRemovalName, Loc.GetString("admin-smite-remove-hand-description"))
  343. };
  344. args.Verbs.Add(handRemoval);
  345. var stomachRemovalName = Loc.GetString("admin-smite-stomach-removal-name").ToLowerInvariant();
  346. Verb stomachRemoval = new()
  347. {
  348. Text = stomachRemovalName,
  349. Category = VerbCategory.Smite,
  350. Icon = new SpriteSpecifier.Rsi(new("/Textures/Mobs/Species/Human/organs.rsi"), "stomach"),
  351. Act = () =>
  352. {
  353. foreach (var entity in _bodySystem.GetBodyOrganEntityComps<StomachComponent>((args.Target, body)))
  354. {
  355. QueueDel(entity.Owner);
  356. }
  357. _popupSystem.PopupEntity(Loc.GetString("admin-smite-stomach-removal-self"), args.Target,
  358. args.Target, PopupType.LargeCaution);
  359. },
  360. Impact = LogImpact.Extreme,
  361. Message = string.Join(": ", stomachRemovalName, Loc.GetString("admin-smite-stomach-removal-description"))
  362. };
  363. args.Verbs.Add(stomachRemoval);
  364. var lungRemovalName = Loc.GetString("admin-smite-lung-removal-name").ToLowerInvariant();
  365. Verb lungRemoval = new()
  366. {
  367. Text = lungRemovalName,
  368. Category = VerbCategory.Smite,
  369. Icon = new SpriteSpecifier.Rsi(new("/Textures/Mobs/Species/Human/organs.rsi"), "lung-r"),
  370. Act = () =>
  371. {
  372. foreach (var entity in _bodySystem.GetBodyOrganEntityComps<LungComponent>((args.Target, body)))
  373. {
  374. QueueDel(entity.Owner);
  375. }
  376. _popupSystem.PopupEntity(Loc.GetString("admin-smite-lung-removal-self"), args.Target,
  377. args.Target, PopupType.LargeCaution);
  378. },
  379. Impact = LogImpact.Extreme,
  380. Message = string.Join(": ", lungRemovalName, Loc.GetString("admin-smite-lung-removal-description"))
  381. };
  382. args.Verbs.Add(lungRemoval);
  383. }
  384. if (TryComp<PhysicsComponent>(args.Target, out var physics))
  385. {
  386. var pinballName = Loc.GetString("admin-smite-pinball-name").ToLowerInvariant();
  387. Verb pinball = new()
  388. {
  389. Text = pinballName,
  390. Category = VerbCategory.Smite,
  391. Icon = new SpriteSpecifier.Rsi(new("/Textures/Objects/Fun/toys.rsi"), "basketball"),
  392. Act = () =>
  393. {
  394. var xform = Transform(args.Target);
  395. var fixtures = Comp<FixturesComponent>(args.Target);
  396. xform.Anchored = false; // Just in case.
  397. _physics.SetBodyType(args.Target, BodyType.Dynamic, manager: fixtures, body: physics);
  398. _physics.SetBodyStatus(args.Target, physics, BodyStatus.InAir);
  399. _physics.WakeBody(args.Target, manager: fixtures, body: physics);
  400. foreach (var fixture in fixtures.Fixtures.Values)
  401. {
  402. if (!fixture.Hard)
  403. continue;
  404. _physics.SetRestitution(args.Target, fixture, 1.1f, false, fixtures);
  405. }
  406. _fixtures.FixtureUpdate(args.Target, manager: fixtures, body: physics);
  407. _physics.SetLinearVelocity(args.Target, _random.NextVector2(1.5f, 1.5f), manager: fixtures, body: physics);
  408. _physics.SetAngularVelocity(args.Target, MathF.PI * 12, manager: fixtures, body: physics);
  409. _physics.SetLinearDamping(args.Target, physics, 0f);
  410. _physics.SetAngularDamping(args.Target, physics, 0f);
  411. },
  412. Impact = LogImpact.Extreme,
  413. Message = string.Join(": ", pinballName, Loc.GetString("admin-smite-pinball-description"))
  414. };
  415. args.Verbs.Add(pinball);
  416. var yeetName = Loc.GetString("admin-smite-yeet-name").ToLowerInvariant();
  417. Verb yeet = new()
  418. {
  419. Text = yeetName,
  420. Category = VerbCategory.Smite,
  421. Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/eject.svg.192dpi.png")),
  422. Act = () =>
  423. {
  424. var xform = Transform(args.Target);
  425. var fixtures = Comp<FixturesComponent>(args.Target);
  426. xform.Anchored = false; // Just in case.
  427. _physics.SetBodyType(args.Target, BodyType.Dynamic, body: physics);
  428. _physics.SetBodyStatus(args.Target, physics, BodyStatus.InAir);
  429. _physics.WakeBody(args.Target, manager: fixtures, body: physics);
  430. foreach (var fixture in fixtures.Fixtures.Values)
  431. {
  432. _physics.SetHard(args.Target, fixture, false, manager: fixtures);
  433. }
  434. _physics.SetLinearVelocity(args.Target, _random.NextVector2(8.0f, 8.0f), manager: fixtures, body: physics);
  435. _physics.SetAngularVelocity(args.Target, MathF.PI * 12, manager: fixtures, body: physics);
  436. _physics.SetLinearDamping(args.Target, physics, 0f);
  437. _physics.SetAngularDamping(args.Target, physics, 0f);
  438. },
  439. Impact = LogImpact.Extreme,
  440. Message = string.Join(": ", yeetName, Loc.GetString("admin-smite-yeet-description"))
  441. };
  442. args.Verbs.Add(yeet);
  443. }
  444. var breadName = Loc.GetString("admin-smite-become-bread-name").ToLowerInvariant(); // Will I get cancelled for breadName-ing you?
  445. Verb bread = new()
  446. {
  447. Text = breadName,
  448. Category = VerbCategory.Smite,
  449. Icon = new SpriteSpecifier.Rsi(new("/Textures/Objects/Consumable/Food/Baked/bread.rsi"), "plain"),
  450. Act = () =>
  451. {
  452. _polymorphSystem.PolymorphEntity(args.Target, "AdminBreadSmite");
  453. },
  454. Impact = LogImpact.Extreme,
  455. Message = string.Join(": ", breadName, Loc.GetString("admin-smite-become-bread-description"))
  456. };
  457. args.Verbs.Add(bread);
  458. var mouseName = Loc.GetString("admin-smite-become-mouse-name").ToLowerInvariant();
  459. Verb mouse = new()
  460. {
  461. Text = mouseName,
  462. Category = VerbCategory.Smite,
  463. Icon = new SpriteSpecifier.Rsi(new("/Textures/Mobs/Animals/mouse.rsi"), "icon-0"),
  464. Act = () =>
  465. {
  466. _polymorphSystem.PolymorphEntity(args.Target, "AdminMouseSmite");
  467. },
  468. Impact = LogImpact.Extreme,
  469. Message = string.Join(": ", mouseName, Loc.GetString("admin-smite-become-mouse-description"))
  470. };
  471. args.Verbs.Add(mouse);
  472. if (TryComp<ActorComponent>(args.Target, out var actorComponent))
  473. {
  474. var ghostKickName = Loc.GetString("admin-smite-ghostkick-name").ToLowerInvariant();
  475. Verb ghostKick = new()
  476. {
  477. Text = ghostKickName,
  478. Category = VerbCategory.Smite,
  479. Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/gavel.svg.192dpi.png")),
  480. Act = () =>
  481. {
  482. _ghostKickManager.DoDisconnect(actorComponent.PlayerSession.Channel, "Smitten.");
  483. },
  484. Impact = LogImpact.Extreme,
  485. Message = string.Join(": ", ghostKickName, Loc.GetString("admin-smite-ghostkick-description"))
  486. };
  487. args.Verbs.Add(ghostKick);
  488. }
  489. if (TryComp<InventoryComponent>(args.Target, out var inventory))
  490. {
  491. var nyanifyName = Loc.GetString("admin-smite-nyanify-name").ToLowerInvariant();
  492. Verb nyanify = new()
  493. {
  494. Text = nyanifyName,
  495. Category = VerbCategory.Smite,
  496. Icon = new SpriteSpecifier.Rsi(new("/Textures/Clothing/Head/Hats/catears.rsi"), "icon"),
  497. Act = () =>
  498. {
  499. var ears = Spawn("ClothingHeadHatCatEars", Transform(args.Target).Coordinates);
  500. EnsureComp<UnremoveableComponent>(ears);
  501. _inventorySystem.TryUnequip(args.Target, "head", true, true, false, inventory);
  502. _inventorySystem.TryEquip(args.Target, ears, "head", true, true, false, inventory);
  503. },
  504. Impact = LogImpact.Extreme,
  505. Message = string.Join(": ", nyanifyName, Loc.GetString("admin-smite-nyanify-description"))
  506. };
  507. args.Verbs.Add(nyanify);
  508. var killSignName = Loc.GetString("admin-smite-kill-sign-name").ToLowerInvariant();
  509. Verb killSign = new()
  510. {
  511. Text = killSignName,
  512. Category = VerbCategory.Smite,
  513. Icon = new SpriteSpecifier.Rsi(new("/Textures/Objects/Misc/killsign.rsi"), "icon"),
  514. Act = () =>
  515. {
  516. EnsureComp<KillSignComponent>(args.Target);
  517. },
  518. Impact = LogImpact.Extreme,
  519. Message = string.Join(": ", killSignName, Loc.GetString("admin-smite-kill-sign-description"))
  520. };
  521. args.Verbs.Add(killSign);
  522. var cluwneName = Loc.GetString("admin-smite-cluwne-name").ToLowerInvariant();
  523. Verb cluwne = new()
  524. {
  525. Text = cluwneName,
  526. Category = VerbCategory.Smite,
  527. Icon = new SpriteSpecifier.Rsi(new("/Textures/Clothing/Mask/cluwne.rsi"), "icon"),
  528. Act = () =>
  529. {
  530. EnsureComp<CluwneComponent>(args.Target);
  531. },
  532. Impact = LogImpact.Extreme,
  533. Message = string.Join(": ", cluwneName, Loc.GetString("admin-smite-cluwne-description"))
  534. };
  535. args.Verbs.Add(cluwne);
  536. var maidenName = Loc.GetString("admin-smite-maid-name").ToLowerInvariant();
  537. Verb maiden = new()
  538. {
  539. Text = maidenName,
  540. Category = VerbCategory.Smite,
  541. Icon = new SpriteSpecifier.Rsi(new("/Textures/Clothing/Uniforms/Jumpskirt/janimaid.rsi"), "icon"),
  542. Act = () =>
  543. {
  544. SetOutfitCommand.SetOutfit(args.Target, "JanitorMaidGear", EntityManager, (_, clothing) =>
  545. {
  546. if (HasComp<ClothingComponent>(clothing))
  547. EnsureComp<UnremoveableComponent>(clothing);
  548. EnsureComp<ClumsyComponent>(args.Target);
  549. });
  550. },
  551. Impact = LogImpact.Extreme,
  552. Message = string.Join(": ", maidenName, Loc.GetString("admin-smite-maid-description"))
  553. };
  554. args.Verbs.Add(maiden);
  555. }
  556. var angerPointingArrowsName = Loc.GetString("admin-smite-anger-pointing-arrows-name").ToLowerInvariant();
  557. Verb angerPointingArrows = new()
  558. {
  559. Text = angerPointingArrowsName,
  560. Category = VerbCategory.Smite,
  561. Icon = new SpriteSpecifier.Rsi(new("/Textures/Interface/Misc/pointing.rsi"), "pointing"),
  562. Act = () =>
  563. {
  564. EnsureComp<PointingArrowAngeringComponent>(args.Target);
  565. },
  566. Impact = LogImpact.Extreme,
  567. Message = string.Join(": ", angerPointingArrowsName, Loc.GetString("admin-smite-anger-pointing-arrows-description"))
  568. };
  569. args.Verbs.Add(angerPointingArrows);
  570. var dustName = Loc.GetString("admin-smite-dust-name").ToLowerInvariant();
  571. Verb dust = new()
  572. {
  573. Text = dustName,
  574. Category = VerbCategory.Smite,
  575. Icon = new SpriteSpecifier.Rsi(new("/Textures/Objects/Materials/materials.rsi"), "ash"),
  576. Act = () =>
  577. {
  578. EntityManager.QueueDeleteEntity(args.Target);
  579. Spawn("Ash", Transform(args.Target).Coordinates);
  580. _popupSystem.PopupEntity(Loc.GetString("admin-smite-turned-ash-other", ("name", args.Target)), args.Target, PopupType.LargeCaution);
  581. },
  582. Impact = LogImpact.Extreme,
  583. Message = string.Join(": ", dustName, Loc.GetString("admin-smite-dust-description"))
  584. };
  585. args.Verbs.Add(dust);
  586. var youtubeVideoSimulationName = Loc.GetString("admin-smite-buffering-name").ToLowerInvariant();
  587. Verb youtubeVideoSimulation = new()
  588. {
  589. Text = youtubeVideoSimulationName,
  590. Category = VerbCategory.Smite,
  591. Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/Misc/buffering_smite_icon.png")),
  592. Act = () =>
  593. {
  594. EnsureComp<BufferingComponent>(args.Target);
  595. },
  596. Impact = LogImpact.Extreme,
  597. Message = string.Join(": ", youtubeVideoSimulationName, Loc.GetString("admin-smite-buffering-description"))
  598. };
  599. args.Verbs.Add(youtubeVideoSimulation);
  600. var instrumentationName = Loc.GetString("admin-smite-become-instrument-name").ToLowerInvariant();
  601. Verb instrumentation = new()
  602. {
  603. Text = instrumentationName,
  604. Category = VerbCategory.Smite,
  605. Icon = new SpriteSpecifier.Rsi(new("/Textures/Objects/Fun/Instruments/h_synthesizer.rsi"), "supersynth"),
  606. Act = () =>
  607. {
  608. _polymorphSystem.PolymorphEntity(args.Target, "AdminInstrumentSmite");
  609. },
  610. Impact = LogImpact.Extreme,
  611. Message = string.Join(": ", instrumentationName, Loc.GetString("admin-smite-become-instrument-description"))
  612. };
  613. args.Verbs.Add(instrumentation);
  614. var noGravityName = Loc.GetString("admin-smite-remove-gravity-name").ToLowerInvariant();
  615. Verb noGravity = new()
  616. {
  617. Text = noGravityName,
  618. Category = VerbCategory.Smite,
  619. Icon = new SpriteSpecifier.Rsi(new("/Textures/Structures/Machines/gravity_generator.rsi"), "off"),
  620. Act = () =>
  621. {
  622. var grav = EnsureComp<MovementIgnoreGravityComponent>(args.Target);
  623. grav.Weightless = true;
  624. Dirty(args.Target, grav);
  625. },
  626. Impact = LogImpact.Extreme,
  627. Message = string.Join(": ", noGravityName, Loc.GetString("admin-smite-remove-gravity-description"))
  628. };
  629. args.Verbs.Add(noGravity);
  630. var reptilianName = Loc.GetString("admin-smite-reptilian-species-swap-name").ToLowerInvariant();
  631. Verb reptilian = new()
  632. {
  633. Text = reptilianName,
  634. Category = VerbCategory.Smite,
  635. Icon = new SpriteSpecifier.Rsi(new("/Textures/Objects/Fun/toys.rsi"), "plushie_lizard"),
  636. Act = () =>
  637. {
  638. _polymorphSystem.PolymorphEntity(args.Target, "AdminLizardSmite");
  639. },
  640. Impact = LogImpact.Extreme,
  641. Message = string.Join(": ", reptilianName, Loc.GetString("admin-smite-reptilian-species-swap-description"))
  642. };
  643. args.Verbs.Add(reptilian);
  644. var lockerName = Loc.GetString("admin-smite-locker-stuff-name").ToLowerInvariant();
  645. Verb locker = new()
  646. {
  647. Text = lockerName,
  648. Category = VerbCategory.Smite,
  649. Icon = new SpriteSpecifier.Rsi(new("/Textures/Structures/Storage/closet.rsi"), "generic"),
  650. Act = () =>
  651. {
  652. var xform = Transform(args.Target);
  653. var locker = Spawn("ClosetMaintenance", xform.Coordinates);
  654. if (TryComp<EntityStorageComponent>(locker, out var storage))
  655. {
  656. _entityStorageSystem.ToggleOpen(args.Target, locker, storage);
  657. _entityStorageSystem.Insert(args.Target, locker, storage);
  658. _entityStorageSystem.ToggleOpen(args.Target, locker, storage);
  659. }
  660. _weldableSystem.SetWeldedState(locker, true);
  661. },
  662. Impact = LogImpact.Extreme,
  663. Message = string.Join(": ", lockerName, Loc.GetString("admin-smite-locker-stuff-description"))
  664. };
  665. args.Verbs.Add(locker);
  666. var headstandName = Loc.GetString("admin-smite-headstand-name").ToLowerInvariant();
  667. Verb headstand = new()
  668. {
  669. Text = headstandName,
  670. Category = VerbCategory.Smite,
  671. Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/refresh.svg.192dpi.png")),
  672. Act = () =>
  673. {
  674. EnsureComp<HeadstandComponent>(args.Target);
  675. },
  676. Impact = LogImpact.Extreme,
  677. Message = string.Join(": ", headstandName, Loc.GetString("admin-smite-headstand-description"))
  678. };
  679. args.Verbs.Add(headstand);
  680. var zoomInName = Loc.GetString("admin-smite-zoom-in-name").ToLowerInvariant();
  681. Verb zoomIn = new()
  682. {
  683. Text = zoomInName,
  684. Category = VerbCategory.Smite,
  685. Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/AdminActions/zoom.png")),
  686. Act = () =>
  687. {
  688. var eye = EnsureComp<ContentEyeComponent>(args.Target);
  689. _eyeSystem.SetZoom(args.Target, eye.TargetZoom * 0.2f, ignoreLimits: true);
  690. },
  691. Impact = LogImpact.Extreme,
  692. Message = string.Join(": ", zoomInName, Loc.GetString("admin-smite-zoom-in-description"))
  693. };
  694. args.Verbs.Add(zoomIn);
  695. var flipEyeName = Loc.GetString("admin-smite-flip-eye-name").ToLowerInvariant();
  696. Verb flipEye = new()
  697. {
  698. Text = flipEyeName,
  699. Category = VerbCategory.Smite,
  700. Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/AdminActions/flip.png")),
  701. Act = () =>
  702. {
  703. var eye = EnsureComp<ContentEyeComponent>(args.Target);
  704. _eyeSystem.SetZoom(args.Target, eye.TargetZoom * -1, ignoreLimits: true);
  705. },
  706. Impact = LogImpact.Extreme,
  707. Message = string.Join(": ", flipEyeName, Loc.GetString("admin-smite-flip-eye-description"))
  708. };
  709. args.Verbs.Add(flipEye);
  710. var runWalkSwapName = Loc.GetString("admin-smite-run-walk-swap-name").ToLowerInvariant();
  711. Verb runWalkSwap = new()
  712. {
  713. Text = runWalkSwapName,
  714. Category = VerbCategory.Smite,
  715. Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/AdminActions/run-walk-swap.png")),
  716. Act = () =>
  717. {
  718. var movementSpeed = EnsureComp<MovementSpeedModifierComponent>(args.Target);
  719. (movementSpeed.BaseSprintSpeed, movementSpeed.BaseWalkSpeed) = (movementSpeed.BaseWalkSpeed, movementSpeed.BaseSprintSpeed);
  720. Dirty(args.Target, movementSpeed);
  721. _popupSystem.PopupEntity(Loc.GetString("admin-smite-run-walk-swap-prompt"), args.Target,
  722. args.Target, PopupType.LargeCaution);
  723. },
  724. Impact = LogImpact.Extreme,
  725. Message = string.Join(": ", runWalkSwapName, Loc.GetString("admin-smite-run-walk-swap-description"))
  726. };
  727. args.Verbs.Add(runWalkSwap);
  728. var backwardsAccentName = Loc.GetString("admin-smite-speak-backwards-name").ToLowerInvariant();
  729. Verb backwardsAccent = new()
  730. {
  731. Text = backwardsAccentName,
  732. Category = VerbCategory.Smite,
  733. Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/AdminActions/help-backwards.png")),
  734. Act = () =>
  735. {
  736. EnsureComp<BackwardsAccentComponent>(args.Target);
  737. },
  738. Impact = LogImpact.Extreme,
  739. Message = string.Join(": ", backwardsAccentName, Loc.GetString("admin-smite-speak-backwards-description"))
  740. };
  741. args.Verbs.Add(backwardsAccent);
  742. var disarmProneName = Loc.GetString("admin-smite-disarm-prone-name").ToLowerInvariant();
  743. Verb disarmProne = new()
  744. {
  745. Text = disarmProneName,
  746. Category = VerbCategory.Smite,
  747. Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/Actions/disarm.png")),
  748. Act = () =>
  749. {
  750. EnsureComp<DisarmProneComponent>(args.Target);
  751. },
  752. Impact = LogImpact.Extreme,
  753. Message = string.Join(": ", disarmProneName, Loc.GetString("admin-smite-disarm-prone-description"))
  754. };
  755. args.Verbs.Add(disarmProne);
  756. var superSpeedName = Loc.GetString("admin-smite-super-speed-name").ToLowerInvariant();
  757. Verb superSpeed = new()
  758. {
  759. Text = superSpeedName,
  760. Category = VerbCategory.Smite,
  761. Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/AdminActions/super_speed.png")),
  762. Act = () =>
  763. {
  764. var movementSpeed = EnsureComp<MovementSpeedModifierComponent>(args.Target);
  765. _movementSpeedModifierSystem?.ChangeBaseSpeed(args.Target, 400, 8000, 40, movementSpeed);
  766. _popupSystem.PopupEntity(Loc.GetString("admin-smite-super-speed-prompt"), args.Target,
  767. args.Target, PopupType.LargeCaution);
  768. },
  769. Impact = LogImpact.Extreme,
  770. Message = string.Join(": ", superSpeedName, Loc.GetString("admin-smite-super-speed-description"))
  771. };
  772. args.Verbs.Add(superSpeed);
  773. //Bonk
  774. var superBonkLiteName = Loc.GetString("admin-smite-super-bonk-lite-name").ToLowerInvariant();
  775. Verb superBonkLite = new()
  776. {
  777. Text = superBonkLiteName,
  778. Category = VerbCategory.Smite,
  779. Icon = new SpriteSpecifier.Rsi(new("Structures/Furniture/Tables/glass.rsi"), "full"),
  780. Act = () =>
  781. {
  782. _superBonkSystem.StartSuperBonk(args.Target, stopWhenDead: true);
  783. },
  784. Impact = LogImpact.Extreme,
  785. Message = string.Join(": ", superBonkLiteName, Loc.GetString("admin-smite-super-bonk-lite-description"))
  786. };
  787. args.Verbs.Add(superBonkLite);
  788. var superBonkName = Loc.GetString("admin-smite-super-bonk-name").ToLowerInvariant();
  789. Verb superBonk = new()
  790. {
  791. Text = superBonkName,
  792. Category = VerbCategory.Smite,
  793. Icon = new SpriteSpecifier.Rsi(new("Structures/Furniture/Tables/generic.rsi"), "full"),
  794. Act = () =>
  795. {
  796. _superBonkSystem.StartSuperBonk(args.Target);
  797. },
  798. Impact = LogImpact.Extreme,
  799. Message = string.Join(": ", superBonkName, Loc.GetString("admin-smite-super-bonk-description"))
  800. };
  801. args.Verbs.Add(superBonk);
  802. var superslipName = Loc.GetString("admin-smite-super-slip-name").ToLowerInvariant();
  803. Verb superslip = new()
  804. {
  805. Text = superslipName,
  806. Category = VerbCategory.Smite,
  807. Icon = new SpriteSpecifier.Rsi(new("Objects/Specific/Janitorial/soap.rsi"), "omega-4"),
  808. Act = () =>
  809. {
  810. var hadSlipComponent = EnsureComp(args.Target, out SlipperyComponent slipComponent);
  811. if (!hadSlipComponent)
  812. {
  813. slipComponent.SuperSlippery = true;
  814. slipComponent.ParalyzeTime = 5;
  815. slipComponent.LaunchForwardsMultiplier = 20;
  816. }
  817. _slipperySystem.TrySlip(args.Target, slipComponent, args.Target, requiresContact: false);
  818. if (!hadSlipComponent)
  819. {
  820. RemComp(args.Target, slipComponent);
  821. }
  822. },
  823. Impact = LogImpact.Extreme,
  824. Message = string.Join(": ", superslipName, Loc.GetString("admin-smite-super-slip-description"))
  825. };
  826. args.Verbs.Add(superslip);
  827. var omniaccentName = Loc.GetString("admin-smite-omni-accent-name").ToLowerInvariant();
  828. Verb omniaccent = new()
  829. {
  830. Text = omniaccentName,
  831. Category = VerbCategory.Smite,
  832. Icon = new SpriteSpecifier.Rsi(new("Interface/Actions/voice-mask.rsi"), "icon"),
  833. Act = () =>
  834. {
  835. EnsureComp<BarkAccentComponent>(args.Target);
  836. EnsureComp<BleatingAccentComponent>(args.Target);
  837. EnsureComp<FrenchAccentComponent>(args.Target);
  838. EnsureComp<GermanAccentComponent>(args.Target);
  839. EnsureComp<LizardAccentComponent>(args.Target);
  840. EnsureComp<MobsterAccentComponent>(args.Target);
  841. EnsureComp<MothAccentComponent>(args.Target);
  842. EnsureComp<OwOAccentComponent>(args.Target);
  843. EnsureComp<SkeletonAccentComponent>(args.Target);
  844. EnsureComp<SouthernAccentComponent>(args.Target);
  845. EnsureComp<SpanishAccentComponent>(args.Target);
  846. EnsureComp<StutteringAccentComponent>(args.Target);
  847. EnsureComp<MedievalAccentComponent>(args.Target); // Goobtation
  848. EnsureComp<OhioAccentComponent>(args.Target); // Goobtation
  849. if (_random.Next(0, 8) == 0)
  850. {
  851. EnsureComp<BackwardsAccentComponent>(args.Target); // was asked to make this at a low chance idk
  852. }
  853. },
  854. Impact = LogImpact.Extreme,
  855. Message = string.Join(": ", omniaccentName, Loc.GetString("admin-smite-omni-accent-description"))
  856. };
  857. args.Verbs.Add(omniaccent);
  858. }
  859. }