Thief hotfix (#22976)

* fixes!

* reduced collection amount

* omeeeeega

* pipup

* popup
This commit is contained in:
Ed
2023-12-27 23:42:15 +03:00
committed by GitHub
parent 7d19a323b5
commit 166296b2c5
10 changed files with 77 additions and 57 deletions

View File

@@ -26,8 +26,10 @@ public sealed class ThiefBackpackBoundUserInterface : BoundUserInterface
if (!disposing) if (!disposing)
return; return;
if (_window != null)
_window.OnClose -= Close;
_window?.Dispose(); _window?.Dispose();
_window = null;
} }
protected override void UpdateState(BoundUserInterfaceState state) protected override void UpdateState(BoundUserInterfaceState state)

View File

@@ -132,7 +132,7 @@ public sealed partial class AdminVerbSystem
if (!_minds.TryGetSession(targetMindComp.Mind, out var session)) if (!_minds.TryGetSession(targetMindComp.Mind, out var session))
return; return;
_thief.MakeThief(session, false); //Midround add pacific is bad _thief.AdminMakeThief(session, false); //Midround add pacific is bad
}, },
Impact = LogImpact.High, Impact = LogImpact.High,
Message = Loc.GetString("admin-verb-make-thief"), Message = Loc.GetString("admin-verb-make-thief"),

View File

@@ -15,6 +15,7 @@ public sealed partial class ThiefRuleComponent : Component
/// <summary> /// <summary>
/// Add a Pacified comp to thieves /// Add a Pacified comp to thieves
/// </summary> /// </summary>
[DataField]
public bool PacifistThieves = true; public bool PacifistThieves = true;
/// <summary> /// <summary>
@@ -41,9 +42,10 @@ public sealed partial class ThiefRuleComponent : Component
public List<EntProtoId> StarterItems = new List<EntProtoId> { "ToolboxThief", "ClothingHandsChameleonThief" }; //TO DO - replace to chameleon thieving gloves whem merg public List<EntProtoId> StarterItems = new List<EntProtoId> { "ToolboxThief", "ClothingHandsChameleonThief" }; //TO DO - replace to chameleon thieving gloves whem merg
/// <summary> /// <summary>
/// All Thiefes created by this rule /// All Thieves created by this rule
/// </summary> /// </summary>
public readonly List<EntityUid> ThiefMinds = new(); [DataField]
public List<EntityUid> ThievesMinds = new();
/// <summary> /// <summary>
/// Max Thiefs created by rule on roundstart /// Max Thiefs created by rule on roundstart

View File

@@ -2,11 +2,9 @@ using Content.Server.Chat.Managers;
using Content.Server.GameTicking.Rules.Components; using Content.Server.GameTicking.Rules.Components;
using Content.Server.Mind; using Content.Server.Mind;
using Content.Server.Objectives; using Content.Server.Objectives;
using Content.Server.Shuttles.Components;
using Content.Server.Roles; using Content.Server.Roles;
using Content.Shared.Mind; using Content.Shared.Mind;
using Content.Shared.Objectives.Components; using Content.Shared.Objectives.Components;
using Content.Shared.Preferences;
using Content.Shared.Roles; using Content.Shared.Roles;
using Content.Shared.Roles.Jobs; using Content.Shared.Roles.Jobs;
using Robust.Shared.Player; using Robust.Shared.Player;
@@ -17,24 +15,26 @@ using Content.Shared.Humanoid;
using Content.Server.Antag; using Content.Server.Antag;
using Robust.Server.Audio; using Robust.Server.Audio;
using Content.Shared.CombatMode.Pacification; using Content.Shared.CombatMode.Pacification;
using Content.Shared.Random;
namespace Content.Server.GameTicking.Rules; namespace Content.Server.GameTicking.Rules;
public sealed class ThiefRuleSystem : GameRuleSystem<ThiefRuleComponent> public sealed class ThiefRuleSystem : GameRuleSystem<ThiefRuleComponent>
{ {
[Dependency] private readonly IChatManager _chatManager = default!; [Dependency] private readonly IChatManager _chatManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly AntagSelectionSystem _antagSelection = default!; [Dependency] private readonly AntagSelectionSystem _antagSelection = default!;
[Dependency] private readonly AudioSystem _audio = default!; [Dependency] private readonly AudioSystem _audio = default!;
[Dependency] private readonly MindSystem _mindSystem = default!; [Dependency] private readonly MindSystem _mindSystem = default!;
[Dependency] private readonly SharedRoleSystem _roleSystem = default!; [Dependency] private readonly SharedRoleSystem _roleSystem = default!;
[Dependency] private readonly SharedJobSystem _jobs = default!;
[Dependency] private readonly ObjectivesSystem _objectives = default!; [Dependency] private readonly ObjectivesSystem _objectives = default!;
const string bigObjectiveGroup = "ThiefBigObjectiveGroups"; [ValidatePrototypeId<WeightedRandomPrototype>]
const string smallObjectiveGroup = "ThiefObjectiveGroups"; const string BigObjectiveGroup = "ThiefBigObjectiveGroups";
const string escapeObjectiveGroup = "ThiefEscapeObjectiveGroups"; [ValidatePrototypeId<WeightedRandomPrototype>]
const string SmallObjectiveGroup = "ThiefObjectiveGroups";
[ValidatePrototypeId<WeightedRandomPrototype>]
const string EscapeObjectiveGroup = "ThiefEscapeObjectiveGroups";
private const float BigObjectiveChance = 0.7f; private const float BigObjectiveChance = 0.7f;
public override void Initialize() public override void Initialize()
@@ -52,24 +52,21 @@ public sealed class ThiefRuleSystem : GameRuleSystem<ThiefRuleComponent>
var query = EntityQueryEnumerator<ThiefRuleComponent, GameRuleComponent>(); var query = EntityQueryEnumerator<ThiefRuleComponent, GameRuleComponent>();
while (query.MoveNext(out var uid, out var thief, out var gameRule)) while (query.MoveNext(out var uid, out var thief, out var gameRule))
{ {
//Chance to not lauch gamerule //Chance to not lauch gamerule
if (!_random.Prob(thief.RuleChance)) if (_random.Prob(thief.RuleChance))
{ {
RemComp<ThiefRuleComponent>(uid); if (!GameTicker.IsGameRuleAdded(uid, gameRule))
continue;
}
if (!GameTicker.IsGameRuleAdded(uid, gameRule))
continue;
foreach (var player in ev.Players)
{
if (!ev.Profiles.ContainsKey(player.UserId))
continue; continue;
thief.StartCandidates[player] = ev.Profiles[player.UserId]; foreach (var player in ev.Players)
{
if (!ev.Profiles.TryGetValue(player.UserId, out var profile))
continue;
thief.StartCandidates[player] = profile;
}
DoThiefStart(thief);
} }
DoThiefStart(thief);
} }
} }
@@ -88,19 +85,12 @@ public sealed class ThiefRuleSystem : GameRuleSystem<ThiefRuleComponent>
foreach(var thief in selectedThieves) foreach(var thief in selectedThieves)
{ {
MakeThief(thief, component.PacifistThieves); MakeThief(component, thief, component.PacifistThieves);
} }
} }
public bool MakeThief(ICommonSession thief, bool AddPacified) public bool MakeThief(ThiefRuleComponent thiefRule, ICommonSession thief, bool addPacified)
{ {
var thiefRule = EntityQuery<ThiefRuleComponent>().FirstOrDefault();
if (thiefRule == null)
{
GameTicker.StartGameRule("Thief", out var ruleEntity);
thiefRule = Comp<ThiefRuleComponent>(ruleEntity);
}
//checks //checks
if (!_mindSystem.TryGetMind(thief, out var mindId, out var mind)) if (!_mindSystem.TryGetMind(thief, out var mindId, out var mind))
{ {
@@ -124,9 +114,12 @@ public sealed class ThiefRuleSystem : GameRuleSystem<ThiefRuleComponent>
PrototypeId = thiefRule.ThiefPrototypeId PrototypeId = thiefRule.ThiefPrototypeId
}); });
//Add Pacified //Add Pacified
if (AddPacified) //To Do: Long-term this should just be using the antag code to add components.
if (addPacified) //This check is important because some servers may want to disable the thief's pacifism. Do not remove.
{
EnsureComp<PacifiedComponent>(mind.OwnedEntity.Value); EnsureComp<PacifiedComponent>(mind.OwnedEntity.Value);
}
// Notificate player about new role assignment // Notificate player about new role assignment
if (_mindSystem.TryGetSession(mindId, out var session)) if (_mindSystem.TryGetSession(mindId, out var session))
@@ -140,7 +133,7 @@ public sealed class ThiefRuleSystem : GameRuleSystem<ThiefRuleComponent>
if (_random.Prob(BigObjectiveChance)) // 70% chance to 1 big objective (structure or animal) if (_random.Prob(BigObjectiveChance)) // 70% chance to 1 big objective (structure or animal)
{ {
var objective = _objectives.GetRandomObjective(mindId, mind, bigObjectiveGroup); var objective = _objectives.GetRandomObjective(mindId, mind, BigObjectiveGroup);
if (objective != null) if (objective != null)
{ {
_mindSystem.AddObjective(mindId, mind, objective.Value); _mindSystem.AddObjective(mindId, mind, objective.Value);
@@ -150,7 +143,7 @@ public sealed class ThiefRuleSystem : GameRuleSystem<ThiefRuleComponent>
for (var i = 0; i < thiefRule.MaxStealObjectives && thiefRule.MaxObjectiveDifficulty > difficulty; i++) // Many small objectives for (var i = 0; i < thiefRule.MaxStealObjectives && thiefRule.MaxObjectiveDifficulty > difficulty; i++) // Many small objectives
{ {
var objective = _objectives.GetRandomObjective(mindId, mind, smallObjectiveGroup); var objective = _objectives.GetRandomObjective(mindId, mind, SmallObjectiveGroup);
if (objective == null) if (objective == null)
continue; continue;
@@ -159,17 +152,29 @@ public sealed class ThiefRuleSystem : GameRuleSystem<ThiefRuleComponent>
} }
//Escape target //Escape target
var escapeObjective = _objectives.GetRandomObjective(mindId, mind, escapeObjectiveGroup); var escapeObjective = _objectives.GetRandomObjective(mindId, mind, EscapeObjectiveGroup);
if (escapeObjective != null) if (escapeObjective != null)
_mindSystem.AddObjective(mindId, mind, escapeObjective.Value); _mindSystem.AddObjective(mindId, mind, escapeObjective.Value);
// Give starting items // Give starting items
_antagSelection.GiveAntagBagGear(mind.OwnedEntity.Value, thiefRule.StarterItems); _antagSelection.GiveAntagBagGear(mind.OwnedEntity.Value, thiefRule.StarterItems);
thiefRule.ThiefMinds.Add(mindId); thiefRule.ThievesMinds.Add(mindId);
return true; return true;
} }
public void AdminMakeThief(ICommonSession thief, bool addPacified)
{
var thiefRule = EntityQuery<ThiefRuleComponent>().FirstOrDefault();
if (thiefRule == null)
{
GameTicker.StartGameRule("Thief", out var ruleEntity);
thiefRule = Comp<ThiefRuleComponent>(ruleEntity);
}
MakeThief(thiefRule, thief, addPacified);
}
//Add mind briefing //Add mind briefing
private void OnGetBriefing(Entity<ThiefRoleComponent> thief, ref GetBriefingEvent args) private void OnGetBriefing(Entity<ThiefRoleComponent> thief, ref GetBriefingEvent args)
{ {
@@ -193,7 +198,7 @@ public sealed class ThiefRuleSystem : GameRuleSystem<ThiefRuleComponent>
private void OnObjectivesTextGetInfo(Entity<ThiefRuleComponent> thiefs, ref ObjectivesTextGetInfoEvent args) private void OnObjectivesTextGetInfo(Entity<ThiefRuleComponent> thiefs, ref ObjectivesTextGetInfoEvent args)
{ {
args.Minds = thiefs.Comp.ThiefMinds; args.Minds = thiefs.Comp.ThievesMinds;
args.AgentName = Loc.GetString("thief-round-end-agent-name"); args.AgentName = Loc.GetString("thief-round-end-agent-name");
} }
} }

View File

@@ -1,3 +1,4 @@
using Content.Server.Thief.Systems;
using Content.Shared.Thief; using Content.Shared.Thief;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
@@ -8,7 +9,7 @@ namespace Content.Server.Thief.Components;
/// This component stores the possible contents of the backpack, /// This component stores the possible contents of the backpack,
/// which can be selected via the interface. /// which can be selected via the interface.
/// </summary> /// </summary>
[RegisterComponent] [RegisterComponent, Access(typeof(ThiefUndeterminedBackpackSystem))]
public sealed partial class ThiefUndeterminedBackpackComponent : Component public sealed partial class ThiefUndeterminedBackpackComponent : Component
{ {
/// <summary> /// <summary>

View File

@@ -6,6 +6,11 @@ using Robust.Server.Audio;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
namespace Content.Server.Thief.Systems; namespace Content.Server.Thief.Systems;
/// <summary>
/// <see cref="ThiefUndeterminedBackpackComponent"/>
/// this system links the interface to the logic, and will output to the player a set of items selected by him in the interface
/// </summary>
public sealed class ThiefUndeterminedBackpackSystem : EntitySystem public sealed class ThiefUndeterminedBackpackSystem : EntitySystem
{ {
[Dependency] private readonly AudioSystem _audio = default!; [Dependency] private readonly AudioSystem _audio = default!;
@@ -44,7 +49,7 @@ public sealed class ThiefUndeterminedBackpackSystem : EntitySystem
} }
} }
_audio.PlayPvs(backpack.Comp.ApproveSound, backpack.Owner); _audio.PlayPvs(backpack.Comp.ApproveSound, backpack.Owner);
QueueDel(backpack); //hehe QueueDel(backpack);
} }
private void OnChangeSet(Entity<ThiefUndeterminedBackpackComponent> backpack, ref ThiefBackpackChangeSetMessage args) private void OnChangeSet(Entity<ThiefUndeterminedBackpackComponent> backpack, ref ThiefBackpackChangeSetMessage args)
{ {

View File

@@ -3,7 +3,7 @@ thief-backpack-window-title = thief toolbox
thief-backpack-window-description = thief-backpack-window-description =
This toolbox is filled with unspecified contents. This toolbox is filled with unspecified contents.
Now you need to remember what you put in it. Now you need to remember what you put in it.
Choose up to two different sets from the list. Choose 2 different sets from the list.
thief-backpack-window-selected = Kits selected: ({$selectedCount}/{$maxCount}) thief-backpack-window-selected = Kits selected: ({$selectedCount}/{$maxCount})
@@ -32,12 +32,13 @@ thief-backpack-category-chemistry-description =
A set for those who love to improve their body. A set for those who love to improve their body.
It includes a storage implanter, It includes a storage implanter,
a DNA scrambler implanter, a DNA scrambler implanter,
and a set of chemicals for a rainy day. a set of chemicals for a rainy day,
and omega soap.
thief-backpack-category-syndie-name = syndie kit thief-backpack-category-syndie-name = syndie kit
thief-backpack-category-syndie-description = thief-backpack-category-syndie-description =
A set of items from a syndicate agent you've robbed A set of items from a syndicate agent you've robbed
in the past. Includes an Agent ID card, a syndicate pAI, in the past. Includes an Agent ID card, Emag, a syndicate pAI,
and some strange red crystals. and some strange red crystals.
thief-backpack-category-sleeper-name = sleepwalker's kit thief-backpack-category-sleeper-name = sleepwalker's kit
@@ -50,13 +51,13 @@ thief-backpack-category-sleeper-description =
thief-backpack-category-communicator-name = communicator's kit thief-backpack-category-communicator-name = communicator's kit
thief-backpack-category-communicator-description = thief-backpack-category-communicator-description =
A communication enthusiast's kit. Includes a master key A communication enthusiast's kit. Includes a master key
for all station channels, a radio jammer, a portable for all station channels, a cybersun pen, a portable
crew monitor, a voice chameleon mask and lots of money for business deals. crew monitor, a voice chameleon mask and lots of money for business deals.
thief-backpack-category-smuggler-name = smuggler's kit thief-backpack-category-smuggler-name = smuggler's kit
thief-backpack-category-smuggler-description = thief-backpack-category-smuggler-description =
A kit for those who like to have big pockets. A kit for those who like to have big pockets.
Includes a fulton beacon, ten fultons Includes a fulton beacon, ten fultons, 3 smoke grenades
and an invisible crate. You can't move in them, and an invisible crate. You can't move in them,
but you can quickly hide or carry valuable loot. but you can quickly hide or carry valuable loot.
This kit also has a cool void cloak to go along with it. This kit also has a cool void cloak to go along with it.

View File

@@ -43,7 +43,7 @@
- StorageImplanter - StorageImplanter
- DnaScramblerImplanter - DnaScramblerImplanter
- EphedrineChemistryBottle - EphedrineChemistryBottle
- OmnizineChemistryBottle - SoapOmega
- Syringe - Syringe
- DrinkVodkaBottleFull - DrinkVodkaBottleFull
@@ -56,6 +56,7 @@
state: telecrystal state: telecrystal
content: content:
- AgentIDCard - AgentIDCard
- Emag
- SyndicatePersonalAI - SyndicatePersonalAI
- ClothingHeadHatSyndieMAA - ClothingHeadHatSyndieMAA
- CigPackSyndicate - CigPackSyndicate
@@ -87,7 +88,7 @@
state: icon state: icon
content: content:
- EncryptionKeyStationMaster - EncryptionKeyStationMaster
- RadioJammer - CyberPen
- SpyCrewMonitor - SpyCrewMonitor
- BriefcaseSyndieLobbyingBundleFilled - BriefcaseSyndieLobbyingBundleFilled
- ClothingMaskGasVoiceChameleon - ClothingMaskGasVoiceChameleon
@@ -105,3 +106,6 @@
- ClothingNeckCloakVoid - ClothingNeckCloakVoid
- FultonBeacon - FultonBeacon
- Fulton - Fulton
- SmokeGrenade
- SmokeGrenade
- SmokeGrenade

View File

@@ -51,7 +51,7 @@
- type: weightedRandom - type: weightedRandom
id: ThiefBigObjectiveGroups id: ThiefBigObjectiveGroups
weights: weights:
ThiefObjectiveGroupStructure: 1 ThiefObjectiveGroupStructure: 0 #Temporarily disabled until obvious ways to steal structures are added
ThiefObjectiveGroupAnimal: 2 ThiefObjectiveGroupAnimal: 2
- type: weightedRandom - type: weightedRandom

View File

@@ -123,8 +123,8 @@
job: Scientist job: Scientist
- type: StealCondition - type: StealCondition
stealGroup: TechnologyDisk stealGroup: TechnologyDisk
minCollectionSize: 10 minCollectionSize: 5
maxCollectionSize: 20 maxCollectionSize: 15
verifyMapExistance: false verifyMapExistance: false
- type: Objective - type: Objective
difficulty: 0.8 difficulty: 0.8
@@ -136,8 +136,8 @@
components: components:
- type: StealCondition - type: StealCondition
stealGroup: IDCard stealGroup: IDCard
minCollectionSize: 10 minCollectionSize: 5
maxCollectionSize: 20 maxCollectionSize: 15
verifyMapExistance: false verifyMapExistance: false
- type: Objective - type: Objective
difficulty: 0.7 difficulty: 0.7
@@ -150,7 +150,7 @@
- type: StealCondition - type: StealCondition
stealGroup: EncryptionKey stealGroup: EncryptionKey
minCollectionSize: 5 minCollectionSize: 5
maxCollectionSize: 25 maxCollectionSize: 15
- type: Objective - type: Objective
difficulty: 0.7 difficulty: 0.7
@@ -180,7 +180,7 @@
- type: StealCondition - type: StealCondition
stealGroup: LAMP stealGroup: LAMP
minCollectionSize: 1 minCollectionSize: 1
maxCollectionSize: 30 maxCollectionSize: 10
verifyMapExistance: true verifyMapExistance: true
- type: Objective - type: Objective
difficulty: 0.5 # just for fun, collectings LAMP on Moth difficulty: 0.5 # just for fun, collectings LAMP on Moth