Tweaks: разные мелкие исправления и корректировки (#22)

* add: система улучшения зрения для слепых

* tweak: повышен урон дробовиков, повышен разброс

* tweak: скорость снарядов лазеров увеличена вдвое

* fix: фикс отображение веревки крюка-кошки

* fix: исправлено отображение воспоминаний

* tweak: перевод геймпресета революции

* fix: фикс отображения цели и рефактор правила культа

* add: Теперь помповые ружья нужно перезаряжать вручную

* tweak: повышен урон других снарядов дробовиков

* tweak: вещмешок синдиката больше не замедляет

* fix: исправлено отображение слота хранилища костюма в инвентаре
This commit is contained in:
Remuchi
2024-02-03 17:49:33 +07:00
committed by GitHub
parent 66e628e476
commit 3cfa1890b0
35 changed files with 432 additions and 424 deletions

View File

@@ -20,7 +20,7 @@ public sealed class CharacterInfoSystem : EntitySystem
public void RequestCharacterInfo() public void RequestCharacterInfo()
{ {
var entity = _players.LocalPlayer?.ControlledEntity; var entity = _players.LocalSession?.AttachedEntity;
if (entity == null) if (entity == null)
{ {
return; return;

View File

@@ -1,12 +1,8 @@
using Content.Client.Movement.Systems;
using Robust.Client.Graphics; using Robust.Client.Graphics;
using Robust.Client.Player; using Robust.Client.Player;
using Robust.Shared.Enums; using Robust.Shared.Enums;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Content.Shared.Eye.Blinding;
using Content.Shared.Eye.Blinding.Components; using Content.Shared.Eye.Blinding.Components;
using Content.Shared.Movement.Components;
using Content.Shared.Movement.Systems;
namespace Content.Client.Eye.Blinding namespace Content.Client.Eye.Blinding
{ {
@@ -18,7 +14,9 @@ namespace Content.Client.Eye.Blinding
[Dependency] private readonly ILightManager _lightManager = default!; [Dependency] private readonly ILightManager _lightManager = default!;
public override bool RequestScreenTexture => true; public override bool RequestScreenTexture => true;
public override OverlaySpace Space => OverlaySpace.WorldSpace; public override OverlaySpace Space => OverlaySpace.WorldSpace;
private readonly ShaderInstance _greyscaleShader; private readonly ShaderInstance _greyscaleShader;
private readonly ShaderInstance _circleMaskShader; private readonly ShaderInstance _circleMaskShader;
@@ -30,6 +28,7 @@ namespace Content.Client.Eye.Blinding
_greyscaleShader = _prototypeManager.Index<ShaderPrototype>("GreyscaleFullscreen").InstanceUnique(); _greyscaleShader = _prototypeManager.Index<ShaderPrototype>("GreyscaleFullscreen").InstanceUnique();
_circleMaskShader = _prototypeManager.Index<ShaderPrototype>("CircleMask").InstanceUnique(); _circleMaskShader = _prototypeManager.Index<ShaderPrototype>("CircleMask").InstanceUnique();
} }
protected override bool BeforeDraw(in OverlayDrawArgs args) protected override bool BeforeDraw(in OverlayDrawArgs args)
{ {
if (!_entityManager.TryGetComponent(_playerManager.LocalSession?.AttachedEntity, out EyeComponent? eyeComp)) if (!_entityManager.TryGetComponent(_playerManager.LocalSession?.AttachedEntity, out EyeComponent? eyeComp))
@@ -50,17 +49,15 @@ namespace Content.Client.Eye.Blinding
var blind = _blindableComponent.IsBlind; var blind = _blindableComponent.IsBlind;
if (!blind && _blindableComponent.LightSetup) // Turn FOV back on if we can see again if (blind || !_blindableComponent.LightSetup) // Turn FOV back on if we can see again
{ return blind;
_lightManager.Enabled = true; _lightManager.Enabled = true;
_blindableComponent.LightSetup = false; _blindableComponent.LightSetup = false;
_blindableComponent.GraceFrame = true; _blindableComponent.GraceFrame = true;
return true; return true;
} }
return blind;
}
protected override void Draw(in OverlayDrawArgs args) protected override void Draw(in OverlayDrawArgs args)
{ {
if (ScreenTexture == null) if (ScreenTexture == null)
@@ -75,7 +72,8 @@ namespace Content.Client.Eye.Blinding
{ {
_blindableComponent.LightSetup = true; // Ok we touched the lights _blindableComponent.LightSetup = true; // Ok we touched the lights
_lightManager.Enabled = false; _lightManager.Enabled = false;
} else }
else
{ {
_blindableComponent.GraceFrame = false; _blindableComponent.GraceFrame = false;
} }

View File

@@ -10,8 +10,7 @@ public sealed class BlindingSystem : EntitySystem
{ {
[Dependency] private readonly IPlayerManager _player = default!; [Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IOverlayManager _overlayMan = default!; [Dependency] private readonly IOverlayManager _overlayMan = default!;
[Dependency] ILightManager _lightManager = default!; [Dependency] private readonly ILightManager _lightManager = default!;
private BlindOverlay _overlay = default!; private BlindOverlay _overlay = default!;
@@ -27,7 +26,7 @@ public sealed class BlindingSystem : EntitySystem
SubscribeNetworkEvent<RoundRestartCleanupEvent>(RoundRestartCleanup); SubscribeNetworkEvent<RoundRestartCleanupEvent>(RoundRestartCleanup);
_overlay = new(); _overlay = new BlindOverlay();
} }
private void OnPlayerAttached(EntityUid uid, BlindableComponent component, LocalPlayerAttachedEvent args) private void OnPlayerAttached(EntityUid uid, BlindableComponent component, LocalPlayerAttachedEvent args)
@@ -43,13 +42,13 @@ public sealed class BlindingSystem : EntitySystem
private void OnBlindInit(EntityUid uid, BlindableComponent component, ComponentInit args) private void OnBlindInit(EntityUid uid, BlindableComponent component, ComponentInit args)
{ {
if (_player.LocalPlayer?.ControlledEntity == uid) if (_player.LocalSession?.AttachedEntity == uid)
_overlayMan.AddOverlay(_overlay); _overlayMan.AddOverlay(_overlay);
} }
private void OnBlindShutdown(EntityUid uid, BlindableComponent component, ComponentShutdown args) private void OnBlindShutdown(EntityUid uid, BlindableComponent component, ComponentShutdown args)
{ {
if (_player.LocalPlayer?.ControlledEntity == uid) if (_player.LocalSession?.AttachedEntity == uid)
{ {
_overlayMan.RemoveOverlay(_overlay); _overlayMan.RemoveOverlay(_overlay);
} }

View File

@@ -21,7 +21,7 @@ public sealed class BlurryVisionSystem : EntitySystem
SubscribeLocalEvent<BlurryVisionComponent, LocalPlayerAttachedEvent>(OnPlayerAttached); SubscribeLocalEvent<BlurryVisionComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<BlurryVisionComponent, LocalPlayerDetachedEvent>(OnPlayerDetached); SubscribeLocalEvent<BlurryVisionComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
_overlay = new(); _overlay = new BlurryVisionOverlay();
} }
private void OnPlayerAttached(EntityUid uid, BlurryVisionComponent component, LocalPlayerAttachedEvent args) private void OnPlayerAttached(EntityUid uid, BlurryVisionComponent component, LocalPlayerAttachedEvent args)
@@ -36,13 +36,13 @@ public sealed class BlurryVisionSystem : EntitySystem
private void OnBlurryInit(EntityUid uid, BlurryVisionComponent component, ComponentInit args) private void OnBlurryInit(EntityUid uid, BlurryVisionComponent component, ComponentInit args)
{ {
if (_player.LocalPlayer?.ControlledEntity == uid) if (_player.LocalSession?.AttachedEntity == uid)
_overlayMan.AddOverlay(_overlay); _overlayMan.AddOverlay(_overlay);
} }
private void OnBlurryShutdown(EntityUid uid, BlurryVisionComponent component, ComponentShutdown args) private void OnBlurryShutdown(EntityUid uid, BlurryVisionComponent component, ComponentShutdown args)
{ {
if (_player.LocalPlayer?.ControlledEntity == uid) if (_player.LocalSession?.AttachedEntity == uid)
{ {
_overlayMan.RemoveOverlay(_overlay); _overlayMan.RemoveOverlay(_overlay);
} }

View File

@@ -112,7 +112,6 @@ public sealed class CharacterUIController : UIController, IOnStateEntered<Gamepl
_window.SubText.Text = job; _window.SubText.Text = job;
_window.Objectives.RemoveAllChildren(); _window.Objectives.RemoveAllChildren();
_window.Memories.RemoveAllChildren(); _window.Memories.RemoveAllChildren();
_window.ObjectivesLabel.Visible = objectives.Any();
foreach (var (groupId, conditions) in objectives) foreach (var (groupId, conditions) in objectives)
{ {
@@ -183,7 +182,8 @@ public sealed class CharacterUIController : UIController, IOnStateEntered<Gamepl
_window.Objectives.AddChild(control); _window.Objectives.AddChild(control);
} }
_window.RolePlaceholder.Visible = briefing == null && !controls.Any() && !objectives.Any(); _window.RolePlaceholder.Visible = briefing == null && controls.Count == 0 && objectives.Count == 0;
_window.MemoriesPlaceholder.Visible = memories.Count == 0;
} }
private void CharacterDetached(EntityUid uid) private void CharacterDetached(EntityUid uid)

View File

@@ -8,22 +8,25 @@
<ScrollContainer> <ScrollContainer>
<BoxContainer Orientation="Vertical"> <BoxContainer Orientation="Vertical">
<BoxContainer Orientation="Horizontal"> <BoxContainer Orientation="Horizontal">
<SpriteView OverrideDirection="South" Scale="2 2" Name="SpriteView" Access="Public" SetSize="64 64"/> <SpriteView OverrideDirection="South" Scale="2 2" Name="SpriteView" Access="Public" SetSize="64 64" />
<BoxContainer Orientation="Vertical" VerticalAlignment="Top"> <BoxContainer Orientation="Vertical" VerticalAlignment="Top">
<Label Name="NameLabel" Access="Public"/> <Label Name="NameLabel" Access="Public" />
<Label Name="SubText" VerticalAlignment="Top" StyleClasses="LabelSubText" Access="Public"/> <Label Name="SubText" VerticalAlignment="Top" StyleClasses="LabelSubText" Access="Public" />
</BoxContainer> </BoxContainer>
</BoxContainer> </BoxContainer>
<!-- WD EDIT --> <!-- WD EDIT -->
<Label Text="{Loc 'character-info-memories-label'}" HorizontalAlignment="Center"/> <Label Text="{Loc 'character-info-memories-label'}" HorizontalAlignment="Center" />
<BoxContainer Orientation="Vertical" Name="Memories" Access="Public"/> <BoxContainer Orientation="Vertical" Name="Memories" Access="Public" />
<cc:Placeholder PlaceholderText="{Loc 'character-info-memories-placeholder-text'}"/> <cc:Placeholder Name="MemoriesPlaceholder" Access="Public"
PlaceholderText="{Loc 'character-info-memories-placeholder-text'}" />
<!-- WD EDIT END --> <!-- WD EDIT END -->
<Label Name="ObjectivesLabel" Access="Public" Text="{Loc 'character-info-objectives-label'}" HorizontalAlignment="Center"/> <Label Name="ObjectivesLabel" Access="Public" Text="{Loc 'character-info-objectives-label'}"
<BoxContainer Orientation="Vertical" Name="Objectives" Access="Public"/> HorizontalAlignment="Center" />
<cc:Placeholder Name="RolePlaceholder" Access="Public" PlaceholderText="{Loc 'character-info-roles-antagonist-text'}"/> <BoxContainer Orientation="Vertical" Name="Objectives" Access="Public" />
<cc:Placeholder Name="RolePlaceholder" Access="Public"
PlaceholderText="{Loc 'character-info-roles-antagonist-text'}" />
</BoxContainer> </BoxContainer>
</ScrollContainer> </ScrollContainer>
</windows:CharacterWindow> </windows:CharacterWindow>

View File

@@ -12,7 +12,10 @@ public sealed partial class GunSystem
SubscribeLocalEvent<BallisticAmmoProviderComponent, UpdateAmmoCounterEvent>(OnBallisticAmmoCount); SubscribeLocalEvent<BallisticAmmoProviderComponent, UpdateAmmoCounterEvent>(OnBallisticAmmoCount);
} }
private void OnBallisticAmmoCount(EntityUid uid, BallisticAmmoProviderComponent component, UpdateAmmoCounterEvent args) private void OnBallisticAmmoCount(
EntityUid uid,
BallisticAmmoProviderComponent component,
UpdateAmmoCounterEvent args)
{ {
if (args.Control is DefaultStatusControl control) if (args.Control is DefaultStatusControl control)
{ {
@@ -25,6 +28,9 @@ public sealed partial class GunSystem
if (!Timing.IsFirstTimePredicted) if (!Timing.IsFirstTimePredicted)
return; return;
if (!component.IsCycled)
return;
EntityUid? ent = null; EntityUid? ent = null;
// TODO: Combine with TakeAmmo // TODO: Combine with TakeAmmo
@@ -48,5 +54,6 @@ public sealed partial class GunSystem
var cycledEvent = new GunCycledEvent(); var cycledEvent = new GunCycledEvent();
RaiseLocalEvent(uid, ref cycledEvent); RaiseLocalEvent(uid, ref cycledEvent);
} }
} }

View File

@@ -172,14 +172,13 @@ public sealed partial class AdminVerbSystem
{ {
Text = "Сделать культистом.", Text = "Сделать культистом.",
Category = VerbCategory.Antag, Category = VerbCategory.Antag,
Icon = new SpriteSpecifier.Rsi(new("/Textures/White/Cult/interface.rsi"), "icon"), Icon = new SpriteSpecifier.Rsi(new ResPath("/Textures/White/Cult/interface.rsi"), "icon"),
Act = () => Act = () =>
{ {
if (!_minds.TryGetSession(targetMindComp.Mind, out var session)) if (!_minds.TryGetSession(targetMindComp.Mind, out var session))
return; return;
var playerSession = session; _cultRule.MakeCultist(session);
_cultRule.MakeCultist(playerSession!);
} }
}; };
args.Verbs.Add(cultist); args.Verbs.Add(cultist);

View File

@@ -1,8 +0,0 @@
using Content.Server.Objectives.Systems;
namespace Content.Server.Objectives.Components;
[RegisterComponent, Access(typeof(KillCultistTargetConditionSystem))]
public sealed partial class KillCultistTargetConditionComponent : Component
{
}

View File

@@ -0,0 +1,9 @@
using Content.Server.Objectives.Systems;
namespace Content.Server.Objectives.Components;
[RegisterComponent, Access(typeof(KillPersonConditionSystem))]
public sealed partial class PickCultTargetComponent : Component
{
}

View File

@@ -1,87 +0,0 @@
/*using System.Diagnostics;
using System.Linq;
using Content.Server.Mind;
using Content.Server._White.Cult.GameRule;
using Content.Shared.Mind;
using Content.Shared.Roles.Jobs;
using Robust.Shared.Utility;
namespace Content.Server.Objectives.Conditions;
[DataDefinition]
public sealed partial class KillCultistTarget : IObjectiveCondition
{
private IEntityManager EntityManager => IoCManager.Resolve<IEntityManager>();
protected EntityUid? TargetMindId;
protected MindComponent? TargetMind => EntityManager.GetComponentOrNull<MindComponent>(TargetMindId);
protected SharedJobSystem Jobs => EntityManager.System<SharedJobSystem>();
public IObjectiveCondition GetAssigned(EntityUid mindId, MindComponent mind)
{
var cultistRule = EntityManager.EntityQuery<CultRuleComponent>().FirstOrDefault();
Debug.Assert(cultistRule != null, nameof(cultistRule) + " != null");
var target = cultistRule.CultTarget;
return new KillCultistTarget()
{
TargetMindId = target
};
}
public string Title
{
get
{
var targetName = string.Empty;
var jobName = Jobs.MindTryGetJobName(TargetMindId) ?? "Unknown";
if (TargetMindId == null)
return Loc.GetString("objective-condition-kill-person-title", ("targetName", targetName), ("job", jobName));
if (TargetMind?.OwnedEntity is {Valid: true} owned)
targetName = EntityManager.GetComponent<MetaDataComponent>(owned).EntityName;
return Loc.GetString("objective-condition-kill-person-title", ("targetName", targetName), ("job", jobName));
}
}
public string Description => Loc.GetString("objective-condition-kill-person-description");
public SpriteSpecifier Icon => new SpriteSpecifier.Rsi(new ("Objects/Weapons/Guns/Pistols/viper.rsi"), "icon");
public float Progress
{
get
{
var entityManager = IoCManager.Resolve<EntityManager>();
var mindSystem = entityManager.System<MindSystem>();
return TargetMindId == null || TargetMind == null || mindSystem.IsCharacterDeadIc(TargetMind!) ? 1f : 0f;
}
}
public float Difficulty => 2f;
public bool Equals(IObjectiveCondition? other)
{
return other is KillCultistTarget kpc && Equals(TargetMindId, kpc.TargetMindId);
}
public override bool Equals(object? obj)
{
if (ReferenceEquals(null, obj))
return false;
if (ReferenceEquals(this, obj))
return true;
return obj.GetType() == GetType() && Equals((KillCultistTarget) obj);
}
public override int GetHashCode()
{
return TargetMindId?.GetHashCode() ?? 0;
}
}*/

View File

@@ -1,61 +0,0 @@
using System.Diagnostics;
using System.Linq;
using Content.Server.Objectives.Components;
using Content.Server._White.Cult.GameRule;
using Content.Shared.Mind;
using Content.Shared.Objectives.Components;
namespace Content.Server.Objectives.Systems;
public sealed class KillCultistTargetConditionSystem : EntitySystem
{
[Dependency] private readonly SharedMindSystem _mind = default!;
[Dependency] private readonly TargetObjectiveSystem _target = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<KillCultistTargetConditionComponent, ObjectiveGetProgressEvent>(OnGetProgress);
SubscribeLocalEvent<KillCultistTargetConditionComponent, ObjectiveAssignedEvent>(OnPersonAssigned);
}
private void OnGetProgress(EntityUid uid, KillCultistTargetConditionComponent comp, ref ObjectiveGetProgressEvent args)
{
if (!_target.GetTarget(uid, out var target))
return;
args.Progress = GetProgress(target.Value);
}
private void OnPersonAssigned(EntityUid uid, KillCultistTargetConditionComponent component, ref ObjectiveAssignedEvent args)
{
if (!TryComp<TargetObjectiveComponent>(uid, out var target))
{
args.Cancelled = true;
return;
}
// target already assigned
if (target.Target != null)
return;
var cultistRule = EntityManager.EntityQuery<CultRuleComponent>().FirstOrDefault();
Debug.Assert(cultistRule != null, nameof(cultistRule) + " != null");
var cultTarget = cultistRule.CultTarget;
if (cultTarget != null)
_target.SetTarget(uid, cultTarget.Value, target);
}
private float GetProgress(EntityUid target)
{
// deleted or gibbed or something, counts as dead
if (!TryComp<MindComponent>(target, out var mind) || mind.OwnedEntity == null)
return 1f;
// dead is success
return _mind.IsCharacterDeadIc(mind) ? 1f : 0f;
}
}

View File

@@ -1,3 +1,5 @@
using System.Linq;
using Content.Server._White.Cult.GameRule;
using Content.Server.Objectives.Components; using Content.Server.Objectives.Components;
using Content.Server.Shuttles.Systems; using Content.Server.Shuttles.Systems;
using Content.Shared.CCVar; using Content.Shared.CCVar;
@@ -30,6 +32,8 @@ public sealed class KillPersonConditionSystem : EntitySystem
SubscribeLocalEvent<PickRandomPersonComponent, ObjectiveAssignedEvent>(OnPersonAssigned); SubscribeLocalEvent<PickRandomPersonComponent, ObjectiveAssignedEvent>(OnPersonAssigned);
SubscribeLocalEvent<PickRandomHeadComponent, ObjectiveAssignedEvent>(OnHeadAssigned); SubscribeLocalEvent<PickRandomHeadComponent, ObjectiveAssignedEvent>(OnHeadAssigned);
SubscribeLocalEvent<PickCultTargetComponent, ObjectiveAssignedEvent>(OnCultTargetAssigned);
} }
private void OnGetProgress(EntityUid uid, KillPersonConditionComponent comp, ref ObjectiveGetProgressEvent args) private void OnGetProgress(EntityUid uid, KillPersonConditionComponent comp, ref ObjectiveGetProgressEvent args)
@@ -99,6 +103,28 @@ public sealed class KillPersonConditionSystem : EntitySystem
_target.SetTarget(uid, _random.Pick(allHeads), target); _target.SetTarget(uid, _random.Pick(allHeads), target);
} }
private void OnCultTargetAssigned(Entity<PickCultTargetComponent> ent, ref ObjectiveAssignedEvent args)
{
// invalid prototype
if (!TryComp<TargetObjectiveComponent>(ent.Owner, out var target))
{
args.Cancelled = true;
return;
}
// target already assigned
if (target.Target != null)
return;
var cultistRule = EntityManager.EntityQuery<CultRuleComponent>().FirstOrDefault();
if (cultistRule?.CultTarget is null)
{
return;
}
_target.SetTarget(ent.Owner, cultistRule.CultTarget.Value);
}
private float GetProgress(EntityUid target, bool requireDead) private float GetProgress(EntityUid target, bool requireDead)
{ {
// deleted or gibbed or something, counts as dead // deleted or gibbed or something, counts as dead

View File

@@ -12,6 +12,9 @@ public sealed partial class GunSystem
protected override void Cycle(EntityUid uid, BallisticAmmoProviderComponent component, MapCoordinates coordinates) protected override void Cycle(EntityUid uid, BallisticAmmoProviderComponent component, MapCoordinates coordinates)
{ {
if (!component.IsCycled)
return;
EntityUid? ent = null; EntityUid? ent = null;
// TODO: Combine with TakeAmmo // TODO: Combine with TakeAmmo

View File

@@ -54,11 +54,11 @@ public sealed partial class CultRuleComponent : Component
/// <summary> /// <summary>
/// Players who played as an cultist at some point in the round. /// Players who played as an cultist at some point in the round.
/// </summary> /// </summary>
public Dictionary<string, string> CultistsList = new(); public Dictionary<string, string> CultistsCache = new();
public EntityUid? CultTarget; public EntityUid? CultTarget;
public List<CultistComponent> Cultists = new(); public List<CultistComponent> CurrentCultists = new();
public List<ConstructComponent> Constructs = new(); public List<ConstructComponent> Constructs = new();

View File

@@ -2,9 +2,7 @@
using Content.Server.Chat.Managers; using Content.Server.Chat.Managers;
using Content.Server.GameTicking; using Content.Server.GameTicking;
using Content.Server.GameTicking.Rules; using Content.Server.GameTicking.Rules;
using Content.Server.GameTicking.Rules.Components;
using Content.Server.NPC.Systems; using Content.Server.NPC.Systems;
using Content.Server.Roles;
using Content.Server.Roles.Jobs; using Content.Server.Roles.Jobs;
using Content.Server.RoundEnd; using Content.Server.RoundEnd;
using Content.Server.Shuttles.Components; using Content.Server.Shuttles.Components;
@@ -16,23 +14,15 @@ using Content.Shared.Mind.Components;
using Content.Shared.Mobs; using Content.Shared.Mobs;
using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems; using Content.Shared.Mobs.Systems;
using Content.Shared.Objectives;
using Content.Shared.Players;
using Content.Shared.Preferences; using Content.Shared.Preferences;
using Content.Shared.Roles; using Content.Shared.Roles;
using Content.Shared._White.Cult;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.Audio;
using Robust.Shared.Configuration; using Robust.Shared.Configuration;
using Robust.Shared.Player; using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Random; using Robust.Shared.Random;
using Robust.Shared.Utility;
using Content.Shared._White; using Content.Shared._White;
using Content.Shared._White.Cult.Components;
using Content.Shared.Mind; using Content.Shared.Mind;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
using CultistComponent = Content.Shared._White.Cult.Components.CultistComponent;
namespace Content.Server._White.Cult.GameRule; namespace Content.Server._White.Cult.GameRule;
@@ -43,7 +33,6 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
[Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly InventorySystem _inventorySystem = default!; [Dependency] private readonly InventorySystem _inventorySystem = default!;
[Dependency] private readonly StorageSystem _storageSystem = default!; [Dependency] private readonly StorageSystem _storageSystem = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly NpcFactionSystem _factionSystem = default!; [Dependency] private readonly NpcFactionSystem _factionSystem = default!;
[Dependency] private readonly MobStateSystem _mobStateSystem = default!; [Dependency] private readonly MobStateSystem _mobStateSystem = default!;
[Dependency] private readonly SharedAudioSystem _audioSystem = default!; [Dependency] private readonly SharedAudioSystem _audioSystem = default!;
@@ -86,27 +75,26 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
public MindComponent? GetTarget() public MindComponent? GetTarget()
{ {
var querry = EntityQueryEnumerator<CultRuleComponent, GameRuleComponent>(); var cultistsRule = EntityQuery<CultRuleComponent>().FirstOrDefault();
while (querry.MoveNext(out _, out var cultRuleComponent, out _)) if (cultistsRule?.CultTarget == null || !TryComp<MindComponent>(cultistsRule.CultTarget.Value, out var mind))
{
if (cultRuleComponent.CultTarget.HasValue && TryComp<MindComponent>(cultRuleComponent.CultTarget.Value, out var mind))
{ {
return null;
}
return mind; return mind;
} }
}
return null!;
}
public bool CanSummonNarsie() public bool CanSummonNarsie()
{ {
var querry = EntityQueryEnumerator<CultRuleComponent, GameRuleComponent>(); var cultistsRule = EntityQuery<CultRuleComponent>().FirstOrDefault();
if (cultistsRule is null)
while (querry.MoveNext(out _, out var cultRuleComponent, out _))
{ {
var cultistsAmount = cultRuleComponent.Cultists.Count; return false;
var constructsAmount = cultRuleComponent.Constructs.Count; }
var cultistsAmount = cultistsRule.CurrentCultists.Count;
var constructsAmount = cultistsRule.Constructs.Count;
var enoughCultists = cultistsAmount + constructsAmount > 10; var enoughCultists = cultistsAmount + constructsAmount > 10;
if (!enoughCultists) if (!enoughCultists)
@@ -117,22 +105,20 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
var target = GetTarget(); var target = GetTarget();
var targetKilled = target == null || _mindSystem.IsCharacterDeadIc(target); var targetKilled = target == null || _mindSystem.IsCharacterDeadIc(target);
if (targetKilled) return targetKilled;
return true;
}
return false;
} }
private void CheckRoundShouldEnd() private void CheckRoundShouldEnd()
{ {
var querry = EntityQueryEnumerator<CultRuleComponent, GameRuleComponent>(); var cultistsRule = EntityQuery<CultRuleComponent>().FirstOrDefault();
var aliveCultistsCount = 0; if (cultistsRule is null)
while (querry.MoveNext(out _, out var cultRuleComponent, out _))
{ {
var cultists = 0; return;
foreach (var cultistComponent in cultRuleComponent.Cultists) }
var aliveCultists = 0;
foreach (var cultistComponent in cultistsRule.CurrentCultists)
{ {
var owner = cultistComponent.Owner; var owner = cultistComponent.Owner;
if (!TryComp<MobStateComponent>(owner, out var mobState)) if (!TryComp<MobStateComponent>(owner, out var mobState))
@@ -140,30 +126,24 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
if (_mobStateSystem.IsAlive(owner, mobState)) if (_mobStateSystem.IsAlive(owner, mobState))
{ {
cultists++; aliveCultists++;
} }
} }
if (cultists == 0) if (aliveCultists != 0)
cultRuleComponent.WinCondition = CultWinCondition.CultFailure; return;
aliveCultistsCount += cultists; cultistsRule.WinCondition = CultWinCondition.CultFailure;
}
if (aliveCultistsCount == 0)
{
_roundEndSystem.EndRound(); _roundEndSystem.EndRound();
} }
}
private void OnCultistComponentInit(EntityUid uid, CultistComponent component, ComponentInit args) private void OnCultistComponentInit(EntityUid uid, CultistComponent component, ComponentInit args)
{ {
var query = EntityQueryEnumerator<CultRuleComponent, GameRuleComponent>(); var cultistsRule = EntityQuery<CultRuleComponent>().FirstOrDefault();
if (cultistsRule is null)
while (query.MoveNext(out var ruleEnt, out var cultRuleComponent, out _))
{ {
if (!GameTicker.IsGameRuleAdded(ruleEnt)) return;
continue; }
if (!TryComp<MindContainerComponent>(uid, out var mindComponent)) if (!TryComp<MindContainerComponent>(uid, out var mindComponent))
return; return;
@@ -171,62 +151,51 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
if (!mindComponent.HasMind) if (!mindComponent.HasMind)
return; return;
cultRuleComponent.Cultists.Add(component); cultistsRule.CurrentCultists.Add(component);
if (TryComp<ActorComponent>(component.Owner, out var actor)) if (TryComp<ActorComponent>(uid, out var actor))
{ {
cultRuleComponent.CultistsList.Add(MetaData(component.Owner).EntityName, actor.PlayerSession.Name); cultistsRule.CultistsCache.Add(MetaData(uid).EntityName, actor.PlayerSession.Name);
} }
var traitorRole = new TraitorRoleComponent() UpdateCultistsAppearance(cultistsRule);
{
PrototypeId = cultRuleComponent.CultistRolePrototype
};
_roleSystem.MindAddRole(mindComponent.Mind.Value, traitorRole);
UpdateCultistsAppearance(cultRuleComponent);
}
} }
private void OnCultistComponentRemoved(EntityUid uid, CultistComponent component, ComponentRemove args) private void OnCultistComponentRemoved(EntityUid uid, CultistComponent component, ComponentRemove args)
{ {
var query = EntityQueryEnumerator<CultRuleComponent, GameRuleComponent>(); var cultistsRule = EntityQuery<CultRuleComponent>().FirstOrDefault();
if (cultistsRule is null)
while (query.MoveNext(out var ruleEnt, out var cultRuleComponent, out _))
{ {
if (!GameTicker.IsGameRuleAdded(ruleEnt)) return;
continue; }
cultRuleComponent.Cultists.Remove(component); cultistsRule.CurrentCultists.Remove(component);
RemoveCultistAppearance(component);
RemoveCultistAppearance(uid);
CheckRoundShouldEnd(); CheckRoundShouldEnd();
} }
}
private void RemoveCultistAppearance(CultistComponent component) private void RemoveCultistAppearance(EntityUid cultist)
{ {
if (TryComp<HumanoidAppearanceComponent>(component.Owner, out var appearanceComponent)) if (TryComp<HumanoidAppearanceComponent>(cultist, out var appearanceComponent))
{ {
//Потому что я так сказал //Потому что я так сказал
appearanceComponent.EyeColor = Color.White; appearanceComponent.EyeColor = Color.White;
Dirty(appearanceComponent); Dirty(cultist, appearanceComponent);
} }
RemComp<PentagramComponent>(component.Owner); RemComp<PentagramComponent>(cultist);
} }
private void UpdateCultistsAppearance(CultRuleComponent cultRuleComponent) private void UpdateCultistsAppearance(CultRuleComponent cultRuleComponent)
{ {
var cultistsCount = cultRuleComponent.Cultists.Count; var cultistsCount = cultRuleComponent.CurrentCultists.Count;
var constructsCount = cultRuleComponent.Constructs.Count; var constructsCount = cultRuleComponent.Constructs.Count;
var totalCultMembers = cultistsCount + constructsCount; var totalCultMembers = cultistsCount + constructsCount;
if (totalCultMembers < CultRuleComponent.ReadEyeThreshold) if (totalCultMembers < CultRuleComponent.ReadEyeThreshold)
return; return;
foreach (var cultistComponent in cultRuleComponent.Cultists) foreach (var cultistComponent in cultRuleComponent.CurrentCultists)
{ {
if (TryComp<HumanoidAppearanceComponent>(cultistComponent.Owner, out var appearanceComponent)) if (TryComp<HumanoidAppearanceComponent>(cultistComponent.Owner, out var appearanceComponent))
{ {
@@ -243,31 +212,31 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
private void OnRoundEndText(RoundEndTextAppendEvent ev) private void OnRoundEndText(RoundEndTextAppendEvent ev)
{ {
var querry = EntityQuery<CultRuleComponent>(); var cultistsRule = EntityQuery<CultRuleComponent>().FirstOrDefault();
if (cultistsRule is null)
foreach (var cultRuleComponent in querry)
{ {
var winText = Loc.GetString($"cult-cond-{cultRuleComponent.WinCondition.ToString().ToLower()}"); return;
}
var winText = Loc.GetString($"cult-cond-{cultistsRule.WinCondition.ToString().ToLower()}");
ev.AddLine(winText); ev.AddLine(winText);
ev.AddLine(Loc.GetString("cultists-list-start")); ev.AddLine(Loc.GetString("cultists-list-start"));
foreach (var (entityName, ckey) in cultRuleComponent.CultistsList) foreach (var (entityName, ckey) in cultistsRule.CultistsCache)
{ {
var lising = Loc.GetString("cultists-list-name", ("name", entityName), ("user", ckey)); var lising = Loc.GetString("cultists-list-name", ("name", entityName), ("user", ckey));
ev.AddLine(lising); ev.AddLine(lising);
} }
} }
}
private void OnStartAttempt(RoundStartAttemptEvent ev) private void OnStartAttempt(RoundStartAttemptEvent ev)
{ {
var query = EntityQueryEnumerator<CultRuleComponent, GameRuleComponent>(); var cultistsRule = EntityQuery<CultRuleComponent>().FirstOrDefault();
if (cultistsRule is null)
while (query.MoveNext(out var uid, out _, out var gameRule))
{ {
if (!GameTicker.IsGameRuleAdded(uid, gameRule)) return;
continue; }
var minPlayers = _cultGameRuleMinimapPlayers; var minPlayers = _cultGameRuleMinimapPlayers;
if (!ev.Forced && ev.Players.Length < minPlayers) if (!ev.Forced && ev.Players.Length < minPlayers)
@@ -276,45 +245,43 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
("readyPlayersCount", ev.Players.Length), ("minimumPlayers", minPlayers))); ("readyPlayersCount", ev.Players.Length), ("minimumPlayers", minPlayers)));
ev.Cancel(); ev.Cancel();
continue; return;
} }
if (ev.Players.Length == 0) if (ev.Players.Length != 0)
{ return;
_chatManager.DispatchServerAnnouncement(Loc.GetString("traitor-no-one-ready")); _chatManager.DispatchServerAnnouncement(Loc.GetString("traitor-no-one-ready"));
ev.Cancel(); ev.Cancel();
} }
}
}
private void OnPlayersSpawned(RulePlayerJobsAssignedEvent ev) private void OnPlayersSpawned(RulePlayerJobsAssignedEvent ev)
{ {
var query = EntityQueryEnumerator<CultRuleComponent, GameRuleComponent>(); var cultistsRule = EntityQuery<CultRuleComponent>().FirstOrDefault();
while (query.MoveNext(out var uid, out var cultRule, out var gameRule)) if (cultistsRule is null)
{ {
if (!GameTicker.IsGameRuleAdded(uid, gameRule)) return;
continue; }
foreach (var player in ev.Players) foreach (var player in ev.Players)
{ {
if (!ev.Profiles.ContainsKey(player.UserId)) if (!ev.Profiles.ContainsKey(player.UserId))
continue; continue;
cultRule.StarCandidates[player] = ev.Profiles[player.UserId]; cultistsRule.StarCandidates[player] = ev.Profiles[player.UserId];
} }
var potentialCultists = FindPotentialCultist(cultRule.StarCandidates); var potentialCultists = FindPotentialCultist(cultistsRule.StarCandidates);
var pickedCultist = PickCultists(potentialCultists); var pickedCultist = PickCultists(potentialCultists);
var potentialTargets = FindPotentialTargets(pickedCultist); var potentialTargets = FindPotentialTargets(pickedCultist);
cultRule.CultTarget = _random.PickAndTake(potentialTargets).Mind; cultistsRule.CultTarget = _random.PickAndTake(potentialTargets).Mind;
foreach (var pickerCultist in pickedCultist) foreach (var pickerCultist in pickedCultist)
{ {
MakeCultist(pickerCultist); MakeCultist(pickerCultist);
} }
} }
}
private List<MindContainerComponent> FindPotentialTargets(List<ICommonSession> exclude = null!) private List<MindContainerComponent> FindPotentialTargets(List<ICommonSession> exclude = null!)
{ {
@@ -340,7 +307,8 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
return potentialTargets; return potentialTargets;
} }
private List<ICommonSession> FindPotentialCultist(in Dictionary<ICommonSession, HumanoidCharacterProfile> candidates) private List<ICommonSession> FindPotentialCultist(
in Dictionary<ICommonSession, HumanoidCharacterProfile> candidates)
{ {
var list = new List<ICommonSession>(); var list = new List<ICommonSession>();
var pendingQuery = GetEntityQuery<PendingClockInComponent>(); var pendingQuery = GetEntityQuery<PendingClockInComponent>();
@@ -348,7 +316,8 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
foreach (var player in candidates.Keys) foreach (var player in candidates.Keys)
{ {
// Role prevents antag. // Role prevents antag.
if (!_jobSystem.CanBeAntag(player)) continue; if (!_jobSystem.CanBeAntag(player))
continue;
// Latejoin // Latejoin
if (player.AttachedEntity != null && pendingQuery.HasComponent(player.AttachedEntity.Value)) if (player.AttachedEntity != null && pendingQuery.HasComponent(player.AttachedEntity.Value))
@@ -428,35 +397,34 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
cultistRule = Comp<CultRuleComponent>(ruleEntity); cultistRule = Comp<CultRuleComponent>(ruleEntity);
} }
var mind = cultist.Data.ContentData()?.Mind; if (!_mindSystem.TryGetMind(cultist, out var mindId, out var mind))
if (mind == null)
{ {
_sawmill.Info("Failed getting mind for picked cultist."); Log.Info("Failed getting mind for picked thief.");
return false; return false;
} }
var playerEntity = cultist.AttachedEntity; if (mind.OwnedEntity is not { } playerEntity)
if (!playerEntity.HasValue)
{ {
_sawmill.Error("Mind picked for cultist did not have an attached entity."); Log.Error("Mind picked for cultist did not have an attached entity.");
return false; return false;
} }
var mindComponent = Comp<MindComponent>(mind.Value); var cultistComponent = new CultistRoleComponent
{
PrototypeId = cultistRule.CultistRolePrototype
};
DebugTools.AssertNotNull(playerEntity.Value); _roleSystem.MindAddRole(mindId, cultistComponent);
EnsureComp<CultistComponent>(playerEntity.Value); EnsureComp<CultistComponent>(playerEntity);
_factionSystem.RemoveFaction(playerEntity.Value, "NanoTrasen", false); _factionSystem.RemoveFaction(playerEntity, "NanoTrasen", false);
_factionSystem.AddFaction(playerEntity.Value, "Cultist"); _factionSystem.AddFaction(playerEntity, "Cultist");
if (_inventorySystem.TryGetSlotEntity(playerEntity.Value, "back", out var backPack)) if (_inventorySystem.TryGetSlotEntity(playerEntity, "back", out var backPack))
{ {
foreach (var itemPrototype in cultistRule.StartingItems) foreach (var itemPrototype in cultistRule.StartingItems)
{ {
var itemEntity = Spawn(itemPrototype, Transform(playerEntity.Value).Coordinates); var itemEntity = Spawn(itemPrototype, Transform(playerEntity).Coordinates);
if (backPack != null) if (backPack != null)
{ {
@@ -465,12 +433,14 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
} }
} }
_audioSystem.PlayGlobal(cultistRule.GreatingsSound, Filter.Empty().AddPlayer(cultist), false, // Notificate player about new role assignment
AudioParams.Default); if (_mindSystem.TryGetSession(mindId, out var session))
{
_audioSystem.PlayGlobal(cultistRule.GreatingsSound, session);
_chatManager.DispatchServerMessage(session, Loc.GetString("cult-role-greeting"));
}
_chatManager.DispatchServerMessage(cultist, Loc.GetString("cult-role-greeting")); _mindSystem.TryAddObjective(mindId, mind, "KillCultTargetObjective");
_mindSystem.TryAddObjective(mind.Value, mindComponent, "CultistKillObjective");
return true; return true;
} }
@@ -484,19 +454,19 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
_roundEndSystem.EndRound(); _roundEndSystem.EndRound();
var query = EntityQuery<MobStateComponent, MindContainerComponent, CultistComponent>().ToList(); var query = EntityQueryEnumerator<MobStateComponent, MindContainerComponent, CultistComponent>();
foreach (var (mobState, mindContainer, _) in query) while (query.MoveNext(out var uid, out _, out var mindContainer, out _))
{ {
if (!mindContainer.HasMind || mindContainer.Mind is null) if (!mindContainer.HasMind || mindContainer.Mind is null)
{ {
continue; continue;
} }
var reaper = Spawn(CultRuleComponent.ReaperPrototype, Transform(mobState.Owner).Coordinates); var reaper = Spawn(CultRuleComponent.ReaperPrototype, Transform(uid).Coordinates);
_mindSystem.TransferTo(mindContainer.Mind.Value, reaper); _mindSystem.TransferTo(mindContainer.Mind.Value, reaper);
_bodySystem.GibBody(mobState.Owner); _bodySystem.GibBody(uid);
} }
} }
} }

View File

@@ -67,6 +67,9 @@ public abstract class SharedGrapplingGunSystem : EntitySystem
visuals.Sprite = component.RopeSprite; visuals.Sprite = component.RopeSprite;
visuals.OffsetA = new Vector2(0f, 0.5f); visuals.OffsetA = new Vector2(0f, 0.5f);
visuals.Target = uid; visuals.Target = uid;
component.Joint = visuals.Target;
Dirty(shotUid.Value, visuals); Dirty(shotUid.Value, visuals);
} }

View File

@@ -44,6 +44,24 @@ public sealed partial class BallisticAmmoProviderComponent : Component
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public bool Cycleable = true; public bool Cycleable = true;
/// <summary>
/// Is the firearm currently cycled?
/// It cannot fire if is it not cycled.
/// Must be manually cycled if it is not cycled.
/// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField]
[AutoNetworkedField]
public bool? Cycled = true;
public bool IsCycled => Cycled is true or null;
/// <summary>
/// Automatically cycles the firearm after firing a round
/// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField]
[AutoNetworkedField]
public bool AutoCycle = true;
/// <summary> /// <summary>
/// Is it okay for this entity to directly transfer its valid ammunition into another provider? /// Is it okay for this entity to directly transfer its valid ammunition into another provider?
/// </summary> /// </summary>

View File

@@ -9,7 +9,7 @@ namespace Content.Shared.Weapons.Ranged.Components;
public sealed partial class GrapplingGunComponent : Component public sealed partial class GrapplingGunComponent : Component
{ {
[DataField("jointId"), AutoNetworkedField] [DataField("jointId"), AutoNetworkedField]
public string Joint = string.Empty; public EntityUid? Joint;
[DataField, AutoNetworkedField] [DataField, AutoNetworkedField]
public EntityUid? Projectile; public EntityUid? Projectile;

View File

@@ -206,6 +206,7 @@ public abstract partial class SharedGunSystem
var shots = GetBallisticShots(component); var shots = GetBallisticShots(component);
Cycle(uid, component, coordinates); Cycle(uid, component, coordinates);
component.Cycled = true;
var text = Loc.GetString(shots == 0 ? "gun-ballistic-cycled-empty" : "gun-ballistic-cycled"); var text = Loc.GetString(shots == 0 ? "gun-ballistic-cycled-empty" : "gun-ballistic-cycled");
@@ -243,6 +244,9 @@ public abstract partial class SharedGunSystem
private void OnBallisticTakeAmmo(EntityUid uid, BallisticAmmoProviderComponent component, TakeAmmoEvent args) private void OnBallisticTakeAmmo(EntityUid uid, BallisticAmmoProviderComponent component, TakeAmmoEvent args)
{ {
if (!component.IsCycled)
return;
for (var i = 0; i < args.Shots; i++) for (var i = 0; i < args.Shots; i++)
{ {
EntityUid entity; EntityUid entity;
@@ -263,6 +267,10 @@ public abstract partial class SharedGunSystem
} }
} }
//un-cycle the firearm
if (!component.AutoCycle)
component.Cycled = false;
UpdateBallisticAppearance(uid, component); UpdateBallisticAppearance(uid, component);
Dirty(uid, component); Dirty(uid, component);
} }

View File

@@ -0,0 +1,9 @@
using Content.Shared.Roles;
namespace Content.Shared._White.Cult.Components;
[RegisterComponent]
public sealed partial class CultistRoleComponent : AntagonistRoleComponent
{
}

View File

@@ -0,0 +1,8 @@
namespace Content.Shared._White.ReduceBlindness;
[RegisterComponent, AutoGenerateComponentState]
public sealed partial class ReduceBlindnessComponent : Component
{
[ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float ReduceAmount { get; set; } = 1.5f;
}

View File

@@ -0,0 +1,35 @@
using Content.Shared.Eye.Blinding.Components;
using Content.Shared.Hands;
namespace Content.Shared._White.ReduceBlindness;
public sealed class ReduceBlindnessSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ReduceBlindnessComponent, GotEquippedHandEvent>(OnEquipepd);
SubscribeLocalEvent<ReduceBlindnessComponent, GotUnequippedHandEvent>(OnUnequipped);
}
private void OnEquipepd(Entity<ReduceBlindnessComponent> ent, ref GotEquippedHandEvent args)
{
if (!TryComp(args.User, out BlurryVisionComponent? blurryVisionComponent))
{
return;
}
blurryVisionComponent.Magnitude -= ent.Comp.ReduceAmount;
}
private void OnUnequipped(Entity<ReduceBlindnessComponent> ent, ref GotUnequippedHandEvent args)
{
if (!TryComp(args.User, out BlurryVisionComponent? blurryVisionComponent))
{
return;
}
blurryVisionComponent.Magnitude += ent.Comp.ReduceAmount;
}
}

View File

@@ -1,24 +1,75 @@
rev-title = Революция ## Rev Head
rev-name = Глава революции
rev-description = Группа бунтовщиков тайком пробралась на станцию для того чтобы убить всех глав и захватить её. Они вербуют новых сторонников при помощи устройства-вспышки. Постарайтесь выследить и уничтожить их! roles-antag-rev-head-name = Глава Революции
rev-welcome-headrev = roles-antag-rev-head-objective = Группа бунтовщиков тайком пробралась на станцию для того чтобы убить всех глав и захватить её. Они вербуют новых сторонников при помощи устройства-вспышки. Постарайтесь выследить и уничтожить их!
Вы - главный революционер. Ваша задача - завербовать как можно больше членов экипажа в свои ряды и захватить станцию, убив глав всех отделов и капитана.
В вашем кармане находится вспышка. Используйте её на другом члене экипажа для того чтобы путем гипноза передать ему свои революционные идеалы. head-rev-role-greeting =
Работайте сообща с другими зачинщиками мятежа и постарайтесь не попасться Службе Безопасности. Вы - Глава Революции.
Вашей целью является убрать весь коммандный состав станции - убив их или изгнав.
Синдикат снабдил вас вспышками, которые могут быть использованы для вербовки персонала станции на свою сторону.
Однако, это не сработает на Службу Безопасности, Командный состав или на тех, кто носит защиту от вспышек.
Да здравствует Революция! За старый космос Да здравствует Революция! За старый космос
rev-welcome-rev =
В свете вспышки вы увидели объятую пламенем штаб-квартиру НаноТрейзен, и вам понравилось это зрелище. Хотите вы того или нет, но теперь вы - революционер. head-rev-briefing =
Вы загипнотизированы и обязаны слепо подчиняться приказам главных революционеров. Ваши новые идеалы запрещают вам мешать ходу революции, сдаваться Службе Безопасности или сдавать ей своих товарищей. Ваша задача - захватить станцию, убив глав всех отделов и капитана. Используйте вспышку чтобы вербовать людей на свою сторону.
Да здравствует Революция! За старый космос! Убейте всех глав, чтобы захватить станцию.
rev-revmajor = Крупная победа Революции!
rev-neutral = Ничейный исход! head-rev-break-mindshield = Имплант защиты разума сломался!
rev-crewmajor = Крупная победа экипажа!
rev-cond-allheadrevsdead = Все лидеры революции погибли. ## Rev
rev-cond-allcrewheadsdead = Все главы станции погибли.
rev-list-revs-start = Революционерами были: roles-antag-rev-name = Революционер
rev-list = - [color=White]{ $name }[/color] ([color=gray]{ $user }[/color]) { $headrev } roles-antag-rev-objective = Ваша задача - обеспечить безопасность и выполнять приказы Глав Революции, а также убить весь командный состав станции.
rev-list-heads-start = Главами станции были:
rev-not-enough-ready-players = Недостаточно игроков готовы к игре! { $readyPlayersCount } игроков из необходимых { $minimumPlayers } готовы. Нельзя начать режим: Revolution. rev-break-control = {$name} вспомнили о своей истинной преданности!
rev-no-one-ready = Нет готовых игроков! Нельзя начать Revolution.
rev-list-headrevbool = [color=Red]Глава революции[/color] rev-role-greeting =
rev-objective = Убить глав всех отделов и капитана! Вы - революционер.
Вам поручено захватить станцию и защитить Глав Революции.
Уничтожьте весь командный состав.
Да здравствует революция!
rev-briefing = Помогите Главам Революции убить весь командный состав, чтобы захватить станцию.
## General
rev-title = Революционеры
rev-description = Революционеры среди нас.
rev-not-enough-ready-players = Недостаточно игроков чтобы запустить режим. Готово {$readyPlayersCount} игроков из {$minimumPlayers} необходимых. Невозможно запустить режим Революция.
rev-no-one-ready = Нет готовых игроков! Невозможно запустить режим Революция.
rev-no-heads = Не удалось выбрать Глав Революции. Невозможно запустить режим Революция.
rev-all-heads-dead = Все главы мертвы, теперь прикончите остальных членов экипажа!
rev-won = Главы Революции выжили и убили весь командный состав.
rev-lost = Командный состав выжил и убили всех Глав Революции.
rev-stalemate = И Глав Революции, и командный состав погибли. Ничья.
rev-reverse-stalemate = Обе команды выжили. Ничья.
rev-headrev-count = {$initialCount ->
[one] Был один Глава Революции:
*[other] Было {$initialCount} Глав Революции:
}
rev-headrev-name-user = [color=#5e9cff]{$name}[/color] ([color=gray]{$username}[/color]) завербовал {$count} {$count ->
[one] человека
*[other] человек
}
rev-headrev-name = [color=#5e9cff]{$name}[/color] завербовал {$count} {$count ->
[one] человека
*[other] человек
}
## Deconverted window
rev-deconverted-title = Деконвертирован!
rev-deconverted-text =
Поскольку последний Глава Революции умер, революция закончилась.
Вы больше не революционер, так что будьте спокойны.
rev-deconverted-confirm = Принять

View File

@@ -169,6 +169,9 @@
sprite: Clothing/Back/Duffels/syndicate.rsi sprite: Clothing/Back/Duffels/syndicate.rsi
- type: ExplosionResistance - type: ExplosionResistance
damageCoefficient: 0.1 damageCoefficient: 0.1
- type: ClothingSpeedModifier
walkModifier: 1
sprintModifier: 1
- type: entity - type: entity
parent: ClothingBackpackDuffelSyndicate parent: ClothingBackpackDuffelSyndicate

View File

@@ -10,7 +10,7 @@
- ShellShotgun - ShellShotgun
- type: CartridgeAmmo - type: CartridgeAmmo
count: 6 count: 6
spread: 15 spread: 22
soundEject: soundEject:
collection: ShellEject collection: ShellEject
- type: Sprite - type: Sprite

View File

@@ -10,7 +10,7 @@
- type: Projectile - type: Projectile
damage: damage:
types: types:
Piercing: 28 Piercing: 34
- type: entity - type: entity
id: PelletShotgunBeanbag id: PelletShotgunBeanbag
@@ -40,7 +40,7 @@
- type: Projectile - type: Projectile
damage: damage:
types: types:
Piercing: 10 Piercing: 13
- type: entity - type: entity
id: PelletShotgunIncendiary id: PelletShotgunIncendiary
@@ -54,7 +54,7 @@
- type: Projectile - type: Projectile
damage: damage:
types: types:
Blunt: 3 Blunt: 6
Heat: 7 Heat: 7
- type: IgnitionSource - type: IgnitionSource
ignited: true ignited: true
@@ -85,8 +85,8 @@
- type: Projectile - type: Projectile
damage: damage:
types: types:
Piercing: 3 Piercing: 5
Slash: 3 #remember, it's metal shrapnel! Slash: 5 #remember, it's metal shrapnel!
- type: entity - type: entity
id: PelletShotgunTranquilizer id: PelletShotgunTranquilizer
@@ -177,8 +177,8 @@
- type: Projectile - type: Projectile
damage: damage:
types: types:
Radiation: 5 Radiation: 6
Piercing: 5 Piercing: 7
- type: entity - type: entity
id: PelletGrapeshot #tally fucking ho id: PelletGrapeshot #tally fucking ho

View File

@@ -15,6 +15,7 @@
- type: AmmoCounter - type: AmmoCounter
- type: Gun - type: Gun
fireRate: 2 fireRate: 2
projectileSpeed: 48
selectedMode: SemiAuto selectedMode: SemiAuto
availableModes: availableModes:
- SemiAuto - SemiAuto

View File

@@ -49,6 +49,7 @@
proto: GrenadeFrag proto: GrenadeFrag
soundInsert: soundInsert:
path: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg path: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg
autoCycle: false
- type: entity - type: entity
name: RPG-7 name: RPG-7

View File

@@ -36,6 +36,7 @@
proto: ShellShotgun proto: ShellShotgun
soundInsert: soundInsert:
path: /Audio/Weapons/Guns/MagIn/shotgun_insert.ogg path: /Audio/Weapons/Guns/MagIn/shotgun_insert.ogg
autoCycle: false
- type: ContainerContainer - type: ContainerContainer
containers: containers:
ballistic-ammo: !type:Container ballistic-ammo: !type:Container

View File

@@ -30,6 +30,7 @@
whitelist: whitelist:
tags: tags:
- CartridgeLightRifle - CartridgeLightRifle
autoCycle: false
- type: ContainerContainer - type: ContainerContainer
containers: containers:
ballistic-ammo: !type:Container ballistic-ammo: !type:Container
@@ -63,6 +64,7 @@
- CartridgeAntiMateriel - CartridgeAntiMateriel
capacity: 5 capacity: 5
proto: CartridgeAntiMateriel proto: CartridgeAntiMateriel
autoCycle: true
- type: Wieldable - type: Wieldable
wieldTime: 0 wieldTime: 0
forceTwoHanded: True forceTwoHanded: True

View File

@@ -18,6 +18,7 @@
- type: StaminaDamageOnHit - type: StaminaDamageOnHit
damage: 5 damage: 5
- type: Wieldable - type: Wieldable
- type: ReduceBlindness
- type: IncreaseDamageOnWield - type: IncreaseDamageOnWield
damage: damage:
types: types:

View File

@@ -113,7 +113,7 @@
- name: suitstorage - name: suitstorage
slotTexture: suit_storage slotTexture: suit_storage
slotFlags: SUITSTORAGE slotFlags: SUITSTORAGE
slotGroup: MainHotbar slotGroup: SecondHotbar
stripTime: 3 stripTime: 3
uiWindowPos: 2,0 uiWindowPos: 2,0
strippingWindowPos: 2,5 strippingWindowPos: 2,5

View File

@@ -1,13 +0,0 @@
- type: entity
noSpawn: true
parent: BaseObjective
id: CultistKillObjective
description: objective-condition-kill-person-description
components:
- type: Objective
difficulty: 1.5
issuer: Cult
icon:
sprite: White/Cult/interface.rsi
state: icon
- type: KillCultistTargetCondition

View File

@@ -0,0 +1,22 @@
- type: entity
noSpawn: true
parent: BaseTargetObjective
id: KillCultTargetObjective
description: This fool person should be sacrificed in the glory of our God.
components:
- type: Objective
issuer: cult
unique: true
difficulty: 3
icon:
sprite: Objects/Weapons/Melee/cult_dagger.rsi
state: icon
- type: RoleRequirement
roles:
components:
- CultistRole
- type: TargetObjective
title: objective-condition-kill-person-title
- type: PickCultTarget
- type: KillPersonCondition
requireDead: true