Chaplain stuff (#98)
* - add: Null rod. * - add: Only chaplain can use holy weapons. * - add: Chaplain is cult immune. * - fix: Fix component granting. * - add: Only chaplain can use null rod. * - add: Armaments beacon. * - add: Chaplain playtime requirement.
This commit is contained in:
39
Content.Server/_White/Chaplain/ArmamentsBeaconSystem.cs
Normal file
39
Content.Server/_White/Chaplain/ArmamentsBeaconSystem.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using Content.Server.Hands.Systems;
|
||||
using Content.Server.Popups;
|
||||
using Content.Shared._White.Chaplain;
|
||||
using Content.Shared.Ghost;
|
||||
using Content.Shared.Inventory;
|
||||
|
||||
namespace Content.Server._White.Chaplain;
|
||||
|
||||
public sealed class ArmamentsBeaconSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly InventorySystem _inventorySystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ArmamentsBeaconComponent, ArmorSelectedEvent>(OnArmorSelected);
|
||||
}
|
||||
|
||||
private void OnArmorSelected(Entity<ArmamentsBeaconComponent> ent, ref ArmorSelectedEvent args)
|
||||
{
|
||||
var entity = args.Session.AttachedEntity;
|
||||
var index = args.SelectedIndex;
|
||||
|
||||
if (index < 0 || index >= ent.Comp.Armor.Count || entity == null)
|
||||
return;
|
||||
|
||||
_inventorySystem.TryUnequip(entity.Value, "outerClothing", true);
|
||||
_inventorySystem.SpawnItemInSlot(entity.Value, "outerClothing", ent.Comp.Armor[index], silent: true);
|
||||
|
||||
if (index < ent.Comp.Helmets.Count && ent.Comp.Helmets[index] != null)
|
||||
{
|
||||
_inventorySystem.TryUnequip(entity.Value, "head", true);
|
||||
_inventorySystem.SpawnItemInSlot(entity.Value, "head", ent.Comp.Helmets[index]!.Value, silent: true);
|
||||
}
|
||||
|
||||
Del(ent);
|
||||
}
|
||||
}
|
||||
40
Content.Server/_White/Chaplain/NullRodSystem.cs
Normal file
40
Content.Server/_White/Chaplain/NullRodSystem.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using Content.Server.Hands.Systems;
|
||||
using Content.Server.Popups;
|
||||
using Content.Shared._White.Chaplain;
|
||||
using Content.Shared.Ghost;
|
||||
|
||||
namespace Content.Server._White.Chaplain;
|
||||
|
||||
public sealed class NullRodSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly HandsSystem _hands = default!;
|
||||
[Dependency] private readonly PopupSystem _popup = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<NullRodComponent, WeaponSelectedEvent>(OnWeaponSelected);
|
||||
}
|
||||
|
||||
private void OnWeaponSelected(Entity<NullRodComponent> ent, ref WeaponSelectedEvent args)
|
||||
{
|
||||
var entity = args.Session.AttachedEntity;
|
||||
|
||||
if (args.SelectedWeapon == string.Empty || entity == null)
|
||||
return;
|
||||
|
||||
if (!HasComp<HolyComponent>(entity.Value) && !HasComp<GhostComponent>(entity.Value))
|
||||
{
|
||||
_popup.PopupEntity($"Вам не хватает веры, чтобы использовать {Name(ent)}", entity.Value, entity.Value);
|
||||
return;
|
||||
}
|
||||
|
||||
var weapon = Spawn(args.SelectedWeapon, Transform(entity.Value).Coordinates);
|
||||
EnsureComp<HolyWeaponComponent>(weapon);
|
||||
|
||||
Del(ent);
|
||||
|
||||
_hands.PickupOrDrop(entity.Value, weapon, true, false, false);
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Random;
|
||||
using Content.Shared._White;
|
||||
using Content.Shared._White.Chaplain;
|
||||
using Content.Shared._White.Cult.Components;
|
||||
using Content.Shared.Mind;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
@@ -327,9 +328,10 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
|
||||
if (!_jobSystem.CanBeAntag(player))
|
||||
continue;
|
||||
|
||||
// Gulag
|
||||
// Gulag & chaplain
|
||||
if (!_mindSystem.TryGetMind(player, out _, out var mind) ||
|
||||
mind.OwnedEntity is not { } ownedEntity || HasComp<GulagBoundComponent>(ownedEntity))
|
||||
mind.OwnedEntity is not { } ownedEntity || HasComp<GulagBoundComponent>(ownedEntity) ||
|
||||
HasComp<HolyComponent>(ownedEntity))
|
||||
continue;
|
||||
|
||||
// Latejoin
|
||||
@@ -414,7 +416,7 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
|
||||
|
||||
if (!_mindSystem.TryGetMind(cultist, out var mindId, out var mind))
|
||||
{
|
||||
Log.Info("Failed getting mind for picked thief.");
|
||||
Log.Info("Failed getting mind for picked cultist.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ using Content.Server.Hands.Systems;
|
||||
using Content.Server.Weapons.Ranged.Systems;
|
||||
using Content.Server._White.Cult.GameRule;
|
||||
using Content.Server._White.Cult.Runes.Comps;
|
||||
using Content.Shared._White.Chaplain;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Chemistry.Components.SolutionManager;
|
||||
using Content.Shared.Cuffs.Components;
|
||||
@@ -423,7 +424,8 @@ public sealed partial class CultSystem : EntitySystem
|
||||
var isTarget = mind!.Mind!.Value == targetMind?.Mind!.Value;
|
||||
|
||||
// Выполнение действия в зависимости от условий
|
||||
if (canBeConverted && !HasComp<MindShieldComponent>(victim.Value) && !isTarget)
|
||||
if (canBeConverted && !HasComp<HolyComponent>(victim.Value) &&
|
||||
!HasComp<MindShieldComponent>(victim.Value) && !isTarget)
|
||||
{
|
||||
result = Convert(uid, victim.Value, args.User, args.Cultists);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
using Content.Server.Doors.Systems;
|
||||
using Content.Shared._White.Chaplain;
|
||||
using Content.Shared.Doors;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Stunnable;
|
||||
using Content.Shared._White.Cult;
|
||||
using Content.Shared.Doors.Components;
|
||||
using Content.Shared.Weapons.Melee.Events;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Physics.Systems;
|
||||
using CultistComponent = Content.Shared._White.Cult.Components.CultistComponent;
|
||||
|
||||
@@ -13,6 +18,7 @@ public sealed class RunicDoorSystem : EntitySystem
|
||||
[Dependency] private readonly DoorSystem _doorSystem = default!;
|
||||
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
||||
[Dependency] private readonly SharedStunSystem _stunSystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -20,6 +26,18 @@ public sealed class RunicDoorSystem : EntitySystem
|
||||
|
||||
SubscribeLocalEvent<RunicDoorComponent, BeforeDoorOpenedEvent>(OnBeforeDoorOpened);
|
||||
SubscribeLocalEvent<RunicDoorComponent, BeforeDoorClosedEvent>(OnBeforeDoorClosed);
|
||||
SubscribeLocalEvent<RunicDoorComponent, AttackedEvent>(OnGetAttacked);
|
||||
}
|
||||
|
||||
private void OnGetAttacked(Entity<RunicDoorComponent> ent, ref AttackedEvent args)
|
||||
{
|
||||
if (!HasComp<HolyWeaponComponent>(args.Used) || !TryComp<DoorComponent>(ent, out var doorComp) ||
|
||||
doorComp.State is not DoorState.Closed)
|
||||
return;
|
||||
|
||||
_audio.PlayPvs(new SoundPathSpecifier("/Audio/Magic/knock.ogg"), ent);
|
||||
|
||||
_doorSystem.StartOpening(ent, doorComp);
|
||||
}
|
||||
|
||||
private void OnBeforeDoorOpened(EntityUid uid, RunicDoorComponent component, BeforeDoorOpenedEvent args)
|
||||
@@ -61,7 +79,7 @@ public sealed class RunicDoorSystem : EntitySystem
|
||||
|
||||
_doorSystem.Deny(airlock);
|
||||
|
||||
if (!HasComp<HumanoidAppearanceComponent>(user))
|
||||
if (!HasComp<HumanoidAppearanceComponent>(user) || HasComp<HolyComponent>(user))
|
||||
return false;
|
||||
|
||||
var direction = Transform(user).MapPosition.Position - Transform(airlock).MapPosition.Position;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Content.Server._White.Other.MeleeBlockSystem;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class MeleeBlockComponent : Component
|
||||
{
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public float BlockChance = 0.4f;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Weapons.Melee.Events;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server._White.Other.MeleeBlockSystem;
|
||||
|
||||
public sealed class MeleeBlockSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<HandsComponent, MeleeBlockAttemptEvent>(OnBlockAttempt);
|
||||
}
|
||||
|
||||
private void OnBlockAttempt(Entity<HandsComponent> ent, ref MeleeBlockAttemptEvent args)
|
||||
{
|
||||
if (ent.Owner == args.Attacker ||
|
||||
!TryComp(ent.Comp.ActiveHandEntity, out MeleeBlockComponent? blockComponent) ||
|
||||
!_random.Prob(blockComponent.BlockChance))
|
||||
return;
|
||||
|
||||
args.Blocked = true;
|
||||
|
||||
_popupSystem.PopupEntity("заблокировал!", ent);
|
||||
|
||||
_audio.PlayPvs(new SoundPathSpecifier("/Audio/Weapons/block_metal1.ogg"), ent,
|
||||
AudioParams.Default.WithVariation(0.25f));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Content.Server._White.Other.RandomDamageSystem;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class RandomDamageComponent : Component
|
||||
{
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public float Max = 50f;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Damage.Prototypes;
|
||||
using Content.Shared.Weapons.Melee.Events;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server._White.Other.RandomDamageSystem;
|
||||
|
||||
public sealed class RandomDamageSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<RandomDamageComponent, MeleeHitEvent>(HandleHit);
|
||||
}
|
||||
|
||||
private void HandleHit(Entity<RandomDamageComponent> ent, ref MeleeHitEvent args)
|
||||
{
|
||||
var damage = _random.NextFloat() * ent.Comp.Max;
|
||||
args.BonusDamage = new DamageSpecifier(_prototypeManager.Index<DamageTypePrototype>("Slash"), damage);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user