diff --git a/Content.Client/Weapons/Melee/MeleeWeaponSystem.cs b/Content.Client/Weapons/Melee/MeleeWeaponSystem.cs index 20655737259..b01d7dac8ac 100644 --- a/Content.Client/Weapons/Melee/MeleeWeaponSystem.cs +++ b/Content.Client/Weapons/Melee/MeleeWeaponSystem.cs @@ -156,7 +156,6 @@ public override void Update(float frameTime) if (altDown == BoundKeyState.Up && attackTime >= TimeSpan.FromSeconds(charged.MinAttackTime) || attackTime >= TimeSpan.FromSeconds(charged.MaxAttackTime)) { RaisePredictiveEvent(new ChargedAttackEnd(GetNetCoordinates(coordinates), GetNetEntity(weaponUid), attackTime)); - Log.Info("1"); return; } else if (altDown == BoundKeyState.Up && attackTime <= TimeSpan.FromSeconds(charged.MinAttackTime)) diff --git a/Content.Server/Imperial/Medieval/Cult/Bloodspells/CultCastSystem.cs b/Content.Server/Imperial/Medieval/Cult/Bloodspells/CultCastSystem.cs index b7be87ea2e5..14ad17c0da1 100644 --- a/Content.Server/Imperial/Medieval/Cult/Bloodspells/CultCastSystem.cs +++ b/Content.Server/Imperial/Medieval/Cult/Bloodspells/CultCastSystem.cs @@ -1,27 +1,25 @@ +using System.Linq; +using System.Numerics; using System.Data; using Content.Server.Chat.Systems; using Content.Server.Cult.Components; -using Content.Server.Imperial.Medieval.Cult.Bloodspells.mateials; +using Content.Server.Imperial.Medieval.Cult.Bloodspells.Materials; +using Content.Server.Imperial.Medieval.Cult.Bloodspells.Light; +using Content.Server.Hands.Systems; using Content.Shared.Body.Components; using Content.Shared.Inventory; using Content.Shared.Popups; -using Robust.Shared.Timing; -using System.Linq; -using System.Numerics; -using Content.Server.Hands.Systems; -using Content.Server.Imperial.Medieval.Cult.Bloodspells.light; +using Content.Shared.Stacks; using Content.Shared.Alert; using Content.Shared.Damage; using Content.Shared.Imperial.Medieval.Cult; using Content.Shared.Interaction.Events; using Content.Shared.Weapons.Melee.Events; - +using Robust.Shared.Prototypes; +using Robust.Shared.Timing; namespace Content.Server.Imperial.Medieval.Cult.Bloodspells; -/// -/// This handles... -/// public sealed class CultCastSystem : EntitySystem { [Dependency] private readonly HandsSystem _handsSystem = default!; @@ -32,352 +30,316 @@ public sealed class CultCastSystem : EntitySystem [Dependency] private readonly InventorySystem _inventorySystem = default!; [Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly AlertsSystem _alert = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly SharedStackSystem _stack = default!; + + private const int MaxStoredMessages = 3; + private const float MinTimeBetweenWords = 0.7f; + private const float MaxSpellCastTime = 5.0f; + private const float MaterialLookupRange = 1f; + private const float DeathCurseDamageMultiplier = 1.5f; + private const int DeathCurseCountDivisor = 2; + + private List _bloodSpells = new(); - /// public override void Initialize() { SubscribeLocalEvent(OnSpoke); - SubscribeLocalEvent(OnGetDamage); + SubscribeLocalEvent(OnDamageReceived); SubscribeLocalEvent(OnInit); - SubscribeLocalEvent(OnAttack); - + SubscribeLocalEvent(OnAttackAttempt); } private void OnInit(EntityUid uid, CultMemberComponent component, ComponentInit args) { - if (component.DeathCusre) + if (component.DeathCurse) _alert.ShowAlert(uid, component.DeathCurseAlert); } - private void OnGetDamage(EntityUid uid, CultMemberComponent component, DamageChangedEvent args) + private void OnDamageReceived(EntityUid uid, CultMemberComponent component, DamageChangedEvent args) { - if (!component.DeathCusre) + if (!component.DeathCurse || !args.DamageIncreased || !args.Origin.HasValue) + return; + + var attacker = args.Origin.Value; + + if (HasComp(attacker)) return; - if (!args.DamageIncreased) + + if (TryComp(attacker, out var cursed) && cursed.CurseLevel != 0) return; - if (!args.Origin.HasValue) + + ApplyOrIncreaseCurse(attacker); + RemoveDeathCurse(uid, component); + } + + private void OnAttackAttempt(EntityUid uid, CultMemberComponent component, AttackAttemptEvent args) + { + if (!component.DeathCurse || args.Target == null) return; - if (HasComp(args.Origin.Value)) + + var target = args.Target.Value; + + if (HasComp(target)) + return; + + if (TryComp(target, out var cursed) && cursed.CurseLevel != 0) return; - if (TryComp(args.Origin.Value, out var curs)) - { - if (curs.CurseLevel != 0) - return; - } - if (TryComp(args.Origin.Value, out var cursed)) + RemoveDeathCurse(uid, component); + } + + private void ApplyOrIncreaseCurse(EntityUid target) + { + if (TryComp(target, out var existingCurse)) { - foreach (var key in cursed.CurseDamage.DamageDict.Keys.ToList()) + foreach (var key in existingCurse.CurseDamage.DamageDict.Keys.ToList()) { - cursed.CurseDamage.DamageDict[key] *= 1.5f; - cursed.CurseCount /= 2; + existingCurse.CurseDamage.DamageDict[key] *= DeathCurseDamageMultiplier; + existingCurse.CurseCount /= DeathCurseCountDivisor; } } else { - AddComp(args.Origin.Value); + EnsureComp(target); } - component.DeathCusre = false; + } + + private void RemoveDeathCurse(EntityUid uid, CultMemberComponent component) + { + component.DeathCurse = false; _alert.ClearAlert(uid, component.DeathCurseAlert); } - private void OnAttack(EntityUid uid, CultMemberComponent component, AttackAttemptEvent args) + private bool CheckSpellSequence(Queue<(string message, TimeSpan time)> queue, BloodSpellPrototype spell) { - if (!component.DeathCusre) - return; - if (args.Target == null) - return; - if (HasComp(args.Target.Value)) - return; - if (TryComp(args.Target.Value, out var curs) && curs.CurseLevel != 0) - return; + var sequenceLength = spell.Incantation.Count; + if (queue.Count < sequenceLength) + return false; - component.DeathCusre = false; - _alert.ClearAlert(uid, component.DeathCurseAlert); + var recentMessages = queue.Reverse().Take(sequenceLength).Reverse().Select(item => item.message).ToArray(); + + return recentMessages.Zip(spell.Incantation, (msg, spellWord) => + msg.Equals(spellWord, StringComparison.OrdinalIgnoreCase)).All(match => match); } - private static bool CheckSequenceInQueueFromRow(Queue<(string message, TimeSpan time)> queue, string[,] array, int targetRow) + private bool ValidateSpellTiming(Queue<(string message, TimeSpan time)> messages, EntityUid caster) { - if (targetRow >= array.GetLength(0) || targetRow < 0) return false; + if (messages.Count == 0) + return false; - int seqLength = array.GetLength(1); - if (queue.Count < seqLength) return false; + var messageArray = messages.ToArray(); - var messages = queue.Reverse().Take(seqLength).Reverse().Select(item => item.message).ToArray(); + for (int i = 1; i < messageArray.Length; i++) + { + var timeDiff = messageArray[i].time - messageArray[i - 1].time; + if (timeDiff.TotalSeconds < MinTimeBetweenWords) + { + _popupSystem.PopupEntity(Loc.GetString("cult-spell-too-fast"), caster, caster); + return false; + } + } - // Получаем последовательность из ряда - var rowSequence = new string[seqLength]; - for (int j = 0; j < seqLength; j++) + var oldestMessage = messages.MaxBy(item => item.time); + if (oldestMessage.time.TotalSeconds <= MaxSpellCastTime) { - rowSequence[j] = array[targetRow, j]; + _popupSystem.PopupEntity(Loc.GetString("cult-spell-too-slow"), caster, caster); + return false; } - // Сравнение (case-insensitive) - return messages.Zip(rowSequence, (msg, seq) => msg.Equals(seq, StringComparison.OrdinalIgnoreCase)).All(match => match); + return true; } - private bool CheckTime(Queue<(string message, TimeSpan time)> lastSpokenMessages , EntityUid uid) + private void OnSpoke(EntityUid uid, CultMemberComponent component, EntitySpokeEvent args) { - if (lastSpokenMessages.Count == 0) - return false; + if (component.LastSpokenMessages.Count >= MaxStoredMessages) + component.LastSpokenMessages.Dequeue(); + + component.LastSpokenMessages.Enqueue((args.Message, _timing.CurTime)); + + if (!TryComp(uid, out var bloodstream) || bloodstream.BleedAmount == 0) + return; + + var spells = _prototypeManager + .EnumeratePrototypes() + .OrderByDescending(s => s.Incantation.Count); - var messages = lastSpokenMessages.ToArray(); - for (int i = 1; i < messages.Length; i++) + foreach (var spell in spells) { - var diff = messages[i].time - messages[i - 1].time; - if (diff.TotalSeconds < 0.7) - { - _popupSystem.PopupEntity("Ты чуствуешь, что твои слова не успели наполнится магией", uid, uid); - return true; - } + if (spell.Incantation.Count == 0 || spell.Incantation.Last() != args.Message) + continue; + + if (!CheckSpellSequence(component.LastSpokenMessages, spell)) + continue; + + if (!ValidateSpellTiming(component.LastSpokenMessages, uid)) + return; + ExecuteSpell(uid, component, spell); + return; } + } - var oldest = lastSpokenMessages.MaxBy(item => item.time); - if (oldest.time.TotalSeconds <= 5) + private void ExecuteSpell(EntityUid caster, CultMemberComponent component, BloodSpellPrototype spell) + { + switch (spell.SpellType) { - _popupSystem.PopupEntity("Ты чуствуешь, что твои слова успели обветшать", uid, uid); - return true; + case BloodSpellType.ItemUpgrade: + CastItemUpgradeSpell(caster, spell); + break; + + case BloodSpellType.CraftItem: + CastCraftingSpell(caster, spell); + break; + + case BloodSpellType.CraftArmor: + CastCraftingSpell(caster, spell, isArmor: true); + break; + + case BloodSpellType.DeathCurse: + CastDeathCurseSpell(caster, component, spell); + break; + + default: + _popupSystem.PopupEntity(Loc.GetString("cult-spell-incorrect"), caster, caster); + break; } - return false; } - private void OnSpoke(EntityUid uid, CultMemberComponent component, EntitySpokeEvent args) + private void CastItemUpgradeSpell(EntityUid caster, BloodSpellPrototype spell) { - if (component.LastSpokenMessages.Count >= 3) + if (!_handsSystem.TryGetActiveItem(caster, out var heldItem)) { - component.LastSpokenMessages.Dequeue(); // Удаляем первый (самый старый) элемент + var failMsg = spell.FailureMessage ?? "cult-spell-need-holy-scripture"; + _popupSystem.PopupEntity(Loc.GetString(failMsg), caster, caster); + return; } - component.LastSpokenMessages.Enqueue((args.Message, - _timing.CurTime)); // я бы мог бы сделать сразу что то с акцентами но блин, это всё таки магия и надо быть точным - if (!TryComp(uid, out var bloodstream)) + var itemPrototype = _entityManager.GetComponent(heldItem.Value).EntityPrototype?.ID; + if (spell.RequiredHeldItem == null || itemPrototype != spell.RequiredHeldItem.Value.Id) + { + var itemName = _entityManager.GetComponent(heldItem.Value).EntityPrototype?.Name ?? "unknown"; + _popupSystem.PopupEntity(Loc.GetString("cult-spell-wrong-item", ("item", itemName)), caster, caster); return; - if (bloodstream.BleedAmount == 0) + } + + if (spell.ReplacementItem == null) return; - string[,] bloodcasts = + + EntityManager.DeleteEntity(heldItem.Value); + var newItem = Spawn(spell.ReplacementItem.Value, Transform(caster).Coordinates); + _handsSystem.TryPickup(caster, newItem, checkActionBlocker: false); + + if (spell.SuccessMessage != null) + _popupSystem.PopupEntity(Loc.GetString(spell.SuccessMessage), caster, caster); + } + + private void CastCraftingSpell(EntityUid caster, BloodSpellPrototype spell, bool isArmor = false) + { + if (spell.RequiredMaterial == null || spell.SpawnProto == null) + return; + + var (availableCount, materials) = CollectNearbyMaterials(caster, spell.RequiredMaterial, spell.RequiredMaterialCount); + if (availableCount < spell.RequiredMaterialCount) { - {"Ave", "The", "Truth"}, - {"Ave", "The", "Bronus"}, - {"Ave", "The", "Vilkus"}, - {"Ave", "The", "Knatus"}, - {"Ave", "The", "Sekir"}, - {"Ave", "The", "Magical"}, - {"Katariemai", "Opoion", "Me chtypisei"}, - // {"Дебагус", "Магикус", "Призывус"} - // {"Elderberry", "Fig", "Banana"} - }; - - for (int i = bloodcasts.GetLength(0)-1; i >= 0; i--) + var failMsg = spell.FailureMessage ?? "cult-spell-insufficient-materials"; + _popupSystem.PopupEntity(Loc.GetString(failMsg), caster, caster); + return; + } + + if (isArmor && spell.ReplaceEquipment) { - if (bloodcasts[i, 2] != args.Message) // Проверяем первое слово - continue; + if (spell.EquipmentSlot == null || + !TryComp(caster, out var inventory) || + !_inventorySystem.TryGetSlotEntity(caster, spell.EquipmentSlot, out var existingOutfit)) + { + var failMsg = spell.FailureMessage ?? "cult-spell-insufficient-materials"; + _popupSystem.PopupEntity(Loc.GetString(failMsg), caster, caster); + return; + } + + ConsumeMaterials(materials); + EntityManager.DeleteEntity(existingOutfit.Value); + var armor = Spawn(spell.SpawnProto.Value, Transform(caster).Coordinates); + _inventorySystem.TryEquip(caster, armor, spell.EquipmentSlot, silent: true, force: true, inventory: inventory); + } + else + { + ConsumeMaterials(materials); + Spawn(spell.SpawnProto.Value, Transform(caster).Coordinates); + } + + if (spell.SuccessMessage != null) + _popupSystem.PopupEntity(Loc.GetString(spell.SuccessMessage), caster, caster); + } + + private (int totalCount, List<(EntityUid entity, int takeCount)> materials) CollectNearbyMaterials( + EntityUid caster, + string materialType, + int requiredCount) + { + var result = new List<(EntityUid entity, int takeCount)>(); + int foundTotal = 0; + + var entities = _lookup.GetEntitiesInRange(caster, MaterialLookupRange) + .Where(e => TryComp(e, out var mat) && mat.MaterialType == materialType) + .ToList(); + + var sortedEntities = entities.OrderByDescending(e => { + int count = TryComp(e, out var stack) ? stack.Count : 1; + return count >= requiredCount ? int.MaxValue : count; + }).ThenByDescending(e => _stack.GetCount(e)); + + foreach (var entity in sortedEntities) + { + if (foundTotal >= requiredCount) + break; + + int availableInStack = _stack.GetCount(entity); + int neededFromThisStack = Math.Min(availableInStack, requiredCount - foundTotal); + + result.Add((entity, neededFromThisStack)); + foundTotal += neededFromThisStack; + } + + return (foundTotal, result); + } - if (!CheckSequenceInQueueFromRow(component.LastSpokenMessages, bloodcasts, i)) + private void ConsumeMaterials(List<(EntityUid entity, int takeCount)> materials) + { + foreach (var (entity, takeCount) in materials) + { + if (!TryComp(entity, out var stack)) { + EntityManager.DeleteEntity(entity); continue; } - if (CheckTime(component.LastSpokenMessages, uid)) - return; - switch (bloodcasts[i, 2]) + + if (stack.Count <= takeCount) { - case "Призывус": - { - var center = Transform(uid).Coordinates; - for (int x = -4; x <= 5; x++) - { - for (int y = -4; y <= 5; y++) - { - var b = Spawn("MedievalCultBrushFine", center.Offset(new Vector2(x*0.5f, y*-0.5f))); - if (!TryComp(b, out var bloodPaint)) - break; - bloodPaint.PosX = x+5; - bloodPaint.PosY = y+5; - } - } - break; - } - - - case "Truth": - { - if (_handsSystem.TryGetActiveItem(uid, out var heldItem)) - { - // Проверяем, что предмет в руке — это именно книга-прототип (MedievalBookCultGuide) - if (!_entityManager.GetComponent(heldItem.Value).EntityPrototype?.ID.Equals("MedievalBookCultGuide") == true) - { - _popupSystem.PopupEntity("В руке должно быть святое писание! а не "+ heldItem+" "+_entityManager.GetComponent(heldItem.Value).EntityPrototype?.Name, uid, uid); - break; - } - - // Удаляем текущий предмет в руке - _entityManager.DeleteEntity(heldItem.Value); - - // Спавним новую книгу и экипируем её - var newBook = Spawn("MedievalBookCultGuide2", Transform(uid).Coordinates); - _handsSystem.TryPickup(uid, newBook, checkActionBlocker: false); - } - else - { - _popupSystem.PopupEntity("В руке должно быть святое писание!", uid, uid); - } - break; - } - - - case "Bronus": - { - var needCount = 5; - var myMaterials = new List{}; - foreach (var target in _lookup.GetEntitiesInRange(uid, 1f)) - { - if (TryComp(target, out var bloodMaterial) && bloodMaterial.MaterialType == "BloodIron") - { - myMaterials.Add(target); - needCount--; - if (needCount == 0) - { - if (TryComp(uid, out var inventory) && _inventorySystem.TryGetSlotEntity(uid, "outerClothing", out var existingOutfit)) - { - foreach (var material in myMaterials) - { - _entityManager.DeleteEntity(material); - } - _entityManager.DeleteEntity(existingOutfit.Value); - var b = Spawn("MedievalClothingOuterArmorCultUp", Transform(uid).Coordinates); - _inventorySystem.TryEquip(uid, b, "outerClothing", silent: true, force: true, inventory: inventory); - return; - } - - } - } - } - _popupSystem.PopupEntity("Ресурсов не достаточно", uid, uid); - break; - } - case "Vilkus": - { - var needCount = 5; - var myMaterials = new List{}; - foreach (var target in _lookup.GetEntitiesInRange(uid, 1f)) - { - if (TryComp(target, out var bloodMaterial) && bloodMaterial.MaterialType == "BloodIron") - { - myMaterials.Add(target); - needCount--; - if (needCount == 0) - { - foreach (var material in myMaterials) - { - _entityManager.DeleteEntity(material); - } - Spawn("MedievalSpearCult", Transform(uid).Coordinates); - return; - } - } - } - _popupSystem.PopupEntity("Ресурсов не достаточно", uid, uid); - break; - } - case "Knatus": - { - var needCount = 5; - var myMaterials = new List{}; - foreach (var target in _lookup.GetEntitiesInRange(uid, 1f)) - { - if (TryComp(target, out var bloodMaterial) && bloodMaterial.MaterialType == "BloodIron") - { - myMaterials.Add(target); - needCount--; - if (needCount == 0) - { - foreach (var material in myMaterials) - { - _entityManager.DeleteEntity(material); - } - Spawn("MedievalCultYatagan", Transform(uid).Coordinates); - return; - } - } - } - _popupSystem.PopupEntity("Ресурсов не достаточно", uid, uid); - break; - } - case "Sekir": - { - var needCount = 5; - var myMaterials = new List{}; - foreach (var target in _lookup.GetEntitiesInRange(uid, 1f)) - { - if (TryComp(target, out var bloodMaterial) && bloodMaterial.MaterialType == "BloodIron") - { - myMaterials.Add(target); - needCount--; - if (needCount == 0) - { - foreach (var material in myMaterials) - { - _entityManager.DeleteEntity(material); - } - Spawn("MedievalIronSekirCult", Transform(uid).Coordinates); - return; - } - } - } - _popupSystem.PopupEntity("Ресурсов не достаточно", uid, uid); - break; - } - case "Magical": - { - var needCount = 5; - var myMaterials = new List{}; - foreach (var target in _lookup.GetEntitiesInRange(uid, 1f)) - { - if (TryComp(target, out var bloodMaterial) && bloodMaterial.MaterialType == "BloodLeather") - { - myMaterials.Add(target); - needCount--; - if (needCount == 0) - { - if (TryComp(uid, out var inventory) && _inventorySystem.TryGetSlotEntity(uid, "outerClothing", out var existingOutfit)) - { - foreach (var material in myMaterials) - { - _entityManager.DeleteEntity(material); - } - _entityManager.DeleteEntity(existingOutfit.Value); - var b = Spawn("MedievalClothingOuterArmorCultMana", Transform(uid).Coordinates); - _inventorySystem.TryEquip(uid, b, "outerClothing", silent: true, force: true, inventory: inventory); - return; - } - - } - } - } - _popupSystem.PopupEntity("Ресурсов не достаточно", uid, uid); - break; - } - case "Me chtypisei": - { - if (!component.DeathCusre) - { - component.DeathCusre = true; - _popupSystem.PopupEntity("Да будет проклят тот, кто меня ударит", uid, uid); - _alert.ShowAlert(uid, component.DeathCurseAlert); - } - else - { - _popupSystem.PopupEntity("Ты чуствуешь, что проклятье сильно", uid, uid); - } - break; - } - default: - _popupSystem.PopupEntity("Ты чуствуешь неправильность в своих словах", uid, uid); - break; + EntityManager.DeleteEntity(entity); + } + else + { + _stack.SetCount(entity, stack.Count - takeCount, stack); } } + } + private void CastDeathCurseSpell(EntityUid caster, CultMemberComponent component, BloodSpellPrototype spell) + { + if (!component.DeathCurse) + { + component.DeathCurse = true; + var successMsg = spell.SuccessMessage ?? "cult-spell-death-curse-activated"; + _popupSystem.PopupEntity(Loc.GetString(successMsg), caster, caster); + _alert.ShowAlert(caster, component.DeathCurseAlert); + } + else + { + var failMsg = spell.FailureMessage ?? "cult-spell-death-curse-already-active"; + _popupSystem.PopupEntity(Loc.GetString(failMsg), caster, caster); + } } } - diff --git a/Content.Server/Imperial/Medieval/Cult/Bloodspells/mateials/BloodMaterialComponent.cs b/Content.Server/Imperial/Medieval/Cult/Bloodspells/Materials/BloodMaterialComponent.cs similarity index 59% rename from Content.Server/Imperial/Medieval/Cult/Bloodspells/mateials/BloodMaterialComponent.cs rename to Content.Server/Imperial/Medieval/Cult/Bloodspells/Materials/BloodMaterialComponent.cs index f87468b9ecb..2f8a925a6f6 100644 --- a/Content.Server/Imperial/Medieval/Cult/Bloodspells/mateials/BloodMaterialComponent.cs +++ b/Content.Server/Imperial/Medieval/Cult/Bloodspells/Materials/BloodMaterialComponent.cs @@ -1,8 +1,5 @@ -namespace Content.Server.Imperial.Medieval.Cult.Bloodspells.mateials; +namespace Content.Server.Imperial.Medieval.Cult.Bloodspells.Materials; -/// -/// This is used for... -/// [RegisterComponent] public sealed partial class BloodMaterialComponent : Component { diff --git a/Content.Server/Imperial/Medieval/Cult/Bloodspells/MedievalBlodedComponent.cs b/Content.Server/Imperial/Medieval/Cult/Bloodspells/MedievalBlodedComponent.cs deleted file mode 100644 index 94ba93c16dc..00000000000 --- a/Content.Server/Imperial/Medieval/Cult/Bloodspells/MedievalBlodedComponent.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Content.Server.Imperial.Medieval.Cult.Bloodspells; - -/// -/// This is used for... -/// -[RegisterComponent] -public sealed partial class MedievalBlodedComponent : Component -{ - [DataField("blood")] - [ViewVariables(VVAccess.ReadWrite)] - public int Blood; -} diff --git a/Content.Server/Imperial/Medieval/Cult/Bloodspells/MedievalBloodedComponent.cs b/Content.Server/Imperial/Medieval/Cult/Bloodspells/MedievalBloodedComponent.cs new file mode 100644 index 00000000000..2418e38e192 --- /dev/null +++ b/Content.Server/Imperial/Medieval/Cult/Bloodspells/MedievalBloodedComponent.cs @@ -0,0 +1,8 @@ +namespace Content.Server.Imperial.Medieval.Cult.Bloodspells; + +[RegisterComponent] +public sealed partial class MedievalBloodedComponent : Component +{ + [DataField("blood"), ViewVariables(VVAccess.ReadWrite)] + public int Blood; +} diff --git a/Content.Server/Imperial/Medieval/Cult/Bloodspells/light/DeathCurseSystem.cs b/Content.Server/Imperial/Medieval/Cult/Bloodspells/light/DeathCurseSystem.cs index 0a0ae3d6894..86a05bd1b09 100644 --- a/Content.Server/Imperial/Medieval/Cult/Bloodspells/light/DeathCurseSystem.cs +++ b/Content.Server/Imperial/Medieval/Cult/Bloodspells/light/DeathCurseSystem.cs @@ -9,11 +9,8 @@ using Content.Shared.Popups; using Robust.Shared.Timing; -namespace Content.Server.Imperial.Medieval.Cult.Bloodspells.light; +namespace Content.Server.Imperial.Medieval.Cult.Bloodspells.Light; -/// -/// This handles... -/// public sealed class DeathCurseSystem : EntitySystem { [Dependency] private readonly IGameTiming _timing = default!; @@ -21,7 +18,6 @@ public sealed class DeathCurseSystem : EntitySystem [Dependency] private readonly SharedPopupSystem _popupSystem = default!; [Dependency] private readonly AlertsSystem _alertsSystem = default!; - /// private TimeSpan _nextCheckTime; private TimeSpan _nextCheckTimePopup; diff --git a/Content.Server/Imperial/Medieval/Cult/CultMemberComponent.cs b/Content.Server/Imperial/Medieval/Cult/CultMemberComponent.cs index 393277822c5..6339840bb89 100644 --- a/Content.Server/Imperial/Medieval/Cult/CultMemberComponent.cs +++ b/Content.Server/Imperial/Medieval/Cult/CultMemberComponent.cs @@ -3,7 +3,6 @@ using Robust.Shared.Prototypes; using System.Collections.Generic; using System; -using System.Linq; using Content.Shared.Alert; namespace Content.Server.Cult.Components; @@ -12,17 +11,17 @@ namespace Content.Server.Cult.Components; public sealed partial class CultMemberComponent : Component { [DataField] - public EntityUid? parent; + public EntityUid? Parent; [ViewVariables(VVAccess.ReadWrite)] [DataField] public DamageSpecifier Damage = new() { DamageDict = new() - { - { "Poison", 10 }, - { "Asphyxiation", 10} - } + { + { "Poison", 10 }, + { "Asphyxiation", 10 } + } }; [ViewVariables(VVAccess.ReadWrite)] @@ -30,7 +29,7 @@ public sealed partial class CultMemberComponent : Component public Queue<(string message, TimeSpan time)> LastSpokenMessages = new(); [DataField] - public bool DeathCusre = true; + public bool DeathCurse = true; [DataField] public ProtoId DeathCurseAlert = "CultDeathCurse"; diff --git a/Content.Server/Imperial/Medieval/Cult/CultSystem.cs b/Content.Server/Imperial/Medieval/Cult/CultSystem.cs index 0699bf1137b..cb64414fb21 100644 --- a/Content.Server/Imperial/Medieval/Cult/CultSystem.cs +++ b/Content.Server/Imperial/Medieval/Cult/CultSystem.cs @@ -27,7 +27,7 @@ using Content.Server.Construction.Completions; using Content.Server.Construction.Conditions; using Content.Server.Imperial.Medieval.Cult.Bloodspells; -using Content.Server.Imperial.Medieval.Cult.Bloodspells.mateials; +using Content.Server.Imperial.Medieval.Cult.Bloodspells.Materials; using Content.Shared.Alert; using Content.Shared.Inventory; using Content.Shared.Mobs.Components; @@ -249,7 +249,7 @@ public override void Update(float frameTime) if (picture.CollegiumUnlocked) continue; foreach (var cultist in EntityManager.EntityQuery()) { - if (TryComp(cultist.parent, out var blocker)) + if (TryComp(cultist.Parent, out var blocker)) { switch (blocker.Sector) { @@ -332,7 +332,7 @@ private void OnChangeParent(EntityUid uid, CultMemberComponent comp, ref MoveEve if (!args.ParentChanged) return; - comp.parent = newParent; + comp.Parent = newParent; } public void OnActivated(EntityUid uid, CultCheckPictureComponent comp, ActivateInWorldEvent args) { @@ -931,7 +931,7 @@ private bool CheckCrystals(EntityUid uid, CultCheckPictureComponent comp, int bl if (_itemSlotsSystem.TryGetSlot(slot.Item.Value, "Conductor" + i, out var container) && container.HasItem && container.Item != null) { - if (TryComp(container.Item.Value, out var bloodcomp)) + if (TryComp(container.Item.Value, out var bloodcomp)) { bloodcomp.Blood += bloodyCost * 3 + redCost; if (bloodcomp.Blood >= 10) @@ -945,13 +945,13 @@ private bool CheckCrystals(EntityUid uid, CultCheckPictureComponent comp, int bl } else { - AddComp(container.Item.Value); + EnsureComp(container.Item.Value); } } } - if (TryComp(slot.Item.Value, out var blodcomp)) + if (TryComp(slot.Item.Value, out var blodcomp)) { blodcomp.Blood += bloodyCost * 3 + redCost; if (blodcomp.Blood >= 10) @@ -967,7 +967,7 @@ private bool CheckCrystals(EntityUid uid, CultCheckPictureComponent comp, int bl } else { - AddComp(slot.Item.Value); + EnsureComp(slot.Item.Value); } comp.BloodyCrystall -= bloodyCost; comp.RedCrystall -= redCost; diff --git a/Content.Server/Imperial/Medieval/MedievalRevive/MedievalReviveSystem.cs b/Content.Server/Imperial/Medieval/MedievalRevive/MedievalReviveSystem.cs index 94d2d660186..3523b867a88 100644 --- a/Content.Server/Imperial/Medieval/MedievalRevive/MedievalReviveSystem.cs +++ b/Content.Server/Imperial/Medieval/MedievalRevive/MedievalReviveSystem.cs @@ -1,167 +1,111 @@ using System.Linq; -using System.Numerics; using Content.Server.Administration.Logs; -using Content.Server.Chat.Managers; -using Content.Server.Chat.Systems; -using Content.Server.GameTicking; using Content.Server.Ghost.Components; using Content.Server.MagicBarrier.Components; using Content.Server.Mind; -using Content.Server.Roles.Jobs; -using Content.Shared.Actions; -using Content.Shared.CCVar; -using Content.Shared.Coordinates; -using Content.Shared.Damage; -using Content.Shared.Damage.Prototypes; using Content.Shared.Database; -using Content.Shared.Examine; -using Content.Shared.Eye; -using Content.Shared.FixedPoint; -using Content.Shared.Follower; using Content.Shared.Ghost; using Content.Shared.Imperial.Medieval.CCVar; using Content.Shared.Imperial.Medieval.MedievalReviveSpawner; using Content.Shared.Imperial.Medieval.Revive; using Content.Shared.Mind; using Content.Shared.Mind.Components; -using Content.Shared.Mobs; -using Content.Shared.Mobs.Components; -using Content.Shared.Mobs.Systems; -using Content.Shared.Movement.Events; -using Content.Shared.Movement.Systems; -using Content.Shared.NameModifier.EntitySystems; -using Content.Shared.Players; -using Content.Shared.Popups; -using Content.Shared.Storage.Components; -using Content.Shared.Tag; -using Content.Shared.Warps; using Robust.Server.GameObjects; using Robust.Shared.Configuration; -using Robust.Shared.Map; -using Robust.Shared.Network; -using Robust.Shared.Physics.Components; -using Robust.Shared.Physics.Systems; using Robust.Shared.Player; -using Robust.Shared.Prototypes; using Robust.Shared.Random; -using Robust.Shared.Timing; using Robust.Shared.Utility; -namespace Content.Server.Imperial.Medieval.Revive +namespace Content.Server.Imperial.Medieval.Revive; + +public sealed class MedievalReviveSystem : EntitySystem { - public sealed class MedievalReviveSystem : EntitySystem + [Dependency] private readonly MindSystem _minds = default!; + [Dependency] private readonly TransformSystem _transform = default!; + [Dependency] private readonly IConfigurationManager _cfg = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly IAdminLogManager _adminLog = default!; + + private const int MaxRevives = 3; + + public override void Initialize() { - [Dependency] private readonly MindSystem _minds = default!; - [Dependency] private readonly TransformSystem _transformSystem = default!; - [Dependency] private readonly IRobustRandom _random = default!; - [Dependency] private readonly IConfigurationManager _cfg = default!; - [Dependency] private readonly SharedPopupSystem _popup = default!; - [Dependency] private readonly IAdminLogManager _adminlog = default!; + SubscribeNetworkEvent(OnGhostReviveRequest); + SubscribeNetworkEvent(OnReviveCountRequest); + } - private const int MaxRevives = 3; + private void OnGhostReviveRequest(GhostReviveRequestEvent ev, EntitySessionEventArgs args) + { + if (!_cfg.GetCVar(MedievalCCVars.GhostRevive)) + return; + var session = args.SenderSession; + var userId = session.UserId; - public override void Initialize() + if (!EntityQuery().TryFirstOrDefault(out var barrier)) { - base.Initialize(); - SubscribeNetworkEvent(OnGhostReviveRequest); - SubscribeNetworkEvent(OnReviveCountRequest); + _adminLog.Add(LogType.Action, LogImpact.Low, $"Игрок {session.Name} попытался возродиться, но барьер не найден"); + return; } - private void OnGhostReviveRequest(GhostReviveRequestEvent msg, EntitySessionEventArgs args) - { - var revivesOn = _cfg.GetCVar(MedievalCCVars.GhostRevive); - if (!revivesOn) - return; - - var player = args.SenderSession; - var playerUid = player.UserId; - if (!EntityQuery().TryFirstOrDefault(out var barrier)) - { - _adminlog.Add(LogType.Action, LogImpact.Low, $"Игрок {player.Name} попытался возродиться, но барьер не найден"); - return; - } - - if (!barrier.ReviveCount.ContainsKey(playerUid)) - barrier.ReviveCount[playerUid] = 0; - - if (barrier.ReviveCount[playerUid] >= MaxRevives) - { - _adminlog.Add(LogType.Action, LogImpact.High, $"Игрок {player.Name} попытался возродиться, но у него уже {MaxRevives} возрождений"); - return; - } - if (!_minds.TryGetNetEntity(player.GetMind(), out var netEntity)) - { - _adminlog.Add(LogType.Action, LogImpact.High, $"Разум {player.GetMind()} не имеет значения"); - return; - } - if (EntityManager.GetEntity(netEntity) == null) - { - _adminlog.Add(LogType.Action, LogImpact.High, $"Сущность {netEntity} не имеет значения"); - return; - } - - var playerMind = EntityManager.GetEntity(netEntity); - - if (!playerMind.HasValue) - { - _adminlog.Add(LogType.Action, LogImpact.High, $"Разум {playerMind} не имеет значения"); - return; - } - - var playerEntity = EntityManager.GetComponent(playerMind.Value).CurrentEntity; + if (!barrier.ReviveCount.TryGetValue(userId, out var reviveCount)) + reviveCount = 0; + if (reviveCount >= MaxRevives) + { + _adminLog.Add(LogType.Action, LogImpact.High, $"Игрок {session.Name} превысил лимит возрождений ({MaxRevives})"); + return; + } - if (!HasComp(playerEntity)) - { - _adminlog.Add(LogType.Action, LogImpact.High, $"Обнаружена подозрительная активность, разум {netEntity} в теле {playerEntity} пытался возродится, либо софт либо баг менюшки"); - return; - } + if (!_minds.TryGetMind(userId, out _, out var oldMind)) + { + _adminLog.Add(LogType.Action, LogImpact.High, $"Игрок {session.Name} не имеет разума"); + return; + } - var reviveQuery = EntityManager.EntityQuery(); + var currentEntity = oldMind.CurrentEntity; + if (currentEntity == null || !HasComp(currentEntity)) + { + _adminLog.Add(LogType.Action, LogImpact.High, $"Игрок {session.Name} попытался возродиться не находясь в состоянии призрака"); + return; + } - if (reviveQuery.Count() == 0) - return; + var spawnerQuery = EntityQuery(); + if (!spawnerQuery.Any()) + return; - var reviveList = reviveQuery.ToList(); + var spawner = _random.Pick(spawnerQuery.ToList()); + var spawnerCoords = _transform.GetMoverCoordinates(spawner.Owner); + var mob = Spawn(spawner.Prototype, spawnerCoords); - _random.Shuffle(reviveList); - var component = reviveList.ElementAt(0); - var spawner = component.Owner; + _transform.AttachToGridOrMap(mob); + EnsureComp(mob); - var mob = Spawn(component.Prototype, Transform(spawner).Coordinates); - _transformSystem.AttachToGridOrMap(mob); + if (!oldMind.IsVisitingEntity) + _minds.WipeMind(session); - EnsureComp(mob); + var newMind = _minds.CreateMind(userId, Comp(mob).EntityName); - if (_minds.TryGetMind(player.UserId, out _, out var mind) && !mind.IsVisitingEntity) - _minds.WipeMind(player); + _minds.SetUserId(newMind, userId); + _minds.TransferTo(newMind, mob); - var newMind = _minds.CreateMind(player.UserId, - Comp(mob).EntityName); + barrier.ReviveCount[userId] = reviveCount + 1; + } - _minds.SetUserId(newMind, player.UserId); - _minds.TransferTo(newMind, mob); - barrier.ReviveCount[playerUid]++; - } + private void OnReviveCountRequest(ReviveCountRequestEvent _, EntitySessionEventArgs args) + { + var session = args.SenderSession; + var userId = session.UserId; - private void OnReviveCountRequest(ReviveCountRequestEvent msg, EntitySessionEventArgs args) + if (!EntityQuery().TryFirstOrDefault(out var barrier)) { - var player = args.SenderSession; - var playerUid = player.UserId; - if (!EntityQuery().TryFirstOrDefault(out var barrier)) - { - _adminlog.Add(LogType.Action, - LogImpact.High, - $"Player {player.Name} tried to revive but magic barrier was not found"); - return; - } - - if (!barrier.ReviveCount.ContainsKey(playerUid)) - barrier.ReviveCount[playerUid] = 0; - - // Отправляем ответ - RaiseNetworkEvent(new ReviveCountResponseEvent(barrier.ReviveCount[playerUid], MaxRevives), args.SenderSession); + _adminLog.Add(LogType.Action, LogImpact.High, $"Игрок {session.Name} запросил количество возрождений, но барьер не найден"); + return; } + + if (!barrier.ReviveCount.TryGetValue(userId, out var reviveCount)) + reviveCount = 0; + + RaiseNetworkEvent(new ReviveCountResponseEvent(reviveCount, MaxRevives), session); } } diff --git a/Content.Shared/Imperial/Medieval/ChargedAttack/ChargedAttackSystem.cs b/Content.Shared/Imperial/Medieval/ChargedAttack/ChargedAttackSystem.cs index 524f2e5faf3..1111046ea09 100644 --- a/Content.Shared/Imperial/Medieval/ChargedAttack/ChargedAttackSystem.cs +++ b/Content.Shared/Imperial/Medieval/ChargedAttack/ChargedAttackSystem.cs @@ -4,11 +4,14 @@ using Content.Shared.Damage.Systems; using Content.Shared.Hands.EntitySystems; using Content.Shared.Humanoid; +using Content.Shared.Hands; +using Content.Shared.Hands.Components; using Content.Shared.Interaction.Events; using Content.Shared.Mobs.Systems; using Content.Shared.Movement.Systems; using Content.Shared.Weapons.Melee; using Content.Shared.Weapons.Melee.Events; +using Robust.Shared.Containers; using Robust.Shared.Map; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; @@ -40,6 +43,41 @@ public override void Initialize() SubscribeLocalEvent(OnHit); SubscribeLocalEvent(OnStaminaHit); + SubscribeLocalEvent(OnDropped); + SubscribeLocalEvent(OnUnequipped); + SubscribeLocalEvent(OnInsertedIntoContainer); + } + + private void OnDropped(EntityUid weapon, ChargedAttackComponent charged, DroppedEvent args) + { + if (!charged.CurrentAttacking) + return; + + StopAttacking(weapon, charged, args.User); + } + + private void OnUnequipped(EntityUid weapon, ChargedAttackComponent charged, GotUnequippedHandEvent args) + { + if (!charged.CurrentAttacking) + return; + + StopAttacking(weapon, charged, args.User); + } + + private void OnInsertedIntoContainer(EntityUid weapon, ChargedAttackComponent charged, EntInsertedIntoContainerMessage args) + { + if (!charged.CurrentAttacking) + return; + + var user = args.Container.Owner; + + if (TryComp(user, out var xform) && xform.ParentUid.IsValid()) + { + if (HasComp(xform.ParentUid)) + user = xform.ParentUid; + } + + StopAttacking(weapon, charged, user); } private void OnHit(EntityUid weapon, ChargedAttackComponent charged, MeleeHitEvent args) @@ -113,7 +151,9 @@ private void OnStart(ChargedAttackStart msg, EntitySessionEventArgs args) return; var weaponUid = GetEntity(msg.Weapon); - if (!TryComp(weaponUid, out var charged)) return; + if (!TryComp(weaponUid, out var charged)) + return; + charged.AttackStart = _timing.CurTime; charged.CurrentAttacking = true; Dirty(weaponUid, charged); @@ -130,8 +170,12 @@ private void OnEnd(ChargedAttackEnd msg, EntitySessionEventArgs args) var weaponUid = GetEntity(msg.Weapon); var attackTime = msg.AttackTime; - if (!TryComp(weaponUid, out var charged)) return; - if (!TryComp(weaponUid, out var weapon)) return; + if (!TryComp(weaponUid, out var charged)) + return; + + if (!TryComp(weaponUid, out var weapon)) + return; + ChargedAttack(user, coordinates, (weaponUid, weapon), charged, attackTime, args.SenderSession); StopAttacking(weaponUid, charged, user); } diff --git a/Content.Shared/Imperial/Medieval/Cult/BloodSpellPrototype.cs b/Content.Shared/Imperial/Medieval/Cult/BloodSpellPrototype.cs new file mode 100644 index 00000000000..12c6e781469 --- /dev/null +++ b/Content.Shared/Imperial/Medieval/Cult/BloodSpellPrototype.cs @@ -0,0 +1,51 @@ +using Robust.Shared.Prototypes; + +namespace Content.Shared.Imperial.Medieval.Cult; + +[Prototype] +public sealed partial class BloodSpellPrototype : IPrototype +{ + [IdDataField] + public string ID { get; private set; } = default!; + + [DataField(required: true)] + public List Incantation = new(); + + [DataField(required: true)] + public BloodSpellType SpellType = BloodSpellType.ItemUpgrade; + + [DataField] + public string? RequiredMaterial; + + [DataField] + public int RequiredMaterialCount = 5; + + [DataField] + public EntProtoId? SpawnProto; + + [DataField] + public EntProtoId? RequiredHeldItem; + + [DataField] + public EntProtoId? ReplacementItem; + + [DataField] + public string? EquipmentSlot; + + [DataField] + public bool ReplaceEquipment; + + [DataField("successMessage")] + public string? SuccessMessage; + + [DataField] + public string? FailureMessage; +} + +public enum BloodSpellType +{ + ItemUpgrade, + CraftItem, + CraftArmor, + DeathCurse, +} diff --git a/Resources/Locale/ru-RU/Imperial/Medieval/Cult/cult.ftl b/Resources/Locale/ru-RU/Imperial/Medieval/Cult/cult.ftl new file mode 100644 index 00000000000..06c4fb1d87e --- /dev/null +++ b/Resources/Locale/ru-RU/Imperial/Medieval/Cult/cult.ftl @@ -0,0 +1,12 @@ +cult-spell-too-fast = Ты ощущаешь, что слова были произнесены слишком поспешно и не напитались магией +cult-spell-too-slow = Ты ощущаешь, что слова утратили силу, прежде чем завершилось заклинание +cult-spell-incorrect = Ты ощущаешь искажение в произнесённых словах + +cult-spell-insufficient-materials = Недостаточно ресурсов для ритуала + +cult-spell-need-holy-scripture = Ты должен держать в руке святое писание +cult-spell-wrong-item = В твоей руке должно быть святое писание, а не { $item } +cult-spell-book-upgraded = Книга пропитывается силой крови + +cult-spell-death-curse-activated = Да падёт проклятие на того, кто поднимет на меня руку +cult-spell-death-curse-already-active = Ты ощущаешь, что проклятие уже действует diff --git a/Resources/Prototypes/Imperial/Medieval/Cult/blood_spells.yml b/Resources/Prototypes/Imperial/Medieval/Cult/blood_spells.yml new file mode 100644 index 00000000000..a68ededc495 --- /dev/null +++ b/Resources/Prototypes/Imperial/Medieval/Cult/blood_spells.yml @@ -0,0 +1,85 @@ +- type: bloodSpell + id: SpellBookUpgrade + incantation: + - Ave + - The + - Truth + spellType: ItemUpgrade + requiredHeldItem: MedievalBookCultGuide + replacementItem: MedievalBookCultGuideUnlocked + successMessage: cult-spell-book-upgraded + failureMessage: cult-spell-need-holy-scripture + +- type: bloodSpell + id: SpellCraftArmorIron + incantation: + - Ave + - The + - Bronus + spellType: CraftArmor + requiredMaterial: BloodIron + requiredMaterialCount: 5 + spawnProto: MedievalClothingOuterArmorCultUp + equipmentSlot: outerClothing + replaceEquipment: true + failureMessage: cult-spell-insufficient-materials + +- type: bloodSpell + id: SpellCraftSpear + incantation: + - Ave + - The + - Vilkus + spellType: CraftItem + requiredMaterial: BloodIron + requiredMaterialCount: 5 + spawnProto: MedievalSpearCult + failureMessage: cult-spell-insufficient-materials + +- type: bloodSpell + id: SpellCraftYatagan + incantation: + - Ave + - The + - Knatus + spellType: CraftItem + requiredMaterial: BloodIron + requiredMaterialCount: 5 + spawnProto: MedievalCultYatagan + failureMessage: cult-spell-insufficient-materials + +- type: bloodSpell + id: SpellCraftSekir + incantation: + - Ave + - The + - Sekir + spellType: CraftItem + requiredMaterial: BloodIron + requiredMaterialCount: 5 + spawnProto: MedievalIronSekirCult + failureMessage: cult-spell-insufficient-materials + +- type: bloodSpell + id: SpellCraftArmorMana + incantation: + - Ave + - The + - Magical + spellType: CraftArmor + requiredMaterial: BloodLeather + requiredMaterialCount: 5 + spawnProto: MedievalClothingOuterArmorCultMana + equipmentSlot: outerClothing + replaceEquipment: true + failureMessage: cult-spell-insufficient-materials + +- type: bloodSpell + id: SpellDeathCurse + incantation: + - Katariemai + - Opoion + - Me chtypisei + spellType: DeathCurse + successMessage: cult-spell-death-curse-activated + failureMessage: cult-spell-death-curse-already-active diff --git a/Resources/Prototypes/Imperial/Medieval/cult.yml b/Resources/Prototypes/Imperial/Medieval/Cult/cult.yml similarity index 99% rename from Resources/Prototypes/Imperial/Medieval/cult.yml rename to Resources/Prototypes/Imperial/Medieval/Cult/cult.yml index ff1154fd092..1fdc082d939 100644 --- a/Resources/Prototypes/Imperial/Medieval/cult.yml +++ b/Resources/Prototypes/Imperial/Medieval/Cult/cult.yml @@ -423,7 +423,7 @@ - type: entity parent: BaseItem name: книга ритуалов культа истины - id: MedievalBookCultGuide2 + id: MedievalBookCultGuideUnlocked components: - type: Sprite sprite: Imperial/Medieval/Misc/cult.rsi diff --git a/Resources/Prototypes/Imperial/Medieval/decor.yml b/Resources/Prototypes/Imperial/Medieval/decor.yml index 9dab0528e5e..468d104fce3 100644 --- a/Resources/Prototypes/Imperial/Medieval/decor.yml +++ b/Resources/Prototypes/Imperial/Medieval/decor.yml @@ -3889,7 +3889,6 @@ color: red castShadows: false - - type: entity id: MedievalFlagCaptureBlueGold parent: BaseStructure @@ -3897,7 +3896,7 @@ description: A banner displaying the Nanotrasen logo. It looks rather cheap. components: - type: Sprite - drawdepth: Overdoors + drawdepth: 3 sprite: Imperial/Medieval/Decor/medieval_banner.rsi state: banner_blul_gold - type: MedievalFactionFlagChecker @@ -3918,20 +3917,6 @@ behaviors: - !type:DoActsBehavior acts: [ "Destruction" ] - - type: Fixtures - fixtures: - fix1: - shape: - !type:PhysShapeCircle - radius: 0.45 - density: 190 - mask: - - MachineMask - layer: - - Opaque - - MidImpassable - - HighImpassable - - BulletImpassable - type: entity id: MedievalFlagCaptureRedGold @@ -3940,7 +3925,7 @@ description: A banner displaying the Nanotrasen logo. It looks rather cheap. components: - type: Sprite - drawdepth: Overdoors + drawdepth: 3 sprite: Imperial/Medieval/Decor/medieval_banner.rsi state: banner_red_gold - type: MedievalFactionFlagChecker @@ -3968,13 +3953,6 @@ !type:PhysShapeCircle radius: 0.45 density: 190 - mask: - - MachineMask - layer: - - Opaque - - MidImpassable - - HighImpassable - - BulletImpassable - type: entity id: MedievalDecorPerekatiPole