Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upstream sync #1484

Merged
merged 47 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
6ee76b0
Revert "Northstar Gloves dmg reduced from 8 -> 7" (#20674)
JoeHammad1844 Oct 2, 2023
7802bd1
Automatic changelog update
PJBot Oct 2, 2023
c12d0c5
Make minigun weigh more (#20685)
BasedUser Oct 2, 2023
3131481
easiest bug fix of my life (#20686)
VasilisThePikachu Oct 2, 2023
13f218e
Automatic changelog update
PJBot Oct 2, 2023
4c46273
Add rolling pins for flattening dough (#20624)
deltanedas Oct 2, 2023
2d20ca0
Automatic changelog update
PJBot Oct 2, 2023
dc95582
Make forcing others into disposals take longer and more apparent (#20…
notquitehadouken Oct 2, 2023
2b48350
Increase bluespace beaker capacity (#20680)
EmoGarbage404 Oct 2, 2023
8dda8a1
Add names for power infrastructure on Packed (#20689)
JustCone14 Oct 2, 2023
5aa7b01
Disable SSD indicators on LRP (#20021)
Chief-Engineer Oct 2, 2023
1c088d5
Give nukeops play time requirements (#20109)
deltanedas Oct 2, 2023
ba71e4f
Automatic changelog update
PJBot Oct 2, 2023
be55f9a
Play sound when filling ammo (#20691)
deltanedas Oct 2, 2023
edd1757
Box Power Infrastructure Names (#20693)
JustCone14 Oct 2, 2023
fcc24ce
Revert "Disable SSD indicators on LRP (#20021)" (#20703)
Chief-Engineer Oct 3, 2023
1bdb2ce
Origin Station Update 22.09.2023 (remove mines, fix telecoms) (#20411)
brainfood1183 Oct 3, 2023
37f22a8
Add names to unnamed SMES and Subs (#20712)
JustCone14 Oct 3, 2023
fa1c15b
Fix plant species reagent mutations (#20702)
Doru991 Oct 3, 2023
5ae3bff
Automatic changelog update
PJBot Oct 3, 2023
e0fda7c
Fix omnitool not prying airlocks (#20697)
crazybrain23 Oct 4, 2023
e6ee267
Automatic changelog update
PJBot Oct 4, 2023
bfa301b
fix (#20719)
UbaserB Oct 4, 2023
6131721
fix borgs not being able to toggle flashlight (#20448)
EmoGarbage404 Oct 4, 2023
bb0eec3
Automatic changelog update
PJBot Oct 4, 2023
ed9e44d
fix magboots equipped sprites (#20723)
deltanedas Oct 4, 2023
7617328
Add missing type argument from PopupClient to PopupEntity (#20725)
deltanedas Oct 4, 2023
4df0f0e
Add trading ship for future implementation (#20715)
UbaserB Oct 4, 2023
09b2151
Space Ninja 3: an old enemy in a new environment (#20713)
Jackal298 Oct 4, 2023
ef44986
Add clipboards (#20717)
nmajask Oct 4, 2023
44280de
Automatic changelog update
PJBot Oct 4, 2023
13f0676
Add ashwalker and gladiator starting gear sets (#20688)
Fromoriss Oct 4, 2023
2c69dd2
emag inhand sprites (#20729)
notquitehadouken Oct 5, 2023
9df5ded
Revolutionaries (#18477)
coolmankid12345 Oct 5, 2023
c1cfe8d
Removes unnecessary message for defibbing a patient which has ghosted…
rbertoche Oct 5, 2023
cad76d9
Automatic changelog update
PJBot Oct 5, 2023
3f42835
Adds clipboards to bureaucracy crate and replaces incorrectly credite…
nmajask Oct 5, 2023
0660549
Fix revolutionaries not being considered antags (#20739)
DrSmugleaf Oct 5, 2023
5f0b665
Fix printing $username at round end for head revs when it doesn't hav…
DrSmugleaf Oct 5, 2023
c7cf676
Add "Two Strands" hair (#20730)
Bloody2372 Oct 5, 2023
3949932
Fix access for vehicles and mechs (#20737)
EmoGarbage404 Oct 5, 2023
a946093
Automatic changelog update
PJBot Oct 5, 2023
14256de
Barratry seniors (#20720)
TsjipTsjip Oct 5, 2023
a365568
give revs briefing (#20749)
deltanedas Oct 5, 2023
5a4438c
Merge remote-tracking branch 'upstream/master' into upstream-sync
Morb0 Oct 5, 2023
ab79ed1
Revert "Space Ninja 3: an old enemy in a new environment (#20713)"
Morb0 Oct 5, 2023
3cf94e9
Update locale
Morb0 Oct 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions Content.Client/Antag/AntagStatusIconSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Content.Shared.StatusIcon;
using Content.Shared.StatusIcon.Components;
using Robust.Shared.Prototypes;
using Content.Shared.Ghost;
using Robust.Client.Player;

namespace Content.Client.Antag;

/// <summary>
/// Used for assigning specified icons for antags.
/// </summary>
public abstract class AntagStatusIconSystem<T> : SharedStatusIconSystem
where T : Component
{
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly IPlayerManager _player = default!;

/// <summary>
/// Will check if the local player has the same component as the one who called it and give the status icon.
/// </summary>
/// <param name="antagStatusIcon">The status icon that your antag uses</param>
/// <param name="args">The GetStatusIcon event.</param>
protected virtual void GetStatusIcon(string antagStatusIcon, ref GetStatusIconsEvent args)
{
var ent = _player.LocalPlayer?.ControlledEntity;

if (!HasComp<T>(ent) && !HasComp<GhostComponent>(ent))
return;

args.StatusIcons.Add(_prototype.Index<StatusIconPrototype>(antagStatusIcon));
}
}
2 changes: 1 addition & 1 deletion Content.Client/Popups/PopupSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public override void PopupEntity(string message, EntityUid uid, Filter filter, b
public override void PopupClient(string message, EntityUid uid, EntityUid recipient, PopupType type = PopupType.Small)
{
if (_timing.IsFirstTimePredicted)
PopupEntity(message, uid, recipient);
PopupEntity(message, uid, recipient, type);
}

public override void PopupEntity(string message, EntityUid uid, PopupType type = PopupType.Small)
Expand Down
35 changes: 35 additions & 0 deletions Content.Client/Revolutionary/RevolutionarySystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using Content.Shared.Revolutionary.Components;
using Content.Client.Antag;
using Content.Shared.StatusIcon.Components;

namespace Content.Client.Revolutionary;

/// <summary>
/// Used for the client to get status icons from other revs.
/// </summary>
public sealed class RevolutionarySystem : AntagStatusIconSystem<RevolutionaryComponent>
{
public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<RevolutionaryComponent, GetStatusIconsEvent>(GetRevIcon);
SubscribeLocalEvent<HeadRevolutionaryComponent, GetStatusIconsEvent>(GetHeadRevIcon);
}

/// <summary>
/// Checks if the person who triggers the GetStatusIcon event is also a Rev or a HeadRev.
/// </summary>
private void GetRevIcon(EntityUid uid, RevolutionaryComponent comp, ref GetStatusIconsEvent args)
{
if (!HasComp<HeadRevolutionaryComponent>(uid))
{
GetStatusIcon(comp.RevStatusIcon, ref args);
}
}

private void GetHeadRevIcon(EntityUid uid, HeadRevolutionaryComponent comp, ref GetStatusIconsEvent args)
{
GetStatusIcon(comp.HeadRevStatusIcon, ref args);
}
}
15 changes: 4 additions & 11 deletions Content.Client/Zombies/ZombieSystem.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
using System.Linq;
using System.Linq;
using Content.Client.Antag;
using Content.Shared.Humanoid;
using Content.Shared.StatusIcon;
using Content.Shared.StatusIcon.Components;
using Content.Shared.Zombies;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Shared.Prototypes;

namespace Content.Client.Zombies;

public sealed class ZombieSystem : SharedZombieSystem
public sealed class ZombieSystem : AntagStatusIconSystem<ZombieComponent>
{
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;

public override void Initialize()
{
Expand All @@ -38,9 +34,6 @@ private void OnStartup(EntityUid uid, ZombieComponent component, ComponentStartu

private void OnGetStatusIcon(EntityUid uid, ZombieComponent component, ref GetStatusIconsEvent args)
{
if (!HasComp<ZombieComponent>(_player.LocalPlayer?.ControlledEntity))
return;

args.StatusIcons.Add(_prototype.Index<StatusIconPrototype>(component.ZombieStatusIcon));
GetStatusIcon(component.ZombieStatusIcon, ref args);
}
}
22 changes: 22 additions & 0 deletions Content.Server/Administration/Systems/AdminVerbSystem.Antags.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Content.Server.GameTicking;
using Content.Server.GameTicking.Rules;
using Content.Server.Zombies;
using Content.Shared.Administration;
Expand All @@ -8,6 +9,8 @@
using Content.Shared.Verbs;
using Robust.Server.GameObjects;
using Robust.Shared.Utility;
using Content.Server.GameTicking.Rules.Components;
using System.Linq;

namespace Content.Server.Administration.Systems;

Expand All @@ -17,7 +20,9 @@ public sealed partial class AdminVerbSystem
[Dependency] private readonly TraitorRuleSystem _traitorRule = default!;
[Dependency] private readonly NukeopsRuleSystem _nukeopsRule = default!;
[Dependency] private readonly PiratesRuleSystem _piratesRule = default!;
[Dependency] private readonly RevolutionaryRuleSystem _revolutionaryRule = default!;
[Dependency] private readonly SharedMindSystem _minds = default!;
[Dependency] private readonly GameTicker _gameTicker = default!;

// All antag verbs have names so invokeverb works.
private void AddAntagVerbs(GetVerbsEvent<Verb> args)
Expand Down Expand Up @@ -100,5 +105,22 @@ private void AddAntagVerbs(GetVerbsEvent<Verb> args)
Message = Loc.GetString("admin-verb-make-pirate"),
};
args.Verbs.Add(pirate);

//todo come here at some point dear lort.
Verb headRev = new()
{
Text = Loc.GetString("admin-verb-text-make-head-rev"),
Category = VerbCategory.Antag,
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/Misc/job_icons.rsi/HeadRevolutionary.png")),
Act = () =>
{
if (!_minds.TryGetMind(args.Target, out var mindId, out var mind))
return;
_revolutionaryRule.OnHeadRevAdmin(mindId, mind);
},
Impact = LogImpact.High,
Message = Loc.GetString("admin-verb-make-head-rev"),
};
args.Verbs.Add(headRev);
}
}
237 changes: 237 additions & 0 deletions Content.Server/Antag/AntagSelectionSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
using Content.Server.GameTicking.Rules;
using Content.Server.GameTicking.Rules.Components;
using Content.Server.Roles.Jobs;
using Content.Server.Preferences.Managers;
using Content.Shared.Humanoid;
using Content.Shared.Preferences;
using Robust.Server.Player;
using System.Linq;
using Content.Server.Mind;
using Robust.Shared.Random;
using Robust.Shared.Map;
using System.Numerics;
using Content.Shared.Inventory;
using Content.Server.Storage.EntitySystems;
using Robust.Shared.Audio;
using Robust.Server.GameObjects;
using Content.Server.Chat.Managers;
using Content.Server.GameTicking;
using Robust.Shared.Containers;
using Content.Shared.Mobs.Components;
using Content.Server.Station.Systems;
using Content.Server.Shuttles.Systems;
using Content.Shared.Mobs;
using Robust.Server.Containers;
using Robust.Shared.Prototypes;

namespace Content.Server.Antag;

public sealed class AntagSelectionSystem : GameRuleSystem<GameRuleComponent>
{
[Dependency] private readonly IChatManager _chatManager = default!;
[Dependency] private readonly IServerPreferencesManager _prefs = default!;
[Dependency] private readonly IPlayerManager _playerSystem = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly AudioSystem _audioSystem = default!;
[Dependency] private readonly ContainerSystem _containerSystem = default!;
[Dependency] private readonly JobSystem _jobs = default!;
[Dependency] private readonly MindSystem _mindSystem = default!;
[Dependency] private readonly InventorySystem _inventory = default!;
[Dependency] private readonly StorageSystem _storageSystem = default!;
[Dependency] private readonly StationSystem _stationSystem = default!;
[Dependency] private readonly EmergencyShuttleSystem _emergencyShuttle = default!;

/// <summary>
/// Attempts to start the game rule by checking if there are enough players in lobby and readied.
/// </summary>
/// <param name="ev">The roundstart attempt event</param>
/// <param name="uid">The entity the gamerule you are using is on</param>
/// <param name="minPlayers">The minimum amount of players needed for you gamerule to start.</param>
/// <param name="gameRule">The gamerule component.</param>

public void AttemptStartGameRule(RoundStartAttemptEvent ev, EntityUid uid, int minPlayers, GameRuleComponent gameRule)
{
if (GameTicker.IsGameRuleAdded(uid, gameRule))
{
if (!ev.Forced && ev.Players.Length < minPlayers)
{
_chatManager.SendAdminAnnouncement(Loc.GetString("rev-not-enough-ready-players",
("readyPlayersCount", ev.Players.Length),
("minimumPlayers", minPlayers)));
ev.Cancel();
}
else if (ev.Players.Length == 0)
{
_chatManager.DispatchServerAnnouncement(Loc.GetString("rev-no-one-ready"));
ev.Cancel();
}
}
}

/// <summary>
/// Will check which players are eligible to be chosen for antagonist and give them the given antag.
/// </summary>
/// <param name="antagPrototype">The antag prototype from your rule component.</param>
/// <param name="maxAntags">How many antags can be present in any given round.</param>
/// <param name="antagsPerPlayer">How many players you need to spawn an additional antag.</param>
/// <param name="antagSound">The intro sound that plays when the antag is chosen.</param>
/// <param name="antagGreeting">The antag message you want shown when the antag is chosen.</param>
/// <param name="greetingColor">The color of the message for the antag greeting in hex.</param>
/// <param name="chosen">A list of all the antags chosen in case you need to add stuff after.</param>
/// <param name="includeHeads">Whether or not heads can be chosen as antags for this gamemode.</param>
public void EligiblePlayers(string antagPrototype,
int maxAntags,
int antagsPerPlayer,
SoundSpecifier? antagSound,
string antagGreeting,
string greetingColor,
out List<EntityUid> chosen,
bool includeHeads = false)
{
var allPlayers = _playerSystem.ServerSessions.ToList();
var playerList = new List<IPlayerSession>();
var prefList = new List<IPlayerSession>();
chosen = new List<EntityUid>();
foreach (var player in allPlayers)
{
if (includeHeads == false)
{
if (!_jobs.CanBeAntag(player))
continue;
}

if (player.AttachedEntity == null || HasComp<HumanoidAppearanceComponent>(player.AttachedEntity))
playerList.Add(player);
else
continue;

var pref = (HumanoidCharacterProfile) _prefs.GetPreferences(player.UserId).SelectedCharacter;
if (pref.AntagPreferences.Contains(antagPrototype))
prefList.Add(player);
}

if (playerList.Count == 0)
return;

var antags = Math.Clamp(allPlayers.Count / antagsPerPlayer, 1, maxAntags);
for (var antag = 0; antag < antags; antag++)
{
IPlayerSession chosenPlayer;
if (prefList.Count == 0)
{
if (playerList.Count == 0)
{
break;
}
chosenPlayer = _random.PickAndTake(playerList);
}
else
{
chosenPlayer = _random.PickAndTake(prefList);
playerList.Remove(chosenPlayer);
}

if (!_mindSystem.TryGetMind(chosenPlayer, out _, out var mind) ||
mind.OwnedEntity is not { } ownedEntity)
{
continue;
}

chosen.Add(ownedEntity);
_audioSystem.PlayGlobal(antagSound, ownedEntity);
if (mind.Session != null)
{
var message = Loc.GetString(antagGreeting);
var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", message));
_chatManager.ChatMessageToOne(Shared.Chat.ChatChannel.Server, message, wrappedMessage, default, false, mind.Session.ConnectedClient, Color.FromHex(greetingColor));
}
}
}

/// <summary>
/// Will take a group of entities and check if they are all alive or dead
/// </summary>
/// <param name="list">The list of the entities</param>
/// <param name="checkOffStation">Bool for if you want to check if someone is in space and consider them dead. (Won't check when emergency shuttle arrives just in case)</param>
/// <returns></returns>
public bool IsGroupDead(List<EntityUid> list, bool checkOffStation)
{
var dead = 0;
foreach (var entity in list)
{
if (TryComp<MobStateComponent>(entity, out var state))
{
if (state.CurrentState == MobState.Dead || state.CurrentState == MobState.Invalid)
{
dead++;
}
else if (checkOffStation && _stationSystem.GetOwningStation(entity) == null && !_emergencyShuttle.EmergencyShuttleArrived)
{
dead++;
}
}
//If they don't have the MobStateComponent they might as well be dead.
else
{
dead++;
}
}

return dead == list.Count || list.Count == 0;
}

/// <summary>
/// Will attempt to spawn an item inside of a persons bag and then pockets.
/// </summary>
/// <param name="antag">The entity that you want to spawn an item on</param>
/// <param name="items">A list of prototype IDs that you want to spawn in the bag.</param>
public void GiveAntagBagGear(EntityUid antag, List<EntProtoId> items)
{
foreach (var item in items)
{
GiveAntagBagGear(antag, item);
}
}

/// <summary>
/// Will attempt to spawn an item inside of a persons bag and then pockets.
/// </summary>
/// <param name="antag">The entity that you want to spawn an item on</param>
/// <param name="item">The prototype ID that you want to spawn in the bag.</param>
public void GiveAntagBagGear(EntityUid antag, string item)
{
var itemToSpawn = Spawn(item, new EntityCoordinates(antag, Vector2.Zero));
if (!_inventory.TryGetSlotContainer(antag, "back", out var backSlot, out _))
return;

var bag = backSlot.ContainedEntity;
if (bag != null && HasComp<ContainerManagerComponent>(bag) && _storageSystem.CanInsert(bag.Value, itemToSpawn, out _))
{
_storageSystem.Insert(bag.Value, itemToSpawn, out _);
}
else if (_inventory.TryGetSlotContainer(antag, "jumpsuit", out var jumpsuit, out _) && jumpsuit.ContainedEntity != null)
{
if (_inventory.TryGetSlotContainer(antag, "pocket1", out var pocket1Slot, out _))
{
if (pocket1Slot.ContainedEntity == null)
{
if (_containerSystem.CanInsert(itemToSpawn, pocket1Slot))
{
pocket1Slot.Insert(itemToSpawn);
}
}
else if (_inventory.TryGetSlotContainer(antag, "pocket2", out var pocket2Slot, out _))
{
if (pocket2Slot.ContainedEntity == null)
{
if (_containerSystem.CanInsert(itemToSpawn, pocket2Slot))
{
pocket2Slot.Insert(itemToSpawn);
}
}
}
}
}
}
}

Loading