Merge remote-tracking branch 'upstream/master' into upstream-core

This commit is contained in:
Jabak
2024-08-29 13:25:33 +03:00
100 changed files with 5214 additions and 2476 deletions

View File

@@ -1,4 +1,3 @@
using Content.Server.GameTicking.Rules.Components;
using Content.Server._White.AspectsSystem.Aspects.Components;
using Content.Server._White.AspectsSystem.Base;
using Content.Server.GameTicking.Components;

View File

@@ -1,39 +1,29 @@
using Robust.Shared.Audio;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Server._White.AspectsSystem.Base
namespace Content.Server._White.AspectsSystem.Base;
[RegisterComponent]
public sealed partial class AspectComponent : Component
{
[RegisterComponent]
public sealed partial class AspectComponent : Component
{
[DataField("name")]
public string? Name;
[DataField] public string? Name;
[DataField("description")]
public string? Description;
[DataField] public string? Description;
[DataField("requires")]
public string? Requires;
[DataField] public string? Requires;
[DataField("weight")]
public float Weight = 1.0f;
[DataField] public float Weight = 1.0f;
[DataField("forbidden")]
public bool IsForbidden;
[DataField] public bool IsForbidden;
[DataField("hidden")]
public bool IsHidden;
[DataField] public bool IsHidden;
[DataField("startAudio")]
public SoundSpecifier? StartAudio;
[DataField] public SoundSpecifier? StartAudio;
[DataField("endAudio")]
public SoundSpecifier? EndAudio;
[DataField] public SoundSpecifier? EndAudio;
[DataField("startDelay")]
public TimeSpan StartDelay = TimeSpan.Zero;
[DataField] public TimeSpan StartDelay = TimeSpan.Zero;
[DataField("startTime", customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan StartTime;
}
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan StartTime;
}

View File

@@ -1,145 +1,182 @@
using System.Linq;
using Content.Server.Administration;
using Content.Server.GameTicking;
using Content.Server._White.AspectsSystem.Managers;
using Content.Shared.Administration;
using Robust.Shared.Console;
namespace Content.Server._White.AspectsSystem.Commands
namespace Content.Server._White.AspectsSystem.Commands;
[AdminCommand(AdminFlags.Fun)]
public sealed class ForceAspectCommand : IConsoleCommand
{
[AdminCommand(AdminFlags.Fun)]
public sealed class ForceAspectCommand : IConsoleCommand
[Dependency] private readonly IEntityManager _entityManager = default!;
public string Command => "forceaspect";
public string Description => "Принудительно форсит аспект по его ID.";
public string Help => "forceaspect <aspectId>";
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
public string Command => "forceaspect";
public string Description => "Принудительно форсит аспект по его ID.";
public string Help => "forceaspect <aspectId>";
var ticker = _entityManager.System<GameTicker>();
public void Execute(IConsoleShell shell, string argStr, string[] args)
if (ticker.RunLevel != GameRunLevel.PreRoundLobby)
{
var ticker = EntitySystem.Get<GameTicker>();
if (ticker.RunLevel != GameRunLevel.PreRoundLobby)
{
shell.WriteLine("This can only be executed while the game is in the pre-round lobby.");
return;
}
if (args.Length != 1)
{
shell.WriteError("Использование: forceaspect <aspectId>");
return;
}
var aspectId = args[0];
var aspectManager = EntitySystem.Get<AspectManager>();
var result = aspectManager.ForceAspect(aspectId);
shell.WriteLine(result);
shell.WriteLine("This can only be executed while the game is in the pre-round lobby.");
return;
}
if (args.Length != 1)
{
shell.WriteError("Использование: forceaspect <aspectId>");
return;
}
var aspectManager = _entityManager.System<AspectManager>();
var aspectId = args[0];
var result = aspectManager.ForceAspect(aspectId);
shell.WriteLine(result);
}
[AdminCommand(AdminFlags.Fun)]
public sealed class DeForceAspectCommand : IConsoleCommand
public CompletionResult GetCompletion(IConsoleShell shell, string[] args)
{
public string Command => "deforceaspect";
public string Description => "Дефорсит принудительно установленный аспект.";
public string Help => "deforceaspect";
if (args.Length != 1)
return CompletionResult.Empty;
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var ticker = EntitySystem.Get<GameTicker>();
if (ticker.RunLevel != GameRunLevel.PreRoundLobby)
{
shell.WriteLine("This can only be executed while the game is in the pre-round lobby.");
return;
}
var aspectManager = _entityManager.System<AspectManager>();
var aspectManager = EntitySystem.Get<AspectManager>();
var result = aspectManager.DeForceAspect();
shell.WriteLine(result);
}
var options = aspectManager
.GetAspectsPrototypesId()
.Select(p => new CompletionOption(p.Key.ID, p.Value.Name))
.OrderBy(p => p.Value);
return CompletionResult.FromHintOptions(options, Loc.GetString("forcemap-command-arg-map"));
}
}
[AdminCommand(AdminFlags.Fun)]
public sealed class GetForcedAspectCommand : IConsoleCommand
[AdminCommand(AdminFlags.Fun)]
public sealed class DeForceAspectCommand : IConsoleCommand
{
[Dependency] private readonly IEntityManager _entityManager = default!;
public string Command => "deforceaspect";
public string Description => "Дефорсит принудительно установленный аспект.";
public string Help => "deforceaspect";
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
public string Command => "getforcedaspect";
public string Description => "Получает информацию о принудительно установленном аспекте.";
public string Help => "getforcedaspect";
var ticker = _entityManager.System<GameTicker>();
public void Execute(IConsoleShell shell, string argStr, string[] args)
if (ticker.RunLevel != GameRunLevel.PreRoundLobby)
{
var ticker = EntitySystem.Get<GameTicker>();
if (ticker.RunLevel != GameRunLevel.PreRoundLobby)
{
shell.WriteLine("This can only be executed while the game is in the pre-round lobby.");
return;
}
var aspectManager = EntitySystem.Get<AspectManager>();
var result = aspectManager.GetForcedAspect();
shell.WriteLine(result);
shell.WriteLine("This can only be executed while the game is in the pre-round lobby.");
return;
}
var aspectManager = _entityManager.System<AspectManager>();
var result = aspectManager.DeForceAspect();
shell.WriteLine(result);
}
}
[AdminCommand(AdminFlags.Fun)]
public sealed class ListAspectsCommand : IConsoleCommand
[AdminCommand(AdminFlags.Fun)]
public sealed class GetForcedAspectCommand : IConsoleCommand
{
[Dependency] private readonly IEntityManager _entityManager = default!;
public string Command => "getforcedaspect";
public string Description => "Получает информацию о принудительно установленном аспекте.";
public string Help => "getforcedaspect";
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
public string Command => "listaspects";
public string Description => "Список всех доступных аспектов.";
public string Help => "listaspects";
var ticker = _entityManager.System<GameTicker>();
public void Execute(IConsoleShell shell, string argStr, string[] args)
if (ticker.RunLevel != GameRunLevel.PreRoundLobby)
{
var aspectManager = EntitySystem.Get<AspectManager>();
var aspectIds = aspectManager.GetAllAspectIds();
if (aspectIds.Count == 0)
{
shell.WriteLine("Нет доступных аспектов.");
}
else
{
shell.WriteLine("Список доступных аспектов:");
foreach (var aspectId in aspectIds)
{
shell.WriteLine(aspectId);
}
}
shell.WriteLine("This can only be executed while the game is in the pre-round lobby.");
return;
}
var aspectManager = _entityManager.System<AspectManager>();
var result = aspectManager.GetForcedAspect();
shell.WriteLine(result);
}
}
[AdminCommand(AdminFlags.Fun)]
public sealed class RunAspectCommand : IConsoleCommand
[AdminCommand(AdminFlags.Fun)]
public sealed class ListAspectsCommand : IConsoleCommand
{
[Dependency] private readonly IEntityManager _entityManager = default!;
public string Command => "listaspects";
public string Description => "Список всех доступных аспектов.";
public string Help => "listaspects";
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
public string Command => "runaspect";
public string Description => "Запускает аспект по его ID.";
public string Help => "runaspect <aspectId>";
var aspectManager = _entityManager.System<AspectManager>();
public void Execute(IConsoleShell shell, string argStr, string[] args)
var aspectIds = aspectManager.GetAllAspectIds();
if (aspectIds.Count == 0)
{
if (args.Length != 1)
{
shell.WriteError("Использование: runaspect <aspectId>");
return;
}
var aspectId = args[0];
var aspectManager = EntitySystem.Get<AspectManager>();
var result = aspectManager.RunAspect(aspectId);
shell.WriteLine(result);
shell.WriteLine("Нет доступных аспектов.");
}
}
[AdminCommand(AdminFlags.Fun)]
public sealed class RunRandomAspectCommand : IConsoleCommand
{
public string Command => "runrandomaspect";
public string Description => "Запускает случайный аспект.";
public string Help => "runrandomaspect";
public void Execute(IConsoleShell shell, string argStr, string[] args)
else
{
var aspectManager = EntitySystem.Get<AspectManager>();
var result = aspectManager.RunRandomAspect();
shell.WriteLine(result);
shell.WriteLine("Список доступных аспектов:");
foreach (var aspectId in aspectIds)
{
shell.WriteLine(aspectId);
}
}
}
}
[AdminCommand(AdminFlags.Fun)]
public sealed class RunAspectCommand : IConsoleCommand
{
[Dependency] private readonly IEntityManager _entityManager = default!;
public string Command => "runaspect";
public string Description => "Запускает аспект по его ID.";
public string Help => "runaspect <aspectId>";
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length != 1)
{
shell.WriteError("Использование: runaspect <aspectId>");
return;
}
var aspectId = args[0];
var aspectManager = _entityManager.System<AspectManager>();
var result = aspectManager.RunAspect(aspectId);
shell.WriteLine(result);
}
}
[AdminCommand(AdminFlags.Fun)]
public sealed class RunRandomAspectCommand : IConsoleCommand
{
[Dependency] private readonly IEntityManager _entityManager = default!;
public string Command => "runrandomaspect";
public string Description => "Запускает случайный аспект.";
public string Help => "runrandomaspect";
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var aspectManager = _entityManager.System<AspectManager>();
var result = aspectManager.RunRandomAspect();
shell.WriteLine(result);
}
}

View File

@@ -1,3 +1,4 @@
using System.Linq;
using Content.Server.GameTicking;
using Content.Server._White.AspectsSystem.Base;
using Content.Shared.GameTicking;
@@ -193,6 +194,13 @@ namespace Content.Server._White.AspectsSystem.Managers
return aspectIds;
}
public Dictionary<EntityPrototype, AspectComponent> GetAspectsPrototypesId()
{
var availableAspects = AllAspects();
return availableAspects;
}
/// <summary>
/// Runs the specified aspect and adds it as a game rule.
/// </summary>

View File

@@ -1,6 +1,7 @@
using Content.Server.Humanoid;
using Content.Shared._White.Wizard.Appearance;
using Content.Shared.Dataset;
using Content.Shared.Humanoid.Prototypes;
using Content.Shared.Preferences;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
@@ -22,8 +23,41 @@ public sealed class WizardAppearanceSystem : EntitySystem
private void OnInit(EntityUid wizard, WizardAppearanceComponent appearance, ComponentInit _)
{
var random = IoCManager.Resolve<IRobustRandom>();
var profile = HumanoidCharacterProfile.RandomWithSpecies().WithAge(random.Next(appearance.MinAge, appearance.MaxAge));
Wizardify(wizard, appearance);
}
public void Wizardify(EntityUid wizard, WizardAppearanceComponent appearance)
{
var profile = GetWizardProfile(appearance);
_humanoid.LoadProfile(wizard, profile);
_metaData.SetEntityName(wizard, GetRandom(appearance.Name, string.Empty));
}
public string GetWizardName(WizardAppearanceComponent appearance)
{
return GetRandom(appearance.Name, string.Empty);
}
public EntityUid GetWizardEntity(WizardAppearanceComponent appearance)
{
var profile = GetWizardProfile(appearance);
if (!_prototypeManager.TryIndex(profile.Species, out SpeciesPrototype? species))
return EntityUid.Invalid;
var entity = Spawn(species.Prototype);
_humanoid.LoadProfile(entity, profile);
_metaData.SetEntityName(entity, GetWizardName(appearance));
return entity;
}
public HumanoidCharacterProfile GetWizardProfile(WizardAppearanceComponent appearance)
{
var profile = HumanoidCharacterProfile.RandomWithSpecies().WithAge(_random.Next(appearance.MinAge, appearance.MaxAge));
var color = Color.FromHex(GetRandom(appearance.Color, "#B5B8B1"));
var hair = GetRandom(appearance.Hair, "HumanHairAfricanPigtails");
@@ -37,9 +71,7 @@ public sealed class WizardAppearanceSystem : EntitySystem
.Appearance.WithHairColor(color))
.Appearance.WithFacialHairColor(color));
_humanoid.LoadProfile(wizard, profile);
_metaData.SetEntityName(wizard, GetRandom(appearance.Name, string.Empty));
return profile;
}
private string GetRandom(string list, string ifNull)

View File

@@ -4,9 +4,10 @@ using Content.Server.Mind;
using Content.Server.RoundEnd;
using Content.Shared.Mobs;
using System.Linq;
using Content.Server._White.Wizard.Appearance;
using Content.Server.Objectives;
using Content.Server.StationEvents.Components;
using Content.Shared._White.Mood;
using Content.Shared._White.Wizard.Appearance;
using Content.Shared.Mind;
using Content.Shared.Objectives.Components;
@@ -20,12 +21,16 @@ public sealed class WizardRuleSystem : GameRuleSystem<WizardRuleComponent>
[Dependency] private readonly MindSystem _mind = default!;
[Dependency] private readonly RoundEndSystem _roundEndSystem = default!;
[Dependency] private readonly ObjectivesSystem _objectives = default!;
[Dependency] private readonly WizardAppearanceSystem _wizardAppearance = default!;
private const string WizardObjective = "WizardSurviveObjective";
/// <inheritdoc/>
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<WizardRuleComponent, AntagSelectEntityEvent>(OnAntagSelectEntity);
SubscribeLocalEvent<WizardRuleComponent, AfterAntagEntitySelectedEvent>(AfterEntitySelected);
SubscribeLocalEvent<WizardComponent, MobStateChangedEvent>(OnMobStateChanged);
@@ -46,7 +51,7 @@ public sealed class WizardRuleSystem : GameRuleSystem<WizardRuleComponent>
private void GiveObjectives(EntityUid mindId, MindComponent mind, WizardRuleComponent wizardRule)
{
_mind.TryAddObjective(mindId, mind, "WizardSurviveObjective");
_mind.TryAddObjective(mindId, mind, WizardObjective);
var difficulty = 0f;
for (var pick = 0; pick < 6 && 8 > difficulty; pick++)
@@ -66,6 +71,24 @@ public sealed class WizardRuleSystem : GameRuleSystem<WizardRuleComponent>
MakeWizard(args.EntityUid, ent);
}
private void OnAntagSelectEntity(Entity<WizardRuleComponent> ent, ref AntagSelectEntityEvent args)
{
if (args.Handled)
return;
if (!args.Entity.HasValue)
return;
var wizardAppearanceComponent = EnsureComp<WizardAppearanceComponent>(args.Entity.Value);
// TODO: Пофиксить, что игрун сохраняет свой прототип вместе с расой и остаются абилки расы
var entity = _wizardAppearance.GetWizardEntity(wizardAppearanceComponent);
if (entity != EntityUid.Invalid)
args.Entity = entity;
}
private void MakeWizard(EntityUid wizard, WizardRuleComponent component, bool giveObjectives = true)
{
if (!_mind.TryGetMind(wizard, out var mindId, out var mind))