diff --git a/Content.Server/Imperial/Vampire/VampireSystem.Abilities.cs b/Content.Server/Imperial/Vampire/VampireSystem.Abilities.cs index e6ed482c40..71a04cb845 100644 --- a/Content.Server/Imperial/Vampire/VampireSystem.Abilities.cs +++ b/Content.Server/Imperial/Vampire/VampireSystem.Abilities.cs @@ -176,7 +176,8 @@ private void OnStartSleep(VampireSleepEvent args) BreakOnMove = true, BreakOnDamage = true, NeedHand = false, - BlockDuplicate = true + BlockDuplicate = true, + Hidden = true }; _doAfter.TryStartDoAfter(doAfterArgs); @@ -265,14 +266,6 @@ private void OnTurn(VampireTurnEvent args) return; } - if (vamp.GhoulQuantity < args.NecessaryGhoulQuantity) - { - _popup.PopupEntity(Loc.GetString("vampire-popup-ghoul-quantity", ("quantity", args.NecessaryGhoulQuantity - vamp.GhoulQuantity)), - args.Performer, args.Performer, PopupType.Medium); - - return; - } - switch (vamp.SelectedSubgroup) { case VampireAbilityType.Hemomancer: @@ -310,10 +303,8 @@ private void OnTurn(VampireTurnEvent args) args.Handled = true; } - public override void Update(float frameTime) + public void AbilitiesUpdate() { - base.Update(frameTime); - var queryVampBat = EntityQueryEnumerator(); while (queryVampBat.MoveNext(out var uid, out var vamp)) { diff --git a/Content.Server/Imperial/Vampire/VampireSystem.Ghoul.cs b/Content.Server/Imperial/Vampire/VampireSystem.Ghoul.cs index c7f25b0a83..21c21a2549 100644 --- a/Content.Server/Imperial/Vampire/VampireSystem.Ghoul.cs +++ b/Content.Server/Imperial/Vampire/VampireSystem.Ghoul.cs @@ -11,8 +11,6 @@ using Content.Shared.Interaction; using Content.Shared.Radio.Components; using Content.Shared.Radio; -using Robust.Shared.Player; -using Content.Shared.Mind.Components; namespace Content.Server.Imperial.Vampire; @@ -23,13 +21,8 @@ private void OnGetDrinkingGhoul(EntityUid uid, GhoulComponent comp, GetVerbsEven if (!args.CanAccess || !args.CanInteract || uid == args.Target || !_mobState.IsAlive(args.Target)) return; - // если у цели нет крови/разума, кнопки не добавляем - if (!HasComp(args.Target) || !HasComp(args.Target) - || !HasComp(args.Target)) - return; - // верб для питья крови - if (!HasComp(args.Target) && !HasComp(args.Target)) + if (!HasComp(args.Target) && !HasComp(args.Target) && HasComp(args.Target)) { var verbDrinkBloodGhoul = new InnateVerb { diff --git a/Content.Server/Imperial/Vampire/VampireSystem.cs b/Content.Server/Imperial/Vampire/VampireSystem.cs index 9f20e2953f..85f516256c 100644 --- a/Content.Server/Imperial/Vampire/VampireSystem.cs +++ b/Content.Server/Imperial/Vampire/VampireSystem.cs @@ -25,6 +25,8 @@ using Content.Shared.Mindshield.Components; using Content.Shared.Mind.Components; using Content.Shared.Mobs; +using Content.Server.Bible.Components; +using Content.Shared.Alert; using System.Runtime.CompilerServices; using Content.Server.Body; using System.Linq; @@ -50,6 +52,7 @@ public sealed partial class VampireSystem : EntitySystem [Dependency] private readonly MobStateSystem _mobState = default!; [Dependency] private readonly AudioSystem _audio = default!; [Dependency] private readonly SharedTransformSystem _transformSystem = default!; + [Dependency] private readonly AlertsSystem _alert = default!; [Dependency] private readonly VisualBodySystem _visualBodySystem = default!; @@ -80,14 +83,10 @@ private void OnGetVerbsCombined(EntityUid uid, VampireComponent vamp, GetVerbsEv || !_mobState.IsAlive(args.Target)) return; - // если у цели нет крови/разума, кнопки не добавляем - if (!HasComp(args.Target) || !HasComp(args.Target) - || !HasComp(args.Target)) - return; - // верб для превращения цели в упыря - if (!HasComp(args.Target) && !HasComp(args.Target) - && !HasComp(args.Target) && !_statusEffects.HasStatusEffect(uid, vamp.CooldownStatusEffectAppealGhouls)) + if (!HasComp(args.Target) && !HasComp(args.Target) && HasComp(args.Target) + && !HasComp(args.Target) && !_statusEffects.HasStatusEffect(uid, vamp.CooldownStatusEffectAppealGhouls) + && HasComp(args.Target)) { var verbConvert = new InnateVerb { @@ -101,7 +100,7 @@ private void OnGetVerbsCombined(EntityUid uid, VampireComponent vamp, GetVerbsEv } // верб для питья крови - if (!HasComp(args.Target) && !HasComp(args.Target)) + if (!HasComp(args.Target) && !HasComp(args.Target) && HasComp(args.Target)) { var verbDrinkBlood = new InnateVerb { @@ -135,6 +134,12 @@ private void StartConversion(EntityUid vampire, EntityUid target) if (!TryComp(vampire, out var vamp)) return; + if (vamp.GhoulQuantity == vamp.MaxNumberGhouls) + { + _popup.PopupEntity(Loc.GetString("vampire-popup-max-number-ghouls"), vampire, vampire, PopupType.Medium); + return; + } + _popup.PopupEntity(Loc.GetString("vampire-verb-envelope-vampire-transform", ("target", MetaData(target).EntityName)), vampire, vampire, PopupType.Medium); @@ -208,14 +213,34 @@ private void DrinkingComplete(EntityUid drinker, EntityUid target, float amount) // вычисляем текущее количество крови float currentBlood = vamp != null ? vamp.CritThreshold - vamp.BloodDamage : ghoul!.CritThreshold - ghoul.BloodDamage; - if (vamp != null && currentBlood >= 100) + if (currentBlood >= 100 || !HasComp(target) || !HasComp(target)) { - // мы просто засчитываем эту кровь в TotalDrunk, но BloodDamage не понижаем - vamp.TotalDrunk += amount; - _audio.PlayPvs(vamp.DrinkSound, drinker); - - damage.DamageDict["Bloodloss"] = FixedPoint2.New(amount * 2); - _damage.TryChangeDamage(target, damage); + if (vamp != null) + { + // мы просто засчитываем эту кровь в TotalDrunk, но BloodDamage не понижаем + if (currentBlood >= 100 && HasComp(target) && HasComp(target)) + { + vamp.TotalDrunk += amount; + _vampireSystem.SetBloodCounterAlert(drinker, vamp); + } + // мы просто понижаем BloodDamage, но в TotalDrunk не засчитываем + else if (!HasComp(target) || !HasComp(target)) + { + if (currentBlood >= 100) + { + _popup.PopupEntity(Loc.GetString("vampire-popup-target-no-mind-full"), drinker, drinker, PopupType.Medium); + return; + } + + vamp.BloodDamage = Math.Max(vamp.BloodDamage - amount / 2, 0); + _vampireSystem.SetBloodAlert(drinker, vamp); + _popup.PopupEntity(Loc.GetString("vampire-popup-target-no-mind"), drinker, drinker, PopupType.Medium); + } + + _audio.PlayPvs(vamp.DrinkSound, drinker); + + damage.DamageDict["Bloodloss"] = FixedPoint2.New(amount); + _damage.TryChangeDamage(target, damage); var eui = new VampireRequestedEui(drinker, EntityManager, _actions, _vampireSystem, _prototypeManager); eui.GrantAbilities(drinker, vamp.SelectedSubgroup); @@ -223,23 +248,35 @@ private void DrinkingComplete(EntityUid drinker, EntityUid target, float amount) // после того, как вампир выпивает кровь его глаза становятся красными TrySetEntityEyeColor(drinker, Color.Red); - if (_mobState.IsAlive(target)) - StartDrinking(drinker, target); + if (_mobState.IsAlive(target)) + StartDrinking(drinker, target); - return; + return; + } } // увеличиваем количество крови if (vamp != null) { vamp.BloodDamage = Math.Max(vamp.BloodDamage - amount, 0f); + _vampireSystem.SetBloodCounterAlert(drinker, vamp); _vampireSystem.SetBloodAlert(drinker, vamp); vamp.TotalDrunk += amount; _audio.PlayPvs(vamp.DrinkSound, drinker); } else if (ghoul != null) { - ghoul.BloodDamage = Math.Max(ghoul.BloodDamage - amount, 0f); + if (ghoul.BloodDamage - amount < 0) + { + _popup.PopupEntity(Loc.GetString("vampire-drinking-full-blood"), drinker, drinker, PopupType.Medium); + return; + } + + if (!HasComp(target) || !HasComp(target)) + ghoul.BloodDamage = Math.Max(ghoul.BloodDamage - amount / 2, 0); + else + ghoul.BloodDamage = Math.Max(ghoul.BloodDamage - amount, 0f); + _vampireSystem.SetGhoulBloodAlert(drinker, ghoul); _audio.PlayPvs(ghoul.DrinkSound, drinker); } @@ -313,6 +350,41 @@ private void OnSelectingSubgroup(VampireSelectingSubgroupEvent args) _eui.OpenEui(eui, actor.PlayerSession); } + public override void Update(float frameTime) + { + base.Update(frameTime); + + BaseUpdate(frameTime); + AbilitiesUpdate(); + } + + public void BaseUpdate(float frameTime) + { + var querySearch = EntityQueryEnumerator(); + while (querySearch.MoveNext(out var uid, out var comp)) + { + comp.UpdateDelay += frameTime; + var priests = _lookup.GetEntitiesInRange(Transform(uid).Coordinates, 7).FirstOrNull(); + + if (priests == null || _mobState.IsDead(priests.Value)) + { + _alert.ClearAlert(uid, comp.AdjacentChaplainAlert); + comp.UpdateDelay = 0f; + continue; + } + + if (comp.UpdateDelay < 1) + continue; + + _damage.TryChangeDamage(uid, comp.DivineDamage); + _audio.PlayPvs(comp.DivineDamageSound, uid); + _popup.PopupEntity(Loc.GetString("vampire-popup-chaplain-closely"), uid, uid, PopupType.Medium); + _alert.ShowAlert(uid, comp.AdjacentChaplainAlert); + + comp.UpdateDelay = 0; + } + } + private bool TrySetEntityEyeColor(EntityUid uid, Color eyeColor) { if (!_visualBodySystem.TryGatherMarkingsData(uid, null, out var profiles, out _, out var markings)) return false; diff --git a/Content.Shared/Imperial/Vampire/Components/GhoulComponent.cs b/Content.Shared/Imperial/Vampire/Components/GhoulComponent.cs index 1a96a3bfce..7d6de3cb6a 100644 --- a/Content.Shared/Imperial/Vampire/Components/GhoulComponent.cs +++ b/Content.Shared/Imperial/Vampire/Components/GhoulComponent.cs @@ -19,7 +19,7 @@ public sealed partial class GhoulComponent : Component /// Интервал между тиками потери крови /// [DataField] - public TimeSpan BloodDecayInterval = TimeSpan.FromSeconds(30); + public TimeSpan BloodDecayInterval = TimeSpan.FromSeconds(60); /// /// количество урона за каждый тик @@ -43,7 +43,7 @@ public sealed partial class GhoulComponent : Component /// количество выпитой крови за 1 тик /// [DataField("bloodPerTick")] - public float BloodPerTick = 1; + public float BloodPerTick = 3; /// /// сколько занимает излечение упыря diff --git a/Content.Shared/Imperial/Vampire/Components/VampireComponent.cs b/Content.Shared/Imperial/Vampire/Components/VampireComponent.cs index 11a8bd5583..c7be591d37 100644 --- a/Content.Shared/Imperial/Vampire/Components/VampireComponent.cs +++ b/Content.Shared/Imperial/Vampire/Components/VampireComponent.cs @@ -1,4 +1,6 @@ using Content.Shared.Alert; +using Content.Shared.Damage; +using Content.Shared.FixedPoint; using Content.Shared.StatusIcon; using Robust.Shared.Audio; using Robust.Shared.GameStates; @@ -91,7 +93,7 @@ public sealed partial class VampireComponent : Component /// количество выпитой крови за 1 тик /// [DataField("bloodPerTick")] - public float BloodPerTick = 1; + public float BloodPerTick = 3; /// /// кд между призывами катаны @@ -186,6 +188,32 @@ public sealed partial class VampireComponent : Component [DataField("bloodLossDisguiseIsActive")] public float BloodLossDisguiseIsActive = 1; + /// + /// время следующего тика потери крови + /// + public TimeSpan NextBloodDecay = TimeSpan.Zero; + + /// + /// Интервал между тиками потери крови + /// + [DataField] + public TimeSpan BloodDecayInterval = TimeSpan.FromSeconds(45); + + /// + /// количество урона за каждый тик + /// + [DataField] + public float BloodDecayAmount = 2f; + + [DataField] + public EntProtoId GhoulPuddleID = "VampirePuddle"; + + /// + /// длительность тряски при критическом состоянии + /// + [DataField] + public TimeSpan ShakingTime = TimeSpan.FromSeconds(5); + [DataField] public string VampirePuddleID = "VampirePuddle"; @@ -312,9 +340,37 @@ public sealed partial class VampireComponent : Component /// длительность cooldown на обращение в упырей /// [DataField("cooldownTimeAppealGhouls")] - public TimeSpan CooldownTimeAppealGhouls = TimeSpan.FromMinutes(1); + public TimeSpan CooldownTimeAppealGhouls = TimeSpan.FromMinutes(2.5f); [DataField] public string CooldownStatusEffectAppealGhouls = "AppealGhoulsCooldown"; + + [DataField] + public DamageSpecifier DivineDamage = new DamageSpecifier + { + DamageDict = new Dictionary + { + ["Heat"] = 2 + } + }; + + [DataField] + public SoundSpecifier DivineDamageSound = new SoundPathSpecifier("/Audio/Effects/lightburn.ogg") + { + Params = AudioParams.Default.WithVolume(3) + }; + + [AutoNetworkedField] + public float UpdateDelay; + + [DataField] + public ProtoId AdjacentChaplainAlert = "VampireAdjacentChaplainAlert"; + + /// + /// максимальное количество упырей, которое может иметь вампир + /// + [DataField] + public int MaxNumberGhouls = 5; + } } diff --git a/Content.Shared/Imperial/Vampire/Event/VampireActionEvent.cs b/Content.Shared/Imperial/Vampire/Event/VampireActionEvent.cs index 96a3162869..d16b5fce80 100644 --- a/Content.Shared/Imperial/Vampire/Event/VampireActionEvent.cs +++ b/Content.Shared/Imperial/Vampire/Event/VampireActionEvent.cs @@ -343,12 +343,6 @@ public sealed partial class VampireTurnEvent : InstantActionEvent { [DataField("costBlood")] public float CostBlood = 30; - - /// - /// необходимо иметь упырей для обращения - /// - [DataField("necessaryGhoulQuantity")] - public int NecessaryGhoulQuantity = 25; } public sealed partial class VampireSwordEvent : InstantActionEvent diff --git a/Content.Shared/Imperial/Vampire/SharedVampireSystem.cs b/Content.Shared/Imperial/Vampire/SharedVampireSystem.cs index 82e590f997..af9f8abb33 100644 --- a/Content.Shared/Imperial/Vampire/SharedVampireSystem.cs +++ b/Content.Shared/Imperial/Vampire/SharedVampireSystem.cs @@ -436,9 +436,50 @@ private void BaseUpdate() } } + var vampirelQuery = EntityQueryEnumerator(); + while (vampirelQuery.MoveNext(out var uid, out var comp)) + { + if (_mobStateSystem.IsDead(uid)) + continue; + + if (comp.NextBloodDecay == TimeSpan.Zero) + { + comp.NextBloodDecay = _gameTiming.CurTime + comp.BloodDecayInterval; + Dirty(uid, comp); + } + + if (_gameTiming.CurTime >= comp.NextBloodDecay) + { + // наносим урон каждые BloodDecayInterval секунд + DealBloodDamage(uid, comp.BloodDecayAmount, comp); + comp.NextBloodDecay = _gameTiming.CurTime + comp.BloodDecayInterval; + Dirty(uid, comp); + + // если урон больше количества крови, то применяем дебафы + if (comp.BloodDamage >= comp.CritThreshold) + { + if (TryComp(uid, out var stamina)) + { + var dmg = new DamageSpecifier(); + dmg.DamageDict["Bloodloss"] = FixedPoint2.New(30); + + _damage.TryChangeDamage(uid, dmg); + SpawnBloodPuddle(uid, comp.GhoulPuddleID); + _stamina.TakeStaminaDamage(uid, 70f, stamina); + + if (_net.IsServer) + _jitterSystem.DoJitter(uid, comp.ShakingTime, refresh: false, amplitude: 15f, frequency: 4f); + } + } + } + } + var ghoulQuery = EntityQueryEnumerator(); while (ghoulQuery.MoveNext(out var uid, out var comp)) { + if (_mobStateSystem.IsDead(uid)) + continue; + // заставляем упырей пить кровь if (comp.NextBloodDecay == TimeSpan.Zero) { diff --git a/Resources/Locale/ru-RU/Imperial/Vampire/vampire.ftl b/Resources/Locale/ru-RU/Imperial/Vampire/vampire.ftl index c15b4468db..dd63d3271d 100644 --- a/Resources/Locale/ru-RU/Imperial/Vampire/vampire.ftl +++ b/Resources/Locale/ru-RU/Imperial/Vampire/vampire.ftl @@ -10,39 +10,39 @@ vampire-subgroup-gargantua-button = Выбрать Gargantua vampire-selecting-window-subgroupHemomancer-text = {"["}bold]Кровавые щупальца[/bold]: Разблокируется на 100 крови. Из указанной точки вырываются щупальца, наносящие 15 урона и сваливающие жертву на землю. - {"["}bold]Воздушный побег[/bold]: Разблокируется на 200 крови. Призывает рой атакующих летучих мышей и превращает вампира в летучую мышь на 10 секунд. + {"["}bold]Воздушный побег[/bold]: Разблокируется на 100 крови. Призывает рой атакующих летучих мышей и превращает вампира в летучую мышь на 10 секунд. - {"["}bold]Кровавое перевоплощение[/bold]: Разблокируется на 300 крови. На 4 секунды превращает вас в кровь, позволяя проходить сквозь препятствия. + {"["}bold]Кровавое перевоплощение[/bold]: Разблокируется на 200 крови. На 4 секунды превращает вас в кровь, позволяя проходить сквозь препятствия. - {"["}bold]Гнев Носферату[/bold]: Разблокируется на 400 крови. На 25 секунд: в 2 раза больше урона, +50% скорости атаки, +50% скорости передвижения. + {"["}bold]Гнев Носферату[/bold]: Разблокируется на 350 крови. На 25 секунд: в 2 раза больше урона, +50% скорости атаки, +50% скорости передвижения. vampire-selecting-window-subgroupUmbrae-text = {"["}bold]Свобода[/bold]: Разблокируется на 100 крови. Разрывает наручники и увеличивает скорость в 1.5 раза на 10 секунд. - {"["}bold]Переключить режим невидимости[/bold]: Разблокируется на 200 крови. Делает вампира невидимым за счёт 2 ед. крови в секунду. Любая атака/урон прерывает эффект. + {"["}bold]Переключить режим невидимости[/bold]: Разблокируется на 100 крови. Делает вампира невидимым за счёт 2 ед. крови в секунду. Любая атака/урон прерывает эффект. - {"["}bold]Кровавый якорь[/bold]: Разблокируется на 300 крови. Создает якорь в точке активации. При повторном нажатии телепортирует к себе. Якорь исчезает через 2 минуты или после использования. + {"["}bold]Кровавый якорь[/bold]: Разблокируется на 200 крови. Создает якорь в точке активации. При повторном нажатии телепортирует к себе. Якорь исчезает через 2 минуты или после использования. - {"["}bold]Теневой капкан[/bold]: Разблокируется на 400 крови. Устанавливает полу-невидимую ловушку. При срабатывании ослепляет жертву и наносит 20 урона. + {"["}bold]Теневой капкан[/bold]: Разблокируется на 200 крови. Устанавливает полу-невидимую ловушку. При срабатывании ослепляет жертву и наносит 20 урона. - {"["}bold]Клон[/bold]: Разблокируется на 450 крови. Создаёт вашу копию, отвлекающую экипаж, пока вы в невидимости покидаете место боя. + {"["}bold]Клон[/bold]: Разблокируется на 350 крови. Создаёт вашу копию, отвлекающую экипаж, пока вы в невидимости покидаете место боя. vampire-selecting-window-subgroupGargantua-text = {"["}bold]Прилив крови[/bold]: Разблокируется на 100 крови. Увеличивает скорость передвижения в 2.5 раза на 10 секунд. {"["}bold]Вампирский скачок[/bold]: Разблокируется на 200 крови. Телепортирует на короткую дистанцию, оставляя облако дыма на месте отправления. - {"["}bold]Сверк[/bold]: Разблокируется на 300 крови. Ослепляющая вспышка в радиусе 3 тайлов, оглушающая всех жертв и полностью истощающая их выносливость. + {"["}bold]Сверк[/bold]: Разблокируется на 200 крови. Ослепляющая вспышка в радиусе 3 тайлов, оглушающая всех жертв и полностью истощающая их выносливость. - {"["}bold]Гнев Носферату[/bold]: Разблокируется на 400 крови. На 25 секунд: в 2 раза больше урона, +50% скорости атаки, +50% скорости передвижения. + {"["}bold]Гнев Носферату[/bold]: Разблокируется на 300 крови. На 25 секунд: в 2 раза больше урона, +50% скорости атаки, +50% скорости передвижения. - {"["}bold]Рывок[/bold]: Разблокируется на 450 крови. Вы кидаетесь в сторону, куда нажали. Если вы попадёте в человека, вы оглушите его. Если попадёте в предмет, то он получит 200 ед урона. + {"["}bold]Рывок[/bold]: Разблокируется на 350 крови. Вы кидаетесь в сторону, куда нажали. Если вы попадёте в человека, вы оглушите его. Если попадёте в предмет, то он получит 200 ед урона. vampire-selecting-window-subgroupHemomancer-turn = [bold]Обращение[/bold]: Разблокируется на 450 крови. Катана становится вечной: она больше не имеет ограничения по времени и не исчезает после использования. -vampire-selecting-window-subgroupUmbrae-turn = [bold]Обращение[/bold]: Разблокируется на 500 крови. Способность "Переключить режим невидимости" больше не расходует кровь при активации и поддержании. +vampire-selecting-window-subgroupUmbrae-turn = [bold]Обращение[/bold]: Разблокируется на 400 крови. Способность "Переключить режим невидимости" больше не расходует кровь при активации и поддержании. -vampire-selecting-window-subgroupGargantua-turn = [bold]Обращение[/bold]: Разблокируется на 500 крови. Гнев Носферату активируется без затрат крови. Кулдаун между использованиями: 10 секунд. +vampire-selecting-window-subgroupGargantua-turn = [bold]Обращение[/bold]: Разблокируется на 400 крови. Гнев Носферату активируется без затрат крови. Кулдаун между использованиями: 10 секунд. vampire-popup-not-enough-blood = Вам не хватает крови! @@ -68,6 +68,9 @@ vampire-popup-vampire-turned = Вы не можете излечить упыр vampire-popup-ghoul-quantity = Вам необходимо обратить еще { $quantity } упырей vampire-popup-warning-vampire-turned = Вы уже обращены! vampire-popup-anchor-destroyed = Кровавый якорь был разрушен! +vampire-popup-target-no-mind = Жертва без разума - её кровь утоляет жажду, но не даёт силы +vampire-popup-target-no-mind-full = Вы уже сыты, а для получения сил жертва должна иметь разум! +vampire-popup-max-number-ghouls = Максимальное количество рабов уже достигнуто vampire-push-markup-eyes = [color=red]{CAPITALIZE(POSS-PRONOUN($user))} глаза наполнены кровью.[/color] @@ -85,3 +88,5 @@ vampire-verb-envelope-vampire-complete = {$target} был успешно обр vampire-dead-text = Со смертью вампира с вас снимаются все проклятия. vampire-dead-button = Хорошо vampire-dead-title = Смерть вампира + +vampire-popup-chaplain-closely = Присутствие святого причиняет вам боль! diff --git a/Resources/Prototypes/Imperial/Vampire/alert.yml b/Resources/Prototypes/Imperial/Vampire/alert.yml index 0fbcb22784..e2fd848b28 100644 --- a/Resources/Prototypes/Imperial/Vampire/alert.yml +++ b/Resources/Prototypes/Imperial/Vampire/alert.yml @@ -84,3 +84,11 @@ state: brain name: Задержка обращения description: Вы недавно пытались обратить человека в упыря. Функция обращения временно недоступна. + +- type: alert + id: VampireAdjacentChaplainAlert + icons: + - sprite: Imperial/Crook/Chaplain/wood_cross.rsi + state: icon + name: Священная сила + description: Рядом находится священник. Держитесь подальше! diff --git a/Resources/Prototypes/Imperial/Vampire/game_rule.yml b/Resources/Prototypes/Imperial/Vampire/game_rule.yml index 37a25d4e72..cf805f6e9d 100644 --- a/Resources/Prototypes/Imperial/Vampire/game_rule.yml +++ b/Resources/Prototypes/Imperial/Vampire/game_rule.yml @@ -3,10 +3,15 @@ id: Vampire noSpawn: true components: + - type: AntagRandomObjectives + sets: + - groups: VampireObjectiveGroups + maxDifficulty: 1 - type: AntagObjectives objectives: - VampireDrinkBloodObjective - - VampireConvertedGhoulsObjective + - VampireKillRandomPersonObjective + # - VampireConvertedGhoulsObjective - VampireEscapeShuttleObjective - type: GameRule - type: VampireRole @@ -19,10 +24,10 @@ max: 3 lateJoinAdditional: true allowNonHumans: false - multiAntagSetting: NotExclusive blacklist: components: - AntagImmune + - BibleUser briefing: text: vampire-role-greeting-human color: "#8B0000" diff --git a/Resources/Prototypes/Imperial/Vampire/purposes.yml b/Resources/Prototypes/Imperial/Vampire/purposes.yml index e1f656e258..3551033c18 100644 --- a/Resources/Prototypes/Imperial/Vampire/purposes.yml +++ b/Resources/Prototypes/Imperial/Vampire/purposes.yml @@ -10,6 +10,25 @@ roles: - VampireRole +- type: weightedRandom + id: VampireObjectiveGroups + weights: + VampireObjectiveGroupSteal: 1 + +- type: weightedRandom + id: VampireObjectiveGroupSteal + weights: + VampireBibleStealObjective: 1 + VampireWardenHatStealObjective: 1 + VampireForensicScannerStealObjective: 1 + VampireCMOHyposprayStealObjective: 1 + VampireCorgiMeatStealObjective: 1 + VampireFireAxeStealObjective: 1 + VampireCaptainSwordStealObjective: 0.5 + VampireHandTeleporterStealObjective: 0.5 + VampireEnergyMagnumStealObjective: 0.5 + VampireNukeDiskStealObjective: 0.3 + - type: entity parent: [BaseVampireObjective, BaseKillObjective] id: VampireKillRandomPersonObjective @@ -38,26 +57,26 @@ sprite: Imperial/Stellark/Vampire/purposes.rsi state: drink_blood - type: NumberObjective - min: 350 - max: 400 + min: 250 + max: 300 title: objective-condition-blood-title description: objective-condition-blood-description - type: VampireDrinkBloodPurposes -- type: entity - parent: BaseVampireObjective - id: VampireConvertedGhoulsObjective - components: - - type: Objective - icon: - sprite: /Textures/Mobs/Species/Human/organs.rsi - state: brain - - type: NumberObjective - min: 15 - max: 20 - title: objective-condition-converted-ghouls-title - description: objective-condition-converted-ghouls-description - - type: VampireConvertedGhoulsPurposes +# - type: entity +# parent: BaseVampireObjective +# id: VampireConvertedGhoulsObjective +# components: +# - type: Objective +# icon: +# sprite: /Textures/Mobs/Species/Human/organs.rsi +# state: brain +# - type: NumberObjective +# min: 15 +# max: 20 +# title: objective-condition-converted-ghouls-title +# description: objective-condition-converted-ghouls-description +# - type: VampireConvertedGhoulsPurposes - type: entity parent: [BaseVampireObjective, BaseLivingObjective] @@ -71,3 +90,138 @@ state: shuttle - type: EscapeShuttleCondition +- type: entity + parent: [BaseVampireObjective, BaseStealObjective] + id: VampireBibleStealObjective + components: + - type: NotJobRequirement + jobs: [ Chaplain ] + - type: StealCondition + stealGroup: Bible + verifyMapExistence: false + checkStealAreas: true + - type: Objective + difficulty: 0.4 + +- type: entity + parent: [BaseVampireObjective, BaseStealObjective] + id: VampireCaptainSwordStealObjective + components: + - type: NotJobRequirement + jobs: [ Captain ] + - type: StealCondition + stealGroup: CaptainSword + verifyMapExistence: false + checkStealAreas: true + - type: Objective + difficulty: 1.5 + +- type: entity + parent: [BaseVampireObjective, BaseStealObjective] + id: VampireWardenHatStealObjective + components: + - type: StealCondition + stealGroup: ClothingHeadHatWarden + verifyMapExistence: false + checkStealAreas: true + - type: Objective + difficulty: 1.2 + +- type: entity + parent: [BaseVampireObjective, BaseStealObjective] + id: VampireFireAxeStealObjective + components: + - type: NotJobRequirement + jobs: [ AtmosphericTechnician ] + - type: StealCondition + stealGroup: FireAxe + verifyMapExistence: false + checkStealAreas: true + - type: Objective + difficulty: 0.8 + +- type: entity + parent: [BaseVampireObjective, BaseStealObjective] + id: VampireForensicScannerStealObjective + components: + - type: NotJobRequirement + jobs: [ Detective ] + - type: StealCondition + stealGroup: ForensicScanner + verifyMapExistence: false + checkStealAreas: true + - type: Objective + difficulty: 1.0 + +- type: entity + parent: [BaseVampireObjective, BaseStealObjective] + id: VampireCMOHyposprayStealObjective + components: + - type: NotJobRequirement + jobs: [ ChiefMedicalOfficer ] + - type: StealCondition + stealGroup: Hypospray + owner: job-name-cmo + verifyMapExistence: false + checkStealAreas: true + - type: Objective + difficulty: 1.5 + +- type: entity + parent: [BaseVampireObjective, BaseStealObjective] + id: VampireHandTeleporterStealObjective + components: + - type: NotJobRequirement + jobs: [ ResearchDirector ] + - type: StealCondition + stealGroup: HandTeleporter + owner: job-name-rd + verifyMapExistence: false + checkStealAreas: true + - type: Objective + difficulty: 2.0 + +- type: entity + parent: [BaseVampireObjective, BaseStealObjective] + id: VampireEnergyMagnumStealObjective + components: + - type: NotJobRequirement + jobs: [ HeadOfSecurity ] + - type: StealCondition + stealGroup: WeaponEnergyMagnum + owner: job-name-hos + verifyMapExistence: false + checkStealAreas: true + - type: Objective + difficulty: 3.0 + +- type: entity + parent: [BaseVampireObjective, BaseStealObjective] + id: VampireCorgiMeatStealObjective + components: + - type: NotJobRequirement + jobs: [ HeadOfPersonnel ] + - type: ObjectiveLimit + limit: 3 + - type: StealCondition + stealGroup: FoodMeatCorgi + owner: objective-condition-steal-Ian + verifyMapExistence: false + checkStealAreas: true + - type: Objective + difficulty: 2.5 + +- type: entity + parent: [BaseVampireObjective, BaseStealObjective] + id: VampireNukeDiskStealObjective + components: + - type: NotCommandRequirement + - type: NotJobRequirement + jobs: [ Captain ] + - type: StealCondition + stealGroup: NukeDisk + owner: objective-condition-steal-station + verifyMapExistence: false + checkStealAreas: true + - type: Objective + difficulty: 4.0 diff --git a/Resources/Prototypes/Imperial/Vampire/vampire_abilities.yml b/Resources/Prototypes/Imperial/Vampire/vampire_abilities.yml index 18f3ac48b1..e6444dac89 100644 --- a/Resources/Prototypes/Imperial/Vampire/vampire_abilities.yml +++ b/Resources/Prototypes/Imperial/Vampire/vampire_abilities.yml @@ -17,9 +17,9 @@ - VampireTurnAction thresholds: 0: 100 - 1: 200 - 2: 300 - 3: 400 + 1: 100 + 2: 200 + 3: 350 4: 450 upgrades: - VampireSwordPlusAction @@ -36,11 +36,11 @@ - VampireTurnAction thresholds: 0: 100 - 1: 200 - 2: 300 - 3: 400 - 4: 450 - 5: 500 + 1: 100 + 2: 200 + 3: 200 + 4: 350 + 5: 400 upgrades: - VampireInvisiblePlusAction @@ -57,9 +57,9 @@ thresholds: 0: 100 1: 200 - 2: 300 - 3: 400 - 4: 450 - 5: 500 + 2: 200 + 3: 300 + 4: 350 + 5: 400 upgrades: - VampireNosferatyPlusAction diff --git a/Resources/Prototypes/secret_weights.yml b/Resources/Prototypes/secret_weights.yml index 7a409a8919..07b7f9bc27 100644 --- a/Resources/Prototypes/secret_weights.yml +++ b/Resources/Prototypes/secret_weights.yml @@ -10,3 +10,4 @@ KesslerSyndrome: 0.05 Revolutionary: 0.15 Wizard: 0.05 # Why not, should probably be lower + Vampire: 0.15 # imperial space: add a new vampire antagonist. start