Make monkeys better (#19407)

Co-authored-by: deltanedas <@deltanedas:kde.org>
This commit is contained in:
deltanedas
2023-09-10 03:51:51 +01:00
committed by GitHub
parent 65053a1ec2
commit 152a1d1e75
6 changed files with 148 additions and 30 deletions

View File

@@ -2,6 +2,7 @@ using Content.Server.GameTicking.Rules;
using Content.Server.Zombies; using Content.Server.Zombies;
using Content.Shared.Administration; using Content.Shared.Administration;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.Humanoid;
using Content.Shared.Mind; using Content.Shared.Mind;
using Content.Shared.Mind.Components; using Content.Shared.Mind.Components;
using Content.Shared.Verbs; using Content.Shared.Verbs;
@@ -21,7 +22,7 @@ public sealed partial class AdminVerbSystem
// All antag verbs have names so invokeverb works. // All antag verbs have names so invokeverb works.
private void AddAntagVerbs(GetVerbsEvent<Verb> args) private void AddAntagVerbs(GetVerbsEvent<Verb> args)
{ {
if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor)) if (!TryComp<ActorComponent>(args.User, out var actor))
return; return;
var player = actor.PlayerSession; var player = actor.PlayerSession;
@@ -29,8 +30,7 @@ public sealed partial class AdminVerbSystem
if (!_adminManager.HasAdminFlag(player, AdminFlags.Fun)) if (!_adminManager.HasAdminFlag(player, AdminFlags.Fun))
return; return;
var targetHasMind = TryComp(args.Target, out MindContainerComponent? targetMindComp); if (!TryComp<MindContainerComponent>(args.Target, out var targetMindComp))
if (!targetHasMind || targetMindComp == null)
return; return;
Verb traitor = new() Verb traitor = new()
@@ -43,7 +43,9 @@ public sealed partial class AdminVerbSystem
if (!_minds.TryGetSession(targetMindComp.Mind, out var session)) if (!_minds.TryGetSession(targetMindComp.Mind, out var session))
return; return;
_traitorRule.MakeTraitor(session); // if its a monkey or mouse or something dont give uplink or objectives
var isHuman = HasComp<HumanoidAppearanceComponent>(args.Target);
_traitorRule.MakeTraitor(session, giveUplink: isHuman, giveObjectives: isHuman);
}, },
Impact = LogImpact.High, Impact = LogImpact.High,
Message = Loc.GetString("admin-verb-make-traitor"), Message = Loc.GetString("admin-verb-make-traitor"),

View File

@@ -205,7 +205,7 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
return results; return results;
} }
public bool MakeTraitor(ICommonSession traitor) public bool MakeTraitor(ICommonSession traitor, bool giveUplink = true, bool giveObjectives = true)
{ {
var traitorRule = EntityQuery<TraitorRuleComponent>().FirstOrDefault(); var traitorRule = EntityQuery<TraitorRuleComponent>().FirstOrDefault();
if (traitorRule == null) if (traitorRule == null)
@@ -240,19 +240,25 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
if (_jobs.MindTryGetJob(mindId, out _, out var prototype)) if (_jobs.MindTryGetJob(mindId, out _, out var prototype))
startingBalance = Math.Max(startingBalance - prototype.AntagAdvantage, 0); startingBalance = Math.Max(startingBalance - prototype.AntagAdvantage, 0);
// creadth: we need to create uplink for the antag. // Give traitors their codewords and uplink code to keep in their character info menu
// PDA should be in place already var briefing = Loc.GetString("traitor-role-codewords-short", ("codewords", string.Join(", ", traitorRule.Codewords)));
var pda = _uplink.FindUplinkTarget(mind.OwnedEntity!.Value); Note[]? code = null;
if (pda == null || !_uplink.AddUplink(mind.OwnedEntity.Value, startingBalance)) if (giveUplink)
return false; {
// creadth: we need to create uplink for the antag.
// PDA should be in place already
var pda = _uplink.FindUplinkTarget(mind.OwnedEntity!.Value);
if (pda == null || !_uplink.AddUplink(mind.OwnedEntity.Value, startingBalance))
return false;
// Add the ringtone uplink and get its code for greeting // Give traitors their codewords and uplink code to keep in their character info menu
var code = EnsureComp<RingerUplinkComponent>(pda.Value).Code; 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","#"))));
}
// Prepare traitor role // Prepare traitor role
// Give traitors their codewords and uplink code to keep in their character info menu
var briefing =
$"{Loc.GetString("traitor-role-codewords-short", ("codewords", string.Join(", ", traitorRule.Codewords)))}\n{Loc.GetString("traitor-role-uplink-code-short", ("code", string.Join("-", code).Replace("sharp", "#")))}";
var traitorRole = new TraitorRoleComponent var traitorRole = new TraitorRoleComponent
{ {
PrototypeId = traitorRule.TraitorPrototypeId, PrototypeId = traitorRule.TraitorPrototypeId,
@@ -282,17 +288,20 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
_npcFaction.AddFaction(entity, "Syndicate"); _npcFaction.AddFaction(entity, "Syndicate");
// Give traitors their objectives // Give traitors their objectives
var maxDifficulty = _cfg.GetCVar(CCVars.TraitorMaxDifficulty); if (giveObjectives)
var maxPicks = _cfg.GetCVar(CCVars.TraitorMaxPicks);
var difficulty = 0f;
for (var pick = 0; pick < maxPicks && maxDifficulty > difficulty; pick++)
{ {
var objective = _objectives.GetRandomObjective(mindId, mind, "TraitorObjectiveGroups"); var maxDifficulty = _cfg.GetCVar(CCVars.TraitorMaxDifficulty);
var maxPicks = _cfg.GetCVar(CCVars.TraitorMaxPicks);
var difficulty = 0f;
for (var pick = 0; pick < maxPicks && maxDifficulty > difficulty; pick++)
{
var objective = _objectives.GetRandomObjective(mindId, mind, "TraitorObjectiveGroups");
if (objective == null)
continue;
if (objective == null) if (_mindSystem.TryAddObjective(mindId, mind, objective))
continue; difficulty += objective.Difficulty;
if (_mindSystem.TryAddObjective(mindId, mind, objective)) }
difficulty += objective.Difficulty;
} }
return true; return true;
@@ -304,14 +313,15 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
/// <param name="mind">A mind (player)</param> /// <param name="mind">A mind (player)</param>
/// <param name="codewords">Codewords</param> /// <param name="codewords">Codewords</param>
/// <param name="code">Uplink codes</param> /// <param name="code">Uplink codes</param>
private void SendTraitorBriefing(EntityUid mind, string[] codewords, Note[] code) private void SendTraitorBriefing(EntityUid mind, string[] codewords, Note[]? code)
{ {
if (_mindSystem.TryGetSession(mind, out var session)) if (!_mindSystem.TryGetSession(mind, out var session))
{ return;
_chatManager.DispatchServerMessage(session, Loc.GetString("traitor-role-greeting"));
_chatManager.DispatchServerMessage(session, Loc.GetString("traitor-role-codewords", ("codewords", string.Join(", ", codewords)))); _chatManager.DispatchServerMessage(session, Loc.GetString("traitor-role-greeting"));
_chatManager.DispatchServerMessage(session, Loc.GetString("traitor-role-codewords", ("codewords", string.Join(", ", codewords))));
if (code != null)
_chatManager.DispatchServerMessage(session, Loc.GetString("traitor-role-uplink-code", ("code", string.Join("-", code).Replace("sharp","#")))); _chatManager.DispatchServerMessage(session, Loc.GetString("traitor-role-uplink-code", ("code", string.Join("-", code).Replace("sharp","#"))));
}
} }
private void HandleLatejoin(PlayerSpawnCompleteEvent ev) private void HandleLatejoin(PlayerSpawnCompleteEvent ev)

View File

@@ -0,0 +1,22 @@
using Content.Server.Traitor.Systems;
namespace Content.Server.Traitor.Components;
/// <summary>
/// Makes the entity a traitor either instantly if it has a mind or when a mind is added.
/// </summary>
[RegisterComponent, Access(typeof(AutoTraitorSystem))]
public sealed partial class AutoTraitorComponent : Component
{
/// <summary>
/// Whether to give the traitor an uplink or not.
/// </summary>
[DataField("giveUplink"), ViewVariables(VVAccess.ReadWrite)]
public bool GiveUplink = true;
/// <summary>
/// Whether to give the traitor objectives or not.
/// </summary>
[DataField("giveObjectives"), ViewVariables(VVAccess.ReadWrite)]
public bool GiveObjectives = true;
}

View File

@@ -0,0 +1,76 @@
using Content.Server.GameTicking.Rules;
using Content.Server.Traitor.Components;
using Content.Shared.Mind;
using Content.Shared.Mind.Components;
namespace Content.Server.Traitor.Systems;
/// <summary>
/// Makes entities with <see cref="AutoTraitorComponent"/> a traitor either immediately if they have a mind or when a mind is added.
/// </summary>
public sealed class AutoTraitorSystem : EntitySystem
{
[Dependency] private readonly TraitorRuleSystem _traitorRule = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<AutoTraitorComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<AutoTraitorComponent, MindAddedMessage>(OnMindAdded);
}
private void OnMapInit(EntityUid uid, AutoTraitorComponent comp, MapInitEvent args)
{
TryMakeTraitor(uid, comp);
}
private void OnMindAdded(EntityUid uid, AutoTraitorComponent comp, MindAddedMessage args)
{
TryMakeTraitor(uid, comp);
}
/// <summary>
/// Sets the GiveUplink field.
/// </summary>
public void SetGiveUplink(EntityUid uid, bool giveUplink, AutoTraitorComponent? comp = null)
{
if (!Resolve(uid, ref comp))
return;
comp.GiveUplink = giveUplink;
}
/// <summary>
/// Sets the GiveObjectives field.
/// </summary>
public void SetGiveObjectives(EntityUid uid, bool giveObjectives, AutoTraitorComponent? comp = null)
{
if (!Resolve(uid, ref comp))
return;
comp.GiveObjectives = giveObjectives;
}
/// <summary>
/// Checks if there is a mind, then makes it a traitor using the options.
/// </summary>
public bool TryMakeTraitor(EntityUid uid, AutoTraitorComponent? comp = null)
{
if (!Resolve(uid, ref comp))
return false;
if (!TryComp<MindContainerComponent>(uid, out var mindContainer) || mindContainer.Mind == null)
return false;
var mindId = mindContainer.Mind.Value;
if (!TryComp<MindComponent>(mindId, out var mind) || mind.Session == null)
return false;
var session = mind.Session;
_traitorRule.MakeTraitor(session, giveUplink: comp.GiveUplink, giveObjectives: comp.GiveObjectives);
// prevent spamming anything if it fails
RemComp<AutoTraitorComponent>(uid);
return true;
}
}

View File

@@ -811,6 +811,7 @@
- MobMask - MobMask
layer: layer:
- MobLayer - MobLayer
- type: Stripping
- type: Strippable - type: Strippable
- type: UserInterface - type: UserInterface
interfaces: interfaces:
@@ -985,6 +986,7 @@
- Trash - Trash
- VimPilot - VimPilot
- Mouse - Mouse
- DoorBumpOpener
- type: Respirator - type: Respirator
damage: damage:
types: types:
@@ -1494,6 +1496,11 @@
- type: Tag - type: Tag
tags: tags:
- VimPilot - VimPilot
- DoorBumpOpener
# make the player a traitor once its taken
- type: AutoTraitor
giveUplink: false
giveObjectives: false
# I have included a snake_hiss.ogg sound file so if you want to use that be my guest # I have included a snake_hiss.ogg sound file so if you want to use that be my guest
- type: entity - type: entity

View File

@@ -710,5 +710,6 @@
tags: tags:
- CannotSuicide - CannotSuicide
- DoorBumpOpener - DoorBumpOpener
- VimPilot
- type: Loadout - type: Loadout
prototypes: [ MobMonkeyGear ] prototypes: [ MobMonkeyGear ]