Files
crystall-punk-14/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs

187 lines
7.4 KiB
C#
Raw Normal View History

New Thief minor antagonist (#21520) * start working * add right-click thief antagins some architecture restruct * add meh thief greeting audio * add thief subgamemode to Traitors gamemode * add late join thief (not tested yet) add briefing * add pacifism * add Steal tasks to thief * fix crash thief+traitor on person * add new condition: collection steal * add tracking of succes collection objective * add stamp collection target remove some boring steal target add check pulling entity to collection target * finalize first 2 group objective * start merging stealing objective systems * merging * finish merging. Now traitor steal objective work better * we don't check the items of pullable sentient entity * clear naming, enable thief signle item objective start * objective pack add * finish with steal item objectives * convert string to ProtoId<> * some clean up * add thieves to revolution game mode * Update Resources/Locale/en-US/game-ticking/game-presets/preset-thief.ftl Co-authored-by: Flareguy <78941145+Flareguy@users.noreply.github.com> * Update Resources/Locale/en-US/game-ticking/game-presets/preset-thief.ftl Co-authored-by: Flareguy <78941145+Flareguy@users.noreply.github.com> * update pacifism: fix crashing, monkey-thief without pacified * adaptive animal briefing, cleaning locales * add structure steal objectives * remove RCD target * add thiefs to manifest, but bug with traitor duplications * add escape objective * add chat briefing * setup animal objective group system * add animal steal objectives * add animal objectives notroleconditions * add morty * now thief mode has a chance of not launching Now there are a random number of thieves per round from 1 to 3 * 6 hours of trying to fix duplicate tasks. Failure * added thief pinpointer (buggy) * start thief backpack UI work * revert pinpointer for scope reason * UI continue work * add thief starter kits content * remove ERP kit :trollface: * finally! giving starting items to thief. Now it playable, but still need more work * clean up * fix * fox * add merged items into thief new Starting Kit (buggy) * fix YES antag menu * objection tweaks * remove hearts objective, working on spawning things from toolbox * smug * fixes * add race specifier objective condition LAMPS * meh * fix fix fix * the alive * Adding stamps * Update backpack.ftl * Revert1 * Revert ftl * add voice mask to communicator kit * Update Resources/Locale/en-US/administration/antag.ftl Co-authored-by: Colin-Tel <113523727+Colin-Tel@users.noreply.github.com> * Update Resources/Locale/en-US/game-ticking/game-presets/preset-thief.ftl Co-authored-by: Colin-Tel <113523727+Colin-Tel@users.noreply.github.com> * Update Resources/Locale/en-US/thief/backpack.ftl Co-authored-by: Colin-Tel <113523727+Colin-Tel@users.noreply.github.com> * Update Resources/Locale/en-US/objectives/conditions/steal.ftl Co-authored-by: Colin-Tel <113523727+Colin-Tel@users.noreply.github.com> * Update Resources/Locale/en-US/thief/backpack.ftl Co-authored-by: Colin-Tel <113523727+Colin-Tel@users.noreply.github.com> * Update Resources/Locale/en-US/thief/backpack.ftl Co-authored-by: Colin-Tel <113523727+Colin-Tel@users.noreply.github.com> * Update Resources/Locale/en-US/thief/backpack.ftl Co-authored-by: Colin-Tel <113523727+Colin-Tel@users.noreply.github.com> * Update Resources/Locale/en-US/thief/backpack.ftl Co-authored-by: Colin-Tel <113523727+Colin-Tel@users.noreply.github.com> * Update Resources/Locale/en-US/prototypes/roles/antags.ftl Co-authored-by: Colin-Tel <113523727+Colin-Tel@users.noreply.github.com> * Update Resources/Locale/en-US/thief/backpack.ftl Co-authored-by: Colin-Tel <113523727+Colin-Tel@users.noreply.github.com> * update * fix * more reusable function, add documentation * fix doc * faint fixes --------- Co-authored-by: Flareguy <78941145+Flareguy@users.noreply.github.com> Co-authored-by: Colin-Tel <113523727+Colin-Tel@users.noreply.github.com>
2023-12-24 12:58:28 +03:00
using Content.Server.Antag;
2023-04-25 20:23:14 -04:00
using Content.Server.GameTicking.Rules.Components;
2023-06-18 11:33:19 -07:00
using Content.Server.Mind;
using Content.Server.Objectives;
using Content.Server.PDA.Ringer;
2021-12-21 21:23:29 +01:00
using Content.Server.Roles;
using Content.Server.Traitor.Uplink;
using Content.Shared.Mind;
using Content.Shared.NPC.Systems;
using Content.Shared.Objectives.Components;
using Content.Shared.PDA;
using Content.Shared.Roles;
using Content.Shared.Roles.Jobs;
2021-12-21 21:23:29 +01:00
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using System.Linq;
using System.Text;
using Content.Server.GameTicking.Components;
2021-12-21 21:23:29 +01:00
namespace Content.Server.GameTicking.Rules;
2023-04-25 20:23:14 -04:00
public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
2021-12-21 21:23:29 +01:00
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IRobustRandom _random = default!;
2023-07-17 15:51:52 +12:00
[Dependency] private readonly NpcFactionSystem _npcFaction = default!;
[Dependency] private readonly AntagSelectionSystem _antag = default!;
2022-08-17 00:34:25 -04:00
[Dependency] private readonly UplinkSystem _uplink = default!;
2023-06-18 11:33:19 -07:00
[Dependency] private readonly MindSystem _mindSystem = default!;
[Dependency] private readonly SharedRoleSystem _roleSystem = default!;
[Dependency] private readonly SharedJobSystem _jobs = default!;
[Dependency] private readonly ObjectivesSystem _objectives = default!;
public const int MaxPicks = 20;
2021-12-21 21:23:29 +01:00
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<TraitorRuleComponent, AfterAntagEntitySelectedEvent>(AfterEntitySelected);
SubscribeLocalEvent<TraitorRuleComponent, ObjectivesTextGetInfoEvent>(OnObjectivesTextGetInfo);
SubscribeLocalEvent<TraitorRuleComponent, ObjectivesTextPrependEvent>(OnObjectivesTextPrepend);
2021-12-21 21:23:29 +01:00
}
protected override void Added(EntityUid uid, TraitorRuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args)
{
base.Added(uid, component, gameRule, args);
MakeCodewords(component);
}
private void AfterEntitySelected(Entity<TraitorRuleComponent> ent, ref AfterAntagEntitySelectedEvent args)
2023-04-24 16:21:05 +10:00
{
MakeTraitor(args.EntityUid, ent);
2021-12-21 21:23:29 +01:00
}
2023-04-25 20:23:14 -04:00
private void MakeCodewords(TraitorRuleComponent component)
{
var adjectives = _prototypeManager.Index(component.CodewordAdjectives).Values;
var verbs = _prototypeManager.Index(component.CodewordVerbs).Values;
var codewordPool = adjectives.Concat(verbs).ToList();
var finalCodewordCount = Math.Min(component.CodewordCount, codewordPool.Count);
2023-04-25 20:23:14 -04:00
component.Codewords = new string[finalCodewordCount];
for (var i = 0; i < finalCodewordCount; i++)
{
2023-04-25 20:23:14 -04:00
component.Codewords[i] = _random.PickAndTake(codewordPool);
}
}
public bool MakeTraitor(EntityUid traitor, TraitorRuleComponent component, bool giveUplink = true, bool giveObjectives = true)
{
//Grab the mind if it wasnt provided
if (!_mindSystem.TryGetMind(traitor, out var mindId, out var mind))
return false;
var briefing = Loc.GetString("traitor-role-codewords-short", ("codewords", string.Join(", ", component.Codewords)));
Note[]? code = null;
if (giveUplink)
{
// Calculate the amount of currency on the uplink.
var startingBalance = component.StartingBalance;
if (_jobs.MindTryGetJob(mindId, out _, out var prototype))
startingBalance = Math.Max(startingBalance - prototype.AntagAdvantage, 0);
// creadth: we need to create uplink for the antag.
// PDA should be in place already
var pda = _uplink.FindUplinkTarget(traitor);
if (pda == null || !_uplink.AddUplink(traitor, startingBalance))
return false;
// Give traitors their codewords and uplink code to keep in their character info menu
code = EnsureComp<RingerUplinkComponent>(pda.Value).Code;
// If giveUplink is false the uplink code part is omitted
briefing = string.Format("{0}\n{1}", briefing,
Loc.GetString("traitor-role-uplink-code-short", ("code", string.Join("-", code).Replace("sharp", "#"))));
}
2023-04-25 20:23:14 -04:00
_antag.SendBriefing(traitor, GenerateBriefing(component.Codewords, code), null, component.GreetSoundNotification);
component.TraitorMinds.Add(mindId);
// Assign briefing
_roleSystem.MindAddRole(mindId, new RoleBriefingComponent
{
Briefing = briefing
}, mind, true);
2021-12-21 21:23:29 +01:00
// Change the faction
_npcFaction.RemoveFaction(traitor, component.NanoTrasenFaction, false);
_npcFaction.AddFaction(traitor, component.SyndicateFaction);
// Give traitors their objectives
if (giveObjectives)
2021-12-21 21:23:29 +01:00
{
var difficulty = 0f;
for (var pick = 0; pick < MaxPicks && component.MaxDifficulty > difficulty; pick++)
{
var objective = _objectives.GetRandomObjective(mindId, mind, component.ObjectiveGroup);
if (objective == null)
continue;
2023-06-18 11:33:19 -07:00
_mindSystem.AddObjective(mindId, mind, objective.Value);
var adding = Comp<ObjectiveComponent>(objective.Value).Difficulty;
difficulty += adding;
Log.Debug($"Added objective {ToPrettyString(objective):objective} with {adding} difficulty");
}
2021-12-21 21:23:29 +01:00
}
return true;
2021-12-21 21:23:29 +01:00
}
private void OnObjectivesTextGetInfo(EntityUid uid, TraitorRuleComponent comp, ref ObjectivesTextGetInfoEvent args)
2021-12-21 21:23:29 +01:00
{
args.Minds = _antag.GetAntagMindEntityUids(uid);
args.AgentName = Loc.GetString("traitor-round-end-agent-name");
}
2023-04-25 20:23:14 -04:00
private void OnObjectivesTextPrepend(EntityUid uid, TraitorRuleComponent comp, ref ObjectivesTextPrependEvent args)
{
args.Text += "\n" + Loc.GetString("traitor-round-end-codewords", ("codewords", string.Join(", ", comp.Codewords)));
2021-12-21 21:23:29 +01:00
}
private string GenerateBriefing(string[] codewords, Note[]? uplinkCode)
{
var sb = new StringBuilder();
sb.AppendLine(Loc.GetString("traitor-role-greeting"));
sb.AppendLine(Loc.GetString("traitor-role-codewords-short", ("codewords", string.Join(", ", codewords))));
if (uplinkCode != null)
sb.AppendLine(Loc.GetString("traitor-role-uplink-code-short", ("code", string.Join("-", uplinkCode).Replace("sharp", "#"))));
return sb.ToString();
}
public List<(EntityUid Id, MindComponent Mind)> GetOtherTraitorMindsAliveAndConnected(MindComponent ourMind)
{
List<(EntityUid Id, MindComponent Mind)> allTraitors = new();
var query = EntityQueryEnumerator<TraitorRuleComponent>();
while (query.MoveNext(out var uid, out var traitor))
2023-04-25 20:23:14 -04:00
{
foreach (var role in GetOtherTraitorMindsAliveAndConnected(ourMind, (uid, traitor)))
2023-04-25 20:23:14 -04:00
{
if (!allTraitors.Contains(role))
allTraitors.Add(role);
}
}
2023-04-25 20:23:14 -04:00
return allTraitors;
}
private List<(EntityUid Id, MindComponent Mind)> GetOtherTraitorMindsAliveAndConnected(MindComponent ourMind, Entity<TraitorRuleComponent> rule)
2023-04-25 20:23:14 -04:00
{
var traitors = new List<(EntityUid Id, MindComponent Mind)>();
foreach (var mind in _antag.GetAntagMinds(rule.Owner))
{
if (mind.Comp == ourMind)
continue;
traitors.Add((mind, mind));
}
return traitors;
}
2021-12-21 21:23:29 +01:00
}