Cult spells update (#607)

* - add: CultSystem.BloodSpells.

* - add: Cleanup.
This commit is contained in:
Aviu00
2024-08-11 10:55:01 +00:00
committed by GitHub
parent 00a58cf850
commit e14b6cb948
26 changed files with 290 additions and 72 deletions

View File

@@ -1,5 +1,4 @@
using Content.Client.Eui;
using Content.Client.Ghost.UI;
using Content.Shared._White.Cult.UI;
using JetBrains.Annotations;
using Robust.Client.Graphics;

View File

@@ -4,7 +4,7 @@ using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using static Robust.Client.UserInterface.Controls.BoxContainer;
namespace Content.Client.Ghost.UI;
namespace Content.Client._White.Cult.UI.ApocalypseRuneEui;
public sealed class ApocalypseRuneMenu : DefaultWindow
{

View File

@@ -0,0 +1,57 @@
using Content.Client.Eui;
using Content.Shared._White.Cult.UI;
using JetBrains.Annotations;
using Robust.Client.Graphics;
namespace Content.Client._White.Cult.UI.CultBloodSpellsEui;
[UsedImplicitly]
public sealed class CultBloodSpellsEui : BaseEui
{
private readonly CultBloodSpellsMenu _menu;
private bool _messageSent;
public CultBloodSpellsEui()
{
_menu = new CultBloodSpellsMenu();
_menu.OnClose += () =>
{
if (_messageSent)
return;
SendMessage(new BloodSpellMessage(BloodSpellMessageState.Cancel));
_messageSent = true;
};
_menu.RemoveButton.OnPressed += _ =>
{
Send(BloodSpellMessageState.Remove);
};
_menu.CreateButton.OnPressed += _ =>
{
Send(BloodSpellMessageState.Create);
};
}
private void Send(BloodSpellMessageState state)
{
SendMessage(new BloodSpellMessage(state));
_messageSent = true;
_menu.Close();
}
public override void Opened()
{
IoCManager.Resolve<IClyde>().RequestWindowAttention();
_menu.OpenCentered();
}
public override void Closed()
{
base.Closed();
_menu.Close();
}
}

View File

@@ -0,0 +1,60 @@
using System.Numerics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using static Robust.Client.UserInterface.Controls.BoxContainer;
namespace Content.Client._White.Cult.UI.CultBloodSpellsEui;
public sealed class CultBloodSpellsMenu : DefaultWindow
{
public readonly Button RemoveButton;
public readonly Button CreateButton;
public CultBloodSpellsMenu()
{
Title = Loc.GetString("blood-spells-title");
Contents.AddChild(new BoxContainer
{
Orientation = LayoutOrientation.Vertical,
Children =
{
new BoxContainer
{
Orientation = LayoutOrientation.Vertical,
Children =
{
(new Label()
{
Text = Loc.GetString("blood-spells-text")
}),
new BoxContainer
{
Orientation = LayoutOrientation.Horizontal,
Align = AlignMode.Center,
Children =
{
(CreateButton = new Button
{
Text = Loc.GetString("blood-spells-create-button"),
}),
(new Control()
{
MinSize = new Vector2(20, 0)
}),
(RemoveButton = new Button
{
Text = Loc.GetString("blood-spells-remove-button"),
})
}
},
}
},
}
});
}
}

View File

@@ -29,6 +29,7 @@ namespace Content.Server.Construction
public sealed partial class ConstructionSystem
{
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly IEntityManager _entityManager = default!; // WD
#if EXCEPTION_TOLERANCE
[Dependency] private readonly IRuntimeLog _runtimeLog = default!;
#endif
@@ -95,9 +96,6 @@ namespace Content.Server.Construction
if (!Resolve(uid, ref construction))
return HandleResult.False;
if (TryComp(uid, out StackComponent? stack) && stack.Count > 1) // WD
return HandleResult.False;
// Let's make extra sure this is zero...
construction.StepIndex = 0;
@@ -209,7 +207,7 @@ namespace Content.Server.Construction
// We can only perform the rest of our logic if it returns true.
var handle = HandleInteraction(uid, ev, step, validation, out user, construction);
if (step.CultistOnly && !(HasComp<CultistComponent>(user) || HasComp<GhostComponent>(user))) // WD
if (user != null && step.UserWhitelist?.IsValid(user.Value, _entityManager) is false) // WD
return HandleResult.False;
if (handle is not HandleResult.True)

View File

@@ -28,6 +28,7 @@ using Content.Shared._White.Antag;
using Content.Shared._White.Cult.Components;
using Content.Shared._White.Cult.Systems;
using Content.Shared._White.Mood;
using Content.Shared.Alert;
using Content.Shared.Cloning;
using Content.Shared.Mind;
using Content.Shared.NPC.Systems;
@@ -55,6 +56,7 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
[Dependency] private readonly BloodSpearSystem _bloodSpear = default!;
[Dependency] private readonly ContainerSystem _container = default!;
[Dependency] private readonly HandsSystem _hands = default!;
[Dependency] private readonly AlertsSystem _alertsSystem = default!;
private const int PlayerPerCultist = 10;
private int _minStartingCultists;
@@ -95,7 +97,6 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
private void OnGetBriefing(Entity<CultistRoleComponent> ent, ref GetBriefingEvent args)
{
args.Append(Loc.GetString("cult-role-briefing-short"));
args.Append(Loc.GetString("cult-role-briefing-hint"));
}
private void OnStartAttempt(RoundStartAttemptEvent ev)
@@ -166,6 +167,7 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
private void OnCultistComponentInit(EntityUid uid, CultistComponent component, ComponentInit args)
{
RaiseLocalEvent(uid, new MoodEffectEvent("CultFocused"));
_alertsSystem.ShowAlert(uid, AlertType.BloodSpells);
var query = QueryActiveRules();
while (query.MoveNext(out _, out var cult, out _))
@@ -213,6 +215,7 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
RemoveAllCultistItems(uid);
RemoveCultistAppearance(uid);
RaiseLocalEvent(uid, new MoodRemoveEffectEvent("CultFocused"));
_alertsSystem.ClearAlert(uid, AlertType.BloodSpells);
}
_bloodSpear.DetachSpearFromUser((uid, component));

View File

@@ -6,12 +6,9 @@ public sealed partial class CultStunHandComponent : BaseMagicHandComponent
[DataField]
public TimeSpan Duration = TimeSpan.FromSeconds(16);
[DataField]
public TimeSpan HaloDuration = TimeSpan.FromSeconds(1.5);
[DataField]
public TimeSpan MuteDuration = TimeSpan.FromSeconds(12);
[DataField]
public TimeSpan HaloMuteDuration = TimeSpan.FromSeconds(1);
public float PentagramDurationMultiplier = 0.1f;
}

View File

@@ -245,11 +245,18 @@ public sealed class MagicHandSystem : EntitySystem
return;
}
var halo = HasComp<PentagramComponent>(args.User);
var stunDuration = comp.Duration;
var muteDuration = comp.MuteDuration;
_statusEffects.TryAddStatusEffect(target, "Muted", halo ? comp.HaloMuteDuration : comp.MuteDuration, true,
"Muted", status);
_stun.TryParalyze(target, halo ? comp.HaloDuration : comp.Duration, true, status);
if (HasComp<PentagramComponent>(args.User))
{
var multiplier = comp.PentagramDurationMultiplier;
stunDuration *= multiplier;
muteDuration *= multiplier;
}
_statusEffects.TryAddStatusEffect(target, "Muted", muteDuration, true, "Muted", status);
_stun.TryParalyze(target, stunDuration, true, status);
}
private void Popup(string msg, EntityUid user, PopupType type = PopupType.Small)

View File

@@ -3,16 +3,14 @@ using Content.Server.Body.Components;
using Content.Shared._White.Cult;
using Content.Shared._White.Cult.Components;
using Content.Shared.DoAfter;
using Content.Shared.Verbs;
using Robust.Shared.Player;
namespace Content.Server._White.Cult.Runes.Systems;
public sealed partial class CultSystem
{
public void InitializeVerb()
public void InitializeSpells()
{
SubscribeLocalEvent<CultistComponent, GetVerbsEvent<Verb>>(OnGetVerbs);
SubscribeLocalEvent<CultistComponent, CultEmpowerSelectedBuiMessage>(OnCultistEmpowerSelected);
SubscribeLocalEvent<CultistComponent, CultEmpowerRemoveBuiMessage>(OnCultistEmpowerRemove);
SubscribeLocalEvent<CultistComponent, SpellCreatedEvent>(OnSpellCreated);
@@ -57,7 +55,7 @@ public sealed partial class CultSystem
if (comp.SelectedEmpowers.Count >= 2)
{
_popupSystem.PopupEntity(Loc.GetString("verb-spell-create-too-much"), ent, ent);
_popupSystem.PopupEntity(Loc.GetString("blood-spell-create-too-much"), ent, ent);
return;
}
@@ -71,42 +69,16 @@ public sealed partial class CultSystem
});
}
private void OnGetVerbs(Entity<CultistComponent> ent, ref GetVerbsEvent<Verb> args)
public void CreateSpell(Entity<CultistComponent> ent, ICommonSession session)
{
if (ent.Owner != args.User || !TryComp<ActorComponent>(args.User, out var actor))
return;
var createSpellVerb = new Verb
{
Text = Loc.GetString("verb-spell-create-text"),
Message = Loc.GetString("verb-spell-create-message"),
Category = VerbCategory.Cult,
Act = () =>
{
_ui.TryOpen(ent, CultEmpowerUiKey.Key, actor.PlayerSession);
}
};
var removeSpellVerb = new Verb
{
Text = Loc.GetString("verb-spell-remove-text"),
Message = Loc.GetString("verb-spell-remove-message"),
Category = VerbCategory.Cult,
Act = () =>
{
RemoveSpell(ent, actor.PlayerSession);
}
};
args.Verbs.Add(createSpellVerb);
args.Verbs.Add(removeSpellVerb);
_ui.TryOpen(ent, CultEmpowerUiKey.Key, session);
}
private void RemoveSpell(Entity<CultistComponent> ent, ICommonSession session)
public void RemoveSpell(Entity<CultistComponent> ent, ICommonSession session)
{
if (ent.Comp.SelectedEmpowers.Count == 0)
{
_popupSystem.PopupEntity(Loc.GetString("verb-spell-remove-no-spells"), ent, ent);
_popupSystem.PopupEntity(Loc.GetString("blood-spell-remove-no-spells"), ent, ent);
return;
}

View File

@@ -127,7 +127,7 @@ public sealed partial class CultSystem : EntitySystem
InitializeBarrierSystem();
InitializeConstructsAbilities();
InitializeActions();
InitializeVerb();
InitializeSpells();
}
private float _timeToDraw;

View File

@@ -0,0 +1,53 @@
using Content.Server.EUI;
using Content.Server.Popups;
using Content.Server._White.Cult.Runes.Comps;
using Content.Server._White.Cult.Runes.Systems;
using Content.Shared._White.Cult.Components;
using Content.Shared.Eui;
using Content.Shared.Popups;
using Content.Shared._White.Cult.UI;
using Content.Shared.Movement.Pulling.Components;
using Content.Shared.Movement.Pulling.Systems;
using Robust.Shared.Player;
using Robust.Shared.Timing;
namespace Content.Server._White.Cult.UI;
public sealed class CultBloodSpellsEui : BaseEui
{
private readonly IEntityManager _entityManager;
private readonly CultSystem _cult;
private readonly EntityUid _performer;
public CultBloodSpellsEui(EntityUid performer, IEntityManager entityManager)
{
_entityManager = entityManager;
_cult = _entityManager.System<CultSystem>();
_performer = performer;
}
public override void HandleMessage(EuiMessageBase msg)
{
base.HandleMessage(msg);
if (msg is not BloodSpellMessage cast || cast.State == BloodSpellMessageState.Cancel)
{
Close();
return;
}
if (!_entityManager.TryGetComponent(_performer, out CultistComponent? cultist))
{
Close();
return;
}
if (cast.State == BloodSpellMessageState.Create)
_cult.CreateSpell((_performer, cultist), Player);
else if (cast.State == BloodSpellMessageState.Remove)
_cult.RemoveSpell((_performer, cultist), Player);
Close();
}
}

View File

@@ -0,0 +1,21 @@
using Content.Server.EUI;
using Content.Shared.Alert;
using JetBrains.Annotations;
using Robust.Shared.Player;
namespace Content.Server._White.Cult.UI;
[UsedImplicitly, DataDefinition]
public sealed partial class OpenBloodSpellsUi : IAlertClick
{
public void AlertClicked(EntityUid player)
{
var euiManager = IoCManager.Resolve<EuiManager>();
var entManager = IoCManager.Resolve<IEntityManager>();
if (!entManager.TryGetComponent(player, out ActorComponent? actor))
return;
euiManager.OpenEui(new CultBloodSpellsEui(player, entManager), actor.PlayerSession);
}
}

View File

@@ -39,6 +39,7 @@ namespace Content.Shared.Alert
VeryVeryGood,
MoodDead,
CultBuffed,
BloodSpells,
Knockdown,
RecentlyBlocked,
//WD end

View File

@@ -1,4 +1,5 @@
using Content.Shared.Examine;
using Content.Shared.Whitelist;
namespace Content.Shared.Construction.Steps
{
@@ -11,7 +12,7 @@ namespace Content.Shared.Construction.Steps
[DataField("doAfter")] public float DoAfter { get; private set; }
[DataField]
public bool CultistOnly { get; private set; } // WD
public EntityWhitelist? UserWhitelist { get; private set; } // WD
public IReadOnlyList<IGraphAction> Completed => _completed;

View File

@@ -0,0 +1,22 @@
using Content.Shared.Eui;
using Robust.Shared.Serialization;
namespace Content.Shared._White.Cult.UI;
public enum BloodSpellMessageState : byte
{
Create,
Remove,
Cancel
}
[Serializable, NetSerializable]
public sealed class BloodSpellMessage : EuiMessageBase
{
public readonly BloodSpellMessageState State;
public BloodSpellMessage(BloodSpellMessageState state)
{
State = state;
}
}

View File

@@ -2,3 +2,14 @@ apocalypse-rune-title = Вы готовы к финальной битве?
apocalypse-rune-text = Это последний шаг к вызову Нар'Си; это долгий, болезненный ритуал, и экипаж будет предупрежден о вашем присутствии.
apocalypse-rune-accept-button = Жизнь за Нар'Си!
apocalypse-rune-deny-button = Нет
blood-spells-title = Кровавые заклинания
blood-spells-text = Заклинания крови - важнейший козырь в рукаве культиста.
Вы можете создать до двух заклинаний без руны могущества.
С помощью руны могущества можно создать до пяти заклинаний.
Каждое созданное заклинание отнимает у вас большое количество крови;
расход крови и время создания заклинаний уменьшается под воздействием усиления культа.
Заклинания, созданные на руне могущества не требуют крови и создаются мгновенно.
Удаление заклинаний не отнимает кровь и происходит мгновенно.
blood-spells-create-button = Создать заклинание
blood-spells-remove-button = Удалить заклинание

View File

@@ -1,4 +1,4 @@
cult-title = Культ
cult-title = Культ
cult-description = Страх — самое древнее и сильное из человеческих чувств, а самый древний и самый сильный страх — страх неведомого
cult-role-greeting =
Вы - член культа!
@@ -12,7 +12,6 @@ cult-condition-failure = Экипаж уничтожил культ
cult-condition-draw = Ничейный исход
cult-role-briefing-short = Используйте '^' для связи с другими членами культа.
cult-role-briefing-hint = Нажмите правой кнопкой мыши по своему персонажу и выберите меню 'Культ' для действий, связанных с культом.
cultists-list-start = Культистами были:
cultists-list-name = - [color=White]{ $name }[/color] ([color=gray]{ $user }[/color])
cultists-list-name = - [color=White]{ $name }[/color] ([color=gray]{ $user }[/color])

View File

@@ -0,0 +1,2 @@
blood-spell-remove-no-spells = Заклинания крови отсутствуют.
blood-spell-create-too-much = Начертите руну могущества, чтобы создать больше двух заклинаний крови.

View File

@@ -1,9 +0,0 @@
verb-categories-cult = Культ
verb-spell-create-text = Создать заклинание крови
verb-spell-create-message = Вы можете создать два заклинания крови без руны могущества.
verb-spell-create-too-much = Начертите руну могущества, чтобы создать больше двух заклинаний крови.
verb-spell-remove-text = Удалить заклинание крови
verb-spell-remove-message = Убрать любое из созданных заклинаний крови.
verb-spell-remove-no-spells = Заклинания крови отсутствуют.

View File

@@ -22,6 +22,9 @@ carry-start = { $carrier } пытается взять вас на руки!
alerts-knockdown-name = Лежу
alerts-knockdown-desc = Не могу встать.
alerts-blood-spells-name = Заклинания крови
alerts-blood-spells-desc = Нажмите, чтобы создать или удалить заклинания крови.
melee-block-event-blocked = заблокировал!
alerts-blocked-name = Атака заблокирована
alerts-blocked-desc = Невозможно блокировать некоторое время.

View File

@@ -5,6 +5,7 @@
id: BaseAlertOrder
order:
- category: Health
- alertType: BloodSpells
- alertType: Bleeding
- category: Mood # WD edit
- category: Stamina
@@ -518,3 +519,13 @@
state: offer_item
name: alerts-offer-name
description: alerts-offer-desc
# WD-EDIT
- type: alert
id: BloodSpells
onClick: !type:OpenBloodSpellsUi {}
icons:
- sprite: /Textures/White/Cult/actions_cult.rsi
state: blood_spells
name: alerts-blood-spells-name
description: alerts-blood-spells-desc

View File

@@ -7,8 +7,8 @@
- type: EntityTargetAction
canTargetSelf: false
icon:
sprite: /Textures/Objects/Materials/Sheets/metal.rsi
state: steel
sprite: /Textures/White/Cult/actions_cult.rsi
state: transmute
event: !type:CultTwistedConstructionActionEvent
speech: "Ethra p'ni dedol!"
itemIconStyle: BigAction
@@ -168,4 +168,4 @@
state: gone
revealIcon:
sprite: /Textures/White/Cult/actions_cult.rsi
state: telerune
state: back

View File

@@ -25,7 +25,10 @@
- !type:EntityAnchored
steps:
- tool: Dagger
cultistOnly: true
userWhitelist:
components:
- Cultist
- Ghost
- to: wall
completed:
- !type:SnapToGrid
@@ -46,7 +49,10 @@
amount: 1
steps:
- tool: Dagger
cultistOnly: true
userWhitelist:
components:
- Cultist
- Ghost
- type: constructionGraph
id: AirlockGlassCult
@@ -75,7 +81,10 @@
- !type:EntityAnchored
steps:
- tool: Dagger
cultistOnly: true
userWhitelist:
components:
- Cultist
- Ghost
- type: constructionGraph
id: CultPylon

Binary file not shown.

After

Width:  |  Height:  |  Size: 883 B

View File

@@ -64,6 +64,9 @@
{
"name": "carve"
},
{
"name": "blood_spells"
},
{
"name": "teleport"
},
@@ -157,4 +160,4 @@
"name": "blood_charge"
}
]
}
}