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,15 +49,13 @@ 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;
_blindableComponent.LightSetup = false;
_blindableComponent.GraceFrame = true;
return true;
}
return blind; _lightManager.Enabled = true;
_blindableComponent.LightSetup = false;
_blindableComponent.GraceFrame = true;
return true;
} }
protected override void Draw(in OverlayDrawArgs args) protected override void Draw(in OverlayDrawArgs args)
@@ -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,147 +75,127 @@ 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 null!; return mind;
} }
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 enoughCultists = cultistsAmount + constructsAmount > 10;
if (!enoughCultists)
{
return false;
}
var target = GetTarget();
var targetKilled = target == null || _mindSystem.IsCharacterDeadIc(target);
if (targetKilled)
return true;
} }
return false; var cultistsAmount = cultistsRule.CurrentCultists.Count;
var constructsAmount = cultistsRule.Constructs.Count;
var enoughCultists = cultistsAmount + constructsAmount > 10;
if (!enoughCultists)
{
return false;
}
var target = GetTarget();
var targetKilled = target == null || _mindSystem.IsCharacterDeadIc(target);
return targetKilled;
} }
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;
if (!TryComp<MobStateComponent>(owner, out var mobState))
continue;
if (_mobStateSystem.IsAlive(owner, mobState))
{ {
var owner = cultistComponent.Owner; aliveCultists++;
if (!TryComp<MobStateComponent>(owner, out var mobState))
continue;
if (_mobStateSystem.IsAlive(owner, mobState))
{
cultists++;
}
} }
if (cultists == 0)
cultRuleComponent.WinCondition = CultWinCondition.CultFailure;
aliveCultistsCount += cultists;
} }
if (aliveCultistsCount == 0) if (aliveCultists != 0)
{ return;
_roundEndSystem.EndRound();
} cultistsRule.WinCondition = CultWinCondition.CultFailure;
_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))
return;
if (!mindComponent.HasMind)
return;
cultRuleComponent.Cultists.Add(component);
if (TryComp<ActorComponent>(component.Owner, out var actor))
{
cultRuleComponent.CultistsList.Add(MetaData(component.Owner).EntityName, actor.PlayerSession.Name);
}
var traitorRole = new TraitorRoleComponent()
{
PrototypeId = cultRuleComponent.CultistRolePrototype
};
_roleSystem.MindAddRole(mindComponent.Mind.Value, traitorRole);
UpdateCultistsAppearance(cultRuleComponent);
} }
if (!TryComp<MindContainerComponent>(uid, out var mindComponent))
return;
if (!mindComponent.HasMind)
return;
cultistsRule.CurrentCultists.Add(component);
if (TryComp<ActorComponent>(uid, out var actor))
{
cultistsRule.CultistsCache.Add(MetaData(uid).EntityName, actor.PlayerSession.Name);
}
UpdateCultistsAppearance(cultistsRule);
} }
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);
RemoveCultistAppearance(component);
CheckRoundShouldEnd();
} }
cultistsRule.CurrentCultists.Remove(component);
RemoveCultistAppearance(uid);
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,76 +212,74 @@ 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;
ev.AddLine(winText); }
ev.AddLine(Loc.GetString("cultists-list-start")); var winText = Loc.GetString($"cult-cond-{cultistsRule.WinCondition.ToString().ToLower()}");
ev.AddLine(winText);
foreach (var (entityName, ckey) in cultRuleComponent.CultistsList) ev.AddLine(Loc.GetString("cultists-list-start"));
{
var lising = Loc.GetString("cultists-list-name", ("name", entityName), ("user", ckey)); foreach (var (entityName, ckey) in cultistsRule.CultistsCache)
ev.AddLine(lising); {
} var lising = Loc.GetString("cultists-list-name", ("name", entityName), ("user", ckey));
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;
if (!ev.Forced && ev.Players.Length < minPlayers)
{
_chatManager.DispatchServerAnnouncement(Loc.GetString("traitor-not-enough-ready-players",
("readyPlayersCount", ev.Players.Length), ("minimumPlayers", minPlayers)));
ev.Cancel();
continue;
}
if (ev.Players.Length == 0)
{
_chatManager.DispatchServerAnnouncement(Loc.GetString("traitor-no-one-ready"));
ev.Cancel();
}
} }
var minPlayers = _cultGameRuleMinimapPlayers;
if (!ev.Forced && ev.Players.Length < minPlayers)
{
_chatManager.DispatchServerAnnouncement(Loc.GetString("traitor-not-enough-ready-players",
("readyPlayersCount", ev.Players.Length), ("minimumPlayers", minPlayers)));
ev.Cancel();
return;
}
if (ev.Players.Length != 0)
return;
_chatManager.DispatchServerAnnouncement(Loc.GetString("traitor-no-one-ready"));
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;
}
foreach (var player in ev.Players)
{
if (!ev.Profiles.ContainsKey(player.UserId))
continue; continue;
foreach (var player in ev.Players) cultistsRule.StarCandidates[player] = ev.Profiles[player.UserId];
{ }
if (!ev.Profiles.ContainsKey(player.UserId))
continue;
cultRule.StarCandidates[player] = ev.Profiles[player.UserId]; var potentialCultists = FindPotentialCultist(cultistsRule.StarCandidates);
} var pickedCultist = PickCultists(potentialCultists);
var potentialTargets = FindPotentialTargets(pickedCultist);
var potentialCultists = FindPotentialCultist(cultRule.StarCandidates); cultistsRule.CultTarget = _random.PickAndTake(potentialTargets).Mind;
var pickedCultist = PickCultists(potentialCultists);
var potentialTargets = FindPotentialTargets(pickedCultist);
cultRule.CultTarget = _random.PickAndTake(potentialTargets).Mind; foreach (var pickerCultist in pickedCultist)
{
foreach (var pickerCultist in pickedCultist) MakeCultist(pickerCultist);
{
MakeCultist(pickerCultist);
}
} }
} }
@@ -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);
} }
@@ -91,7 +94,7 @@ public abstract class SharedGrapplingGunSystem : EntitySystem
if (msg.Reeling && if (msg.Reeling &&
(!TryComp<CombatModeComponent>(player, out var combatMode) || (!TryComp<CombatModeComponent>(player, out var combatMode) ||
!combatMode.IsInCombatMode)) !combatMode.IsInCombatMode))
{ {
return; return;
} }
@@ -132,7 +135,7 @@ public abstract class SharedGrapplingGunSystem : EntitySystem
component.Projectile = null; component.Projectile = null;
SetReeling(uid, component, false, args.User); SetReeling(uid, component, false, args.User);
_gun.ChangeBasicEntityAmmoCount(uid, 1); _gun.ChangeBasicEntityAmmoCount(uid, 1);
args.Handled = true; args.Handled = true;
} }

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 = Синдикат снабдил вас вспышками, которые могут быть использованы для вербовки персонала станции на свою сторону.
В свете вспышки вы увидели объятую пламенем штаб-квартиру НаноТрейзен, и вам понравилось это зрелище. Хотите вы того или нет, но теперь вы - революционер. Однако, это не сработает на Службу Безопасности, Командный состав или на тех, кто носит защиту от вспышек.
Вы загипнотизированы и обязаны слепо подчиняться приказам главных революционеров. Ваши новые идеалы запрещают вам мешать ходу революции, сдаваться Службе Безопасности или сдавать ей своих товарищей. Ваша задача - захватить станцию, убив глав всех отделов и капитана. Да здравствует Революция! За старый космос
Да здравствует Революция! За старый космос!
rev-revmajor = Крупная победа Революции! head-rev-briefing =
rev-neutral = Ничейный исход! Используйте вспышку чтобы вербовать людей на свою сторону.
rev-crewmajor = Крупная победа экипажа! Убейте всех глав, чтобы захватить станцию.
rev-cond-allheadrevsdead = Все лидеры революции погибли.
rev-cond-allcrewheadsdead = Все главы станции погибли. head-rev-break-mindshield = Имплант защиты разума сломался!
rev-list-revs-start = Революционерами были:
rev-list = - [color=White]{ $name }[/color] ([color=gray]{ $user }[/color]) { $headrev } ## Rev
rev-list-heads-start = Главами станции были:
rev-not-enough-ready-players = Недостаточно игроков готовы к игре! { $readyPlayersCount } игроков из необходимых { $minimumPlayers } готовы. Нельзя начать режим: Revolution. roles-antag-rev-name = Революционер
rev-no-one-ready = Нет готовых игроков! Нельзя начать Revolution. roles-antag-rev-objective = Ваша задача - обеспечить безопасность и выполнять приказы Глав Революции, а также убить весь командный состав станции.
rev-list-headrevbool = [color=Red]Глава революции[/color]
rev-objective = Убить глав всех отделов и капитана! rev-break-control = {$name} вспомнили о своей истинной преданности!
rev-role-greeting =
Вы - революционер.
Вам поручено захватить станцию и защитить Глав Революции.
Уничтожьте весь командный состав.
Да здравствует революция!
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