Spellblade update (#346)
* - tweak: Don't close eui too quickly. * - add: Spellblade update. * - fix: Cult teleport spell.
This commit is contained in:
@@ -3,23 +3,19 @@ using Content.Client._White.Cult.UI.TeleportRunesList;
|
|||||||
using Content.Client.Eui;
|
using Content.Client.Eui;
|
||||||
using Content.Shared.Eui;
|
using Content.Shared.Eui;
|
||||||
using Content.Shared._White.Cult.UI;
|
using Content.Shared._White.Cult.UI;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
namespace Content.Client._White.Cult.UI.TeleportSpell;
|
namespace Content.Client._White.Cult.UI.TeleportSpell;
|
||||||
|
|
||||||
public sealed class TeleportSpellEui : BaseEui
|
[UsedImplicitly]
|
||||||
|
public sealed class CultTeleportSpellEui : BaseEui
|
||||||
{
|
{
|
||||||
|
private readonly TeleportRunesListWindow _window = new();
|
||||||
private TeleportRunesListWindow _window;
|
|
||||||
|
|
||||||
public TeleportSpellEui()
|
|
||||||
{
|
|
||||||
_window = new TeleportRunesListWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Opened()
|
public override void Opened()
|
||||||
{
|
{
|
||||||
_window.OpenCentered();
|
_window.OpenCentered();
|
||||||
_window.ItemSelected += (index, _) => SendMessage(new TeleportSpellTargetRuneSelected(){RuneUid = index});
|
_window.ItemSelected += (index, _) => SendMessage(new TeleportSpellTargetRuneSelected {RuneUid = index});
|
||||||
_window.OnClose += () => SendMessage(new CloseEuiMessage());
|
_window.OnClose += () => SendMessage(new CloseEuiMessage());
|
||||||
|
|
||||||
base.Opened();
|
base.Opened();
|
||||||
@@ -33,7 +29,8 @@ public sealed class TeleportSpellEui : BaseEui
|
|||||||
|
|
||||||
public override void HandleState(EuiStateBase state)
|
public override void HandleState(EuiStateBase state)
|
||||||
{
|
{
|
||||||
if(state is not TeleportSpellEuiState cast) return;
|
if (state is not CultTeleportSpellEuiState cast)
|
||||||
|
return;
|
||||||
|
|
||||||
_window.Clear();
|
_window.Clear();
|
||||||
_window.PopulateList(cast.Runes.Keys.ToList(), cast.Runes.Values.ToList());
|
_window.PopulateList(cast.Runes.Keys.ToList(), cast.Runes.Values.ToList());
|
||||||
57
Content.Client/_White/Wizard/SpellBlade/SpellBladeBUI.cs
Normal file
57
Content.Client/_White/Wizard/SpellBlade/SpellBladeBUI.cs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
using Content.Client._White.UserInterface.Radial;
|
||||||
|
using Content.Shared._White.Wizard.SpellBlade;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Client.GameObjects;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Client._White.Wizard.SpellBlade;
|
||||||
|
|
||||||
|
[UsedImplicitly]
|
||||||
|
// ReSharper disable once InconsistentNaming
|
||||||
|
public sealed class SpellBladeBUI(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey)
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||||
|
|
||||||
|
private RadialContainer? _aspectSelector;
|
||||||
|
|
||||||
|
protected override void Open()
|
||||||
|
{
|
||||||
|
base.Open();
|
||||||
|
|
||||||
|
if (!_entityManager.TryGetComponent(Owner, out SpellBladeComponent? spellBlade) ||
|
||||||
|
spellBlade.ChosenAspect != string.Empty)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var spriteSystem = _entityManager.System<SpriteSystem>();
|
||||||
|
_aspectSelector = new RadialContainer();
|
||||||
|
|
||||||
|
_aspectSelector.Closed += Close;
|
||||||
|
|
||||||
|
foreach (var aspect in spellBlade.Aspects)
|
||||||
|
{
|
||||||
|
if (!_prototypeManager.TryIndex(aspect, out var proto))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var button = _aspectSelector.AddButton(proto.Name,
|
||||||
|
spriteSystem.GetPrototypeIcon(proto).Default);
|
||||||
|
button.Tooltip = proto.Description;
|
||||||
|
|
||||||
|
button.Controller.OnPressed += _ =>
|
||||||
|
{
|
||||||
|
SendMessage(new SpellBladeSystemMessage(aspect));
|
||||||
|
_aspectSelector.Close();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_aspectSelector.OpenAttachedLocalPlayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
base.Dispose(disposing);
|
||||||
|
|
||||||
|
_aspectSelector?.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
using Content.Shared._White.Wizard.SpellBlade;
|
||||||
|
|
||||||
|
namespace Content.Client._White.Wizard.SpellBlade;
|
||||||
|
|
||||||
|
public sealed class SpellBladeSystem : SharedSpellBladeSystem
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ using JetBrains.Annotations;
|
|||||||
namespace Content.Client._White.Wizard.TeleportSpell;
|
namespace Content.Client._White.Wizard.TeleportSpell;
|
||||||
|
|
||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
public sealed class TeleportSpellEui : BaseEui
|
public sealed class WizardTeleportSpellEui : BaseEui
|
||||||
{
|
{
|
||||||
private readonly TeleportRunesListWindow _window = new();
|
private readonly TeleportRunesListWindow _window = new();
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ public sealed class TeleportSpellEui : BaseEui
|
|||||||
|
|
||||||
public override void HandleState(EuiStateBase state)
|
public override void HandleState(EuiStateBase state)
|
||||||
{
|
{
|
||||||
if (state is not TeleportSpellEuiState cast)
|
if (state is not WizardTeleportSpellEuiState cast)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_window.Clear();
|
_window.Clear();
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Content.Server._White.Wizard.SpellBlade;
|
||||||
using Content.Server.Administration.Logs;
|
using Content.Server.Administration.Logs;
|
||||||
using Content.Server.Atmos.Components;
|
using Content.Server.Atmos.Components;
|
||||||
using Content.Server.IgnitionSource;
|
using Content.Server.IgnitionSource;
|
||||||
@@ -49,6 +50,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
[Dependency] private readonly UseDelaySystem _useDelay = default!;
|
[Dependency] private readonly UseDelaySystem _useDelay = default!;
|
||||||
[Dependency] private readonly AudioSystem _audio = default!;
|
[Dependency] private readonly AudioSystem _audio = default!;
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
[Dependency] private readonly SpellBladeSystem _spellBlade = default!; // WD
|
||||||
|
|
||||||
public const float MinimumFireStacks = -10f;
|
public const float MinimumFireStacks = -10f;
|
||||||
public const float MaximumFireStacks = 20f;
|
public const float MaximumFireStacks = 20f;
|
||||||
@@ -84,13 +86,19 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
|
|
||||||
private void OnMeleeHit(EntityUid uid, IgniteOnMeleeHitComponent component, MeleeHitEvent args)
|
private void OnMeleeHit(EntityUid uid, IgniteOnMeleeHitComponent component, MeleeHitEvent args)
|
||||||
{
|
{
|
||||||
|
// WD START
|
||||||
|
var fireStacks = component.FireStacks;
|
||||||
|
if (args.Direction != null) // Heavy attack
|
||||||
|
fireStacks *= 0.5f;
|
||||||
|
// WD END
|
||||||
|
|
||||||
foreach (var entity in args.HitEntities)
|
foreach (var entity in args.HitEntities)
|
||||||
{
|
{
|
||||||
if (!TryComp<FlammableComponent>(entity, out var flammable))
|
if (!TryComp<FlammableComponent>(entity, out var flammable))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
AdjustFireStacks(entity, component.FireStacks, flammable);
|
AdjustFireStacks(entity, fireStacks, flammable); // WD EDIT
|
||||||
if (component.FireStacks >= 0)
|
if (fireStacks >= 0) // WD EDIT
|
||||||
Ignite(entity, args.Weapon, flammable, args.User);
|
Ignite(entity, args.Weapon, flammable, args.User);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -203,8 +211,15 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
if (!flammable.OnFire && !otherFlammable.OnFire)
|
if (!flammable.OnFire && !otherFlammable.OnFire)
|
||||||
return; // Neither are on fire
|
return; // Neither are on fire
|
||||||
|
|
||||||
|
// WD START
|
||||||
|
var weHold = _spellBlade.IsHoldingItemWithComponent<FireAspectComponent>(uid);
|
||||||
|
var theyHold = _spellBlade.IsHoldingItemWithComponent<FireAspectComponent>(otherUid);
|
||||||
|
// WD END
|
||||||
|
|
||||||
if (flammable.OnFire && otherFlammable.OnFire)
|
if (flammable.OnFire && otherFlammable.OnFire)
|
||||||
{
|
{
|
||||||
|
if (weHold && !theyHold || theyHold && !weHold) // WD
|
||||||
|
return;
|
||||||
// Both are on fire -> equalize fire stacks.
|
// Both are on fire -> equalize fire stacks.
|
||||||
var avg = (flammable.FireStacks + otherFlammable.FireStacks) / 2;
|
var avg = (flammable.FireStacks + otherFlammable.FireStacks) / 2;
|
||||||
flammable.FireStacks = flammable.CanExtinguish ? avg : Math.Max(flammable.FireStacks, avg);
|
flammable.FireStacks = flammable.CanExtinguish ? avg : Math.Max(flammable.FireStacks, avg);
|
||||||
@@ -217,6 +232,8 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
// Only one is on fire -> attempt to spread the fire.
|
// Only one is on fire -> attempt to spread the fire.
|
||||||
if (flammable.OnFire)
|
if (flammable.OnFire)
|
||||||
{
|
{
|
||||||
|
if (theyHold) // WD
|
||||||
|
return;
|
||||||
otherFlammable.FireStacks += flammable.FireStacks / 2;
|
otherFlammable.FireStacks += flammable.FireStacks / 2;
|
||||||
Ignite(otherUid, uid, otherFlammable);
|
Ignite(otherUid, uid, otherFlammable);
|
||||||
if (flammable.CanExtinguish)
|
if (flammable.CanExtinguish)
|
||||||
@@ -227,6 +244,8 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (weHold) // WD
|
||||||
|
return;
|
||||||
flammable.FireStacks += otherFlammable.FireStacks / 2;
|
flammable.FireStacks += otherFlammable.FireStacks / 2;
|
||||||
Ignite(uid, otherUid, flammable);
|
Ignite(uid, otherUid, flammable);
|
||||||
if (otherFlammable.CanExtinguish)
|
if (otherFlammable.CanExtinguish)
|
||||||
@@ -436,7 +455,8 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
if (TryComp(uid, out TemperatureComponent? temp))
|
if (TryComp(uid, out TemperatureComponent? temp))
|
||||||
_temperatureSystem.ChangeHeat(uid, 12500 * damageScale, false, temp);
|
_temperatureSystem.ChangeHeat(uid, 12500 * damageScale, false, temp);
|
||||||
|
|
||||||
_damageableSystem.TryChangeDamage(uid, flammable.Damage * damageScale, interruptsDoAfters: false);
|
if (!_spellBlade.IsHoldingItemWithComponent<FireAspectComponent>(uid)) // WD EDIT
|
||||||
|
_damageableSystem.TryChangeDamage(uid, flammable.Damage * damageScale, interruptsDoAfters: false);
|
||||||
|
|
||||||
AdjustFireStacks(uid, flammable.FirestackFade * (flammable.Resisting ? 10f : 1f), flammable);
|
AdjustFireStacks(uid, flammable.FirestackFade * (flammable.Resisting ? 10f : 1f), flammable);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content.Server._White.Wizard.SpellBlade;
|
||||||
using Content.Server.Administration.Logs;
|
using Content.Server.Administration.Logs;
|
||||||
using Content.Server.Atmos.Components;
|
using Content.Server.Atmos.Components;
|
||||||
using Content.Server.Atmos.EntitySystems;
|
using Content.Server.Atmos.EntitySystems;
|
||||||
@@ -22,6 +23,7 @@ public sealed class TemperatureSystem : EntitySystem
|
|||||||
[Dependency] private readonly AtmosphereSystem _atmosphere = default!;
|
[Dependency] private readonly AtmosphereSystem _atmosphere = default!;
|
||||||
[Dependency] private readonly DamageableSystem _damageable = default!;
|
[Dependency] private readonly DamageableSystem _damageable = default!;
|
||||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||||
|
[Dependency] private readonly SpellBladeSystem _spellBlade = default!; // WD
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// All the components that will have their damage updated at the end of the tick.
|
/// All the components that will have their damage updated at the end of the tick.
|
||||||
@@ -266,6 +268,17 @@ public sealed class TemperatureSystem : EntitySystem
|
|||||||
|
|
||||||
if (temperature.CurrentTemperature >= heatDamageThreshold)
|
if (temperature.CurrentTemperature >= heatDamageThreshold)
|
||||||
{
|
{
|
||||||
|
// WD START
|
||||||
|
if (_spellBlade.IsHoldingItemWithComponent<FireAspectComponent>(uid))
|
||||||
|
{
|
||||||
|
if (!temperature.TakingDamage)
|
||||||
|
return;
|
||||||
|
_adminLogger.Add(LogType.Temperature,
|
||||||
|
$"{ToPrettyString(uid):entity} stopped taking temperature damage");
|
||||||
|
temperature.TakingDamage = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// WD END
|
||||||
if (!temperature.TakingDamage)
|
if (!temperature.TakingDamage)
|
||||||
{
|
{
|
||||||
_adminLogger.Add(LogType.Temperature, $"{ToPrettyString(uid):entity} started taking high temperature damage");
|
_adminLogger.Add(LogType.Temperature, $"{ToPrettyString(uid):entity} started taking high temperature damage");
|
||||||
@@ -278,7 +291,8 @@ public sealed class TemperatureSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
else if (temperature.CurrentTemperature <= coldDamageThreshold)
|
else if (temperature.CurrentTemperature <= coldDamageThreshold)
|
||||||
{
|
{
|
||||||
if (TryComp(uid, out VoidAdaptationComponent? voidAdaptation)) // WD
|
// WD START
|
||||||
|
if (TryComp(uid, out VoidAdaptationComponent? voidAdaptation))
|
||||||
{
|
{
|
||||||
if (temperature.TakingDamage)
|
if (temperature.TakingDamage)
|
||||||
{
|
{
|
||||||
@@ -291,6 +305,17 @@ public sealed class TemperatureSystem : EntitySystem
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_spellBlade.IsHoldingItemWithComponent<FrostAspectComponent>(uid))
|
||||||
|
{
|
||||||
|
if (!temperature.TakingDamage)
|
||||||
|
return;
|
||||||
|
_adminLogger.Add(LogType.Temperature,
|
||||||
|
$"{ToPrettyString(uid):entity} stopped taking temperature damage");
|
||||||
|
temperature.TakingDamage = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// WD END
|
||||||
|
|
||||||
if (!temperature.TakingDamage)
|
if (!temperature.TakingDamage)
|
||||||
{
|
{
|
||||||
_adminLogger.Add(LogType.Temperature, $"{ToPrettyString(uid):entity} started taking low temperature damage");
|
_adminLogger.Add(LogType.Temperature, $"{ToPrettyString(uid):entity} started taking low temperature damage");
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Content.Server._White.Wizard.SpellBlade;
|
||||||
using Content.Server.Temperature.Components;
|
using Content.Server.Temperature.Components;
|
||||||
using Content.Server.Temperature.Systems;
|
using Content.Server.Temperature.Systems;
|
||||||
using Content.Shared.Changeling;
|
using Content.Shared.Changeling;
|
||||||
@@ -10,6 +11,7 @@ namespace Content.Server._White.ChangeTemperatureOnCollide;
|
|||||||
public sealed class LowTemperatureSlowdownSystem : EntitySystem
|
public sealed class LowTemperatureSlowdownSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifierSystem = default!;
|
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifierSystem = default!;
|
||||||
|
[Dependency] private readonly SpellBladeSystem _spellBlade = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -22,7 +24,8 @@ public sealed class LowTemperatureSlowdownSystem : EntitySystem
|
|||||||
private void OnMoveSpeedRefresh(EntityUid uid, TemperatureComponent component,
|
private void OnMoveSpeedRefresh(EntityUid uid, TemperatureComponent component,
|
||||||
RefreshMovementSpeedModifiersEvent args)
|
RefreshMovementSpeedModifiersEvent args)
|
||||||
{
|
{
|
||||||
var modifier = HasComp<GodmodeComponent>(uid) || HasComp<VoidAdaptationComponent>(uid) || !component.Slowdown
|
var modifier = _spellBlade.IsHoldingItemWithComponent<FrostAspectComponent>(uid) ||
|
||||||
|
HasComp<GodmodeComponent>(uid) || HasComp<VoidAdaptationComponent>(uid) || !component.Slowdown
|
||||||
? 1f
|
? 1f
|
||||||
: GetSpeedModifier(component.CurrentTemperature);
|
: GetSpeedModifier(component.CurrentTemperature);
|
||||||
args.ModifySpeed(modifier, modifier);
|
args.ModifySpeed(modifier, modifier);
|
||||||
@@ -32,7 +35,7 @@ public sealed class LowTemperatureSlowdownSystem : EntitySystem
|
|||||||
OnTemperatureChangeEvent args)
|
OnTemperatureChangeEvent args)
|
||||||
{
|
{
|
||||||
// ReSharper disable once CompareOfFloatsByEqualityOperator
|
// ReSharper disable once CompareOfFloatsByEqualityOperator
|
||||||
if(GetSpeedModifier(args.LastTemperature) == GetSpeedModifier(args.CurrentTemperature))
|
if (GetSpeedModifier(args.LastTemperature) == GetSpeedModifier(args.CurrentTemperature))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_movementSpeedModifierSystem.RefreshMovementSpeedModifiers(uid, component);
|
_movementSpeedModifierSystem.RefreshMovementSpeedModifiers(uid, component);
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ public partial class CultSystem
|
|||||||
|
|
||||||
_bloodstreamSystem.TryModifyBloodLevel(uid, -5, bloodstream, createPuddle: false);
|
_bloodstreamSystem.TryModifyBloodLevel(uid, -5, bloodstream, createPuddle: false);
|
||||||
|
|
||||||
var eui = new TeleportSpellEui(args.Performer, args.Target);
|
var eui = new CultTeleportSpellEui(args.Performer, args.Target);
|
||||||
_euiManager.OpenEui(eui, actor.PlayerSession);
|
_euiManager.OpenEui(eui, actor.PlayerSession);
|
||||||
eui.StateDirty();
|
eui.StateDirty();
|
||||||
|
|
||||||
|
|||||||
@@ -631,6 +631,18 @@ public sealed partial class CultSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
private bool Teleport(EntityUid rune, EntityUid user, List<EntityUid>? victims = null)
|
private bool Teleport(EntityUid rune, EntityUid user, List<EntityUid>? victims = null)
|
||||||
|
{
|
||||||
|
if (!OpenTeleportUi(user, rune))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_entityManager.EnsureComponent<CultTeleportRuneProviderComponent>(user, out var providerComponent);
|
||||||
|
providerComponent.Targets = victims;
|
||||||
|
providerComponent.BaseRune = rune;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool OpenTeleportUi(EntityUid user, EntityUid? exceptRune = null)
|
||||||
{
|
{
|
||||||
var runesQuery = EntityQueryEnumerator<CultRuneTeleportComponent>();
|
var runesQuery = EntityQueryEnumerator<CultRuneTeleportComponent>();
|
||||||
var list = new List<int>();
|
var list = new List<int>();
|
||||||
@@ -641,7 +653,7 @@ public sealed partial class CultSystem : EntitySystem
|
|||||||
if (teleportComponent.Label == null)
|
if (teleportComponent.Label == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (runeUid == rune)
|
if (runeUid == exceptRune)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!int.TryParse(runeUid.ToString(), out var intValue))
|
if (!int.TryParse(runeUid.ToString(), out var intValue))
|
||||||
@@ -665,10 +677,6 @@ public sealed partial class CultSystem : EntitySystem
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_entityManager.EnsureComponent<CultTeleportRuneProviderComponent>(user, out var providerComponent);
|
|
||||||
providerComponent.Targets = victims;
|
|
||||||
providerComponent.BaseRune = rune;
|
|
||||||
|
|
||||||
_ui.SetUiState(ui, new TeleportRunesListWindowBUIState(list, labels));
|
_ui.SetUiState(ui, new TeleportRunesListWindowBUIState(list, labels));
|
||||||
|
|
||||||
if (_ui.IsUiOpen(user, ui.UiKey))
|
if (_ui.IsUiOpen(user, ui.UiKey))
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ using Robust.Shared.Timing;
|
|||||||
|
|
||||||
namespace Content.Server._White.Cult.UI;
|
namespace Content.Server._White.Cult.UI;
|
||||||
|
|
||||||
public sealed class TeleportSpellEui : BaseEui
|
public sealed class CultTeleportSpellEui : BaseEui
|
||||||
{
|
{
|
||||||
[Dependency] private readonly EntityManager _entityManager = default!;
|
[Dependency] private readonly EntityManager _entityManager = default!;
|
||||||
private readonly SharedTransformSystem _transformSystem;
|
private readonly SharedTransformSystem _transformSystem;
|
||||||
@@ -22,7 +22,7 @@ public sealed class TeleportSpellEui : BaseEui
|
|||||||
|
|
||||||
private bool _used;
|
private bool _used;
|
||||||
|
|
||||||
public TeleportSpellEui(EntityUid performer, EntityUid target)
|
public CultTeleportSpellEui(EntityUid performer, EntityUid target)
|
||||||
{
|
{
|
||||||
IoCManager.InjectDependencies(this);
|
IoCManager.InjectDependencies(this);
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ public sealed class TeleportSpellEui : BaseEui
|
|||||||
public override EuiStateBase GetNewState()
|
public override EuiStateBase GetNewState()
|
||||||
{
|
{
|
||||||
var runesQuery = _entityManager.EntityQueryEnumerator<CultRuneTeleportComponent>();
|
var runesQuery = _entityManager.EntityQueryEnumerator<CultRuneTeleportComponent>();
|
||||||
var state = new TeleportSpellEuiState();
|
var state = new CultTeleportSpellEuiState();
|
||||||
|
|
||||||
while (runesQuery.MoveNext(out var runeUid, out var rune))
|
while (runesQuery.MoveNext(out var runeUid, out var rune))
|
||||||
{
|
{
|
||||||
@@ -110,4 +110,4 @@ public sealed class TeleportSpellEui : BaseEui
|
|||||||
_transformSystem.SetCoordinates(_target, runeTransform.Coordinates);
|
_transformSystem.SetCoordinates(_target, runeTransform.Coordinates);
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
if (!TryComp(msg.Performer, out ActorComponent? actor))
|
if (!TryComp(msg.Performer, out ActorComponent? actor))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var eui = new TeleportSpellEui(msg.Performer);
|
var eui = new WizardTeleportSpellEui(msg.Performer);
|
||||||
_euiManager.OpenEui(eui, actor.PlayerSession);
|
_euiManager.OpenEui(eui, actor.PlayerSession);
|
||||||
eui.StateDirty();
|
eui.StateDirty();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Content.Server._White.Wizard.SpellBlade;
|
||||||
|
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed partial class FireAspectComponent : Component
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using Content.Shared.Atmos;
|
||||||
|
|
||||||
|
namespace Content.Server._White.Wizard.SpellBlade;
|
||||||
|
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed partial class FrostAspectComponent : Component
|
||||||
|
{
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public float TemperatureOnHit = 100;
|
||||||
|
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public float MinTemperature = Atmospherics.TCMB;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
namespace Content.Server._White.Wizard.SpellBlade;
|
||||||
|
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed partial class LightningAspectComponent : Component
|
||||||
|
{
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public float Range = 2f;
|
||||||
|
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public int BoltCount = 3;
|
||||||
|
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public string LightningPrototype = "WeakWizardLightning";
|
||||||
|
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public int ArcDepth = 2;
|
||||||
|
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public TimeSpan ShockRate = TimeSpan.FromSeconds(10);
|
||||||
|
|
||||||
|
public TimeSpan NextShock;
|
||||||
|
}
|
||||||
79
Content.Server/_White/Wizard/SpellBlade/SpellBladeSystem.cs
Normal file
79
Content.Server/_White/Wizard/SpellBlade/SpellBladeSystem.cs
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
using Content.Server.Atmos.Components;
|
||||||
|
using Content.Server.Lightning;
|
||||||
|
using Content.Server.Temperature.Components;
|
||||||
|
using Content.Server.Temperature.Systems;
|
||||||
|
using Content.Shared._White.Wizard.SpellBlade;
|
||||||
|
using Content.Shared.Weapons.Melee.Events;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
|
namespace Content.Server._White.Wizard.SpellBlade;
|
||||||
|
|
||||||
|
public sealed class SpellBladeSystem : SharedSpellBladeSystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly TemperatureSystem _temperature = default!;
|
||||||
|
[Dependency] private readonly LightningSystem _lightning = default!;
|
||||||
|
[Dependency] private readonly IGameTiming _timing = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<FrostAspectComponent, MeleeHitEvent>(OnFrostMeleeHit);
|
||||||
|
SubscribeLocalEvent<LightningAspectComponent, MeleeHitEvent>(OnLightningMeleeHit);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnLightningMeleeHit(Entity<LightningAspectComponent> ent, ref MeleeHitEvent args)
|
||||||
|
{
|
||||||
|
if (args.Direction != null || args.HitEntities.Count != 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ent.Comp.NextShock > _timing.CurTime)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ent.Comp.NextShock = _timing.CurTime + ent.Comp.ShockRate;
|
||||||
|
|
||||||
|
_lightning.ShootRandomLightnings(args.HitEntities[0], ent.Comp.Range, ent.Comp.BoltCount,
|
||||||
|
ent.Comp.LightningPrototype, ent.Comp.ArcDepth, false, args.User);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnFrostMeleeHit(Entity<FrostAspectComponent> ent, ref MeleeHitEvent args)
|
||||||
|
{
|
||||||
|
var temp = ent.Comp.TemperatureOnHit;
|
||||||
|
if (args.Direction != null) // Heavy attack
|
||||||
|
temp *= 0.5f;
|
||||||
|
|
||||||
|
foreach (var entity in args.HitEntities)
|
||||||
|
{
|
||||||
|
if (!TryComp<TemperatureComponent>(entity, out var temperature))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var curTemp = temperature.CurrentTemperature;
|
||||||
|
var newTemp = curTemp - temp;
|
||||||
|
|
||||||
|
newTemp = curTemp < ent.Comp.MinTemperature
|
||||||
|
? MathF.Min(curTemp, newTemp)
|
||||||
|
: Math.Max(newTemp, ent.Comp.MinTemperature);
|
||||||
|
|
||||||
|
_temperature.ForceChangeTemperature(entity, newTemp, temperature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ApplyFireAspect(EntityUid uid)
|
||||||
|
{
|
||||||
|
var ignite = EnsureComp<IgniteOnMeleeHitComponent>(uid);
|
||||||
|
ignite.FireStacks = 2f;
|
||||||
|
EnsureComp<FireAspectComponent>(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ApplyFrostAspect(EntityUid uid)
|
||||||
|
{
|
||||||
|
var ignite = EnsureComp<IgniteOnMeleeHitComponent>(uid);
|
||||||
|
ignite.FireStacks = -5f;
|
||||||
|
EnsureComp<FrostAspectComponent>(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ApplyLightningAspect(EntityUid uid)
|
||||||
|
{
|
||||||
|
EnsureComp<LightningAspectComponent>(uid);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
using System.Linq;
|
using Content.Server.EUI;
|
||||||
using Content.Server.EUI;
|
|
||||||
using Content.Server.Popups;
|
using Content.Server.Popups;
|
||||||
using Content.Shared._White.Wizard.Teleport;
|
using Content.Shared._White.Wizard.Teleport;
|
||||||
using Content.Shared.Eui;
|
using Content.Shared.Eui;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
using TeleportSpellEuiState = Content.Shared._White.Wizard.Teleport.TeleportSpellEuiState;
|
|
||||||
|
|
||||||
namespace Content.Server._White.Wizard.Teleport;
|
namespace Content.Server._White.Wizard.Teleport;
|
||||||
|
|
||||||
public sealed class TeleportSpellEui : BaseEui
|
public sealed class WizardTeleportSpellEui : BaseEui
|
||||||
{
|
{
|
||||||
[Dependency] private readonly EntityManager _entityManager = default!;
|
[Dependency] private readonly EntityManager _entityManager = default!;
|
||||||
private readonly SharedTransformSystem _transformSystem;
|
private readonly SharedTransformSystem _transformSystem;
|
||||||
@@ -19,7 +17,7 @@ public sealed class TeleportSpellEui : BaseEui
|
|||||||
|
|
||||||
private bool _used;
|
private bool _used;
|
||||||
|
|
||||||
public TeleportSpellEui(EntityUid performer)
|
public WizardTeleportSpellEui(EntityUid performer)
|
||||||
{
|
{
|
||||||
IoCManager.InjectDependencies(this);
|
IoCManager.InjectDependencies(this);
|
||||||
|
|
||||||
@@ -29,13 +27,13 @@ public sealed class TeleportSpellEui : BaseEui
|
|||||||
|
|
||||||
_performer = performer;
|
_performer = performer;
|
||||||
|
|
||||||
Timer.Spawn(TimeSpan.FromSeconds(10), Close);
|
Timer.Spawn(TimeSpan.FromSeconds(60), Close);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override EuiStateBase GetNewState()
|
public override EuiStateBase GetNewState()
|
||||||
{
|
{
|
||||||
var locationQuery = _entityManager.EntityQueryEnumerator<TeleportLocationComponent, TransformComponent>();
|
var locationQuery = _entityManager.EntityQueryEnumerator<TeleportLocationComponent, TransformComponent>();
|
||||||
var state = new TeleportSpellEuiState();
|
var state = new WizardTeleportSpellEuiState();
|
||||||
|
|
||||||
while (locationQuery.MoveNext(out var locationUid, out var locationComponent, out var transformComponent))
|
while (locationQuery.MoveNext(out var locationUid, out var locationComponent, out var transformComponent))
|
||||||
{
|
{
|
||||||
@@ -533,6 +533,11 @@ public abstract partial class SharedGunSystem : EntitySystem
|
|||||||
Dirty(gun);
|
Dirty(gun);
|
||||||
}
|
}
|
||||||
// WD EDIT
|
// WD EDIT
|
||||||
|
public void SetUseKey(GunComponent gun, bool useKey)
|
||||||
|
{
|
||||||
|
gun.UseKey = useKey;
|
||||||
|
}
|
||||||
|
|
||||||
public void SetProjectileSpeed(EntityUid weapon, float projectileSpeed)
|
public void SetProjectileSpeed(EntityUid weapon, float projectileSpeed)
|
||||||
{
|
{
|
||||||
if(!TryComp<GunComponent>(weapon, out var gunComponent))
|
if(!TryComp<GunComponent>(weapon, out var gunComponent))
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared._White.BetrayalDagger;
|
namespace Content.Shared._White.BetrayalDagger;
|
||||||
|
|
||||||
[RegisterComponent]
|
[RegisterComponent, NetworkedComponent]
|
||||||
public sealed partial class BlinkComponent : Component
|
public sealed partial class BlinkComponent : Component
|
||||||
{
|
{
|
||||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using Robust.Shared.Serialization;
|
|||||||
namespace Content.Shared._White.Cult.UI;
|
namespace Content.Shared._White.Cult.UI;
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public sealed class TeleportSpellEuiState : EuiStateBase
|
public sealed class CultTeleportSpellEuiState : EuiStateBase
|
||||||
{
|
{
|
||||||
public Dictionary<int, string> Runes = new();
|
public Dictionary<int, string> Runes = new();
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Content.Shared._White.BetrayalDagger;
|
||||||
|
using Content.Shared.Examine;
|
||||||
|
using Content.Shared.Hands.EntitySystems;
|
||||||
|
using Content.Shared.Popups;
|
||||||
|
using Content.Shared.UserInterface;
|
||||||
|
using Content.Shared.Weapons.Ranged.Components;
|
||||||
|
using Content.Shared.Weapons.Ranged.Systems;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.Audio.Systems;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Shared._White.Wizard.SpellBlade;
|
||||||
|
|
||||||
|
public abstract class SharedSpellBladeSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||||
|
[Dependency] private readonly SharedHandsSystem _hands = default!;
|
||||||
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||||
|
[Dependency] private readonly SharedGunSystem _gun = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<SpellBladeComponent, SpellBladeSystemMessage>(OnMessage);
|
||||||
|
SubscribeLocalEvent<SpellBladeComponent, ActivatableUIOpenAttemptEvent>(OnOpenAttempt);
|
||||||
|
SubscribeLocalEvent<SpellBladeComponent, ExaminedEvent>(OnExamined);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnExamined(Entity<SpellBladeComponent> ent, ref ExaminedEvent args)
|
||||||
|
{
|
||||||
|
if (ent.Comp.ChosenAspect == string.Empty)
|
||||||
|
{
|
||||||
|
args.PushMarkup("Аспект не выбран.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var proto = _prototypeManager.Index(ent.Comp.ChosenAspect);
|
||||||
|
|
||||||
|
args.PushMarkup($"Выбранный аспект: {proto.Name}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnOpenAttempt(Entity<SpellBladeComponent> ent, ref ActivatableUIOpenAttemptEvent args)
|
||||||
|
{
|
||||||
|
if (ent.Comp.ChosenAspect == string.Empty)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_popup.PopupEntity("Аспект уже выбран.", args.User, args.User);
|
||||||
|
args.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnMessage(Entity<SpellBladeComponent> ent, ref SpellBladeSystemMessage args)
|
||||||
|
{
|
||||||
|
if (ent.Comp.ChosenAspect != string.Empty)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (args.ProtoId)
|
||||||
|
{
|
||||||
|
case "AspectFire":
|
||||||
|
ApplyFireAspect(ent);
|
||||||
|
break;
|
||||||
|
case "AspectFrost":
|
||||||
|
ApplyFrostAspect(ent);
|
||||||
|
break;
|
||||||
|
case "AspectLightning":
|
||||||
|
ApplyLightningAspect(ent);
|
||||||
|
break;
|
||||||
|
case "AspectBluespace":
|
||||||
|
ApplyBluespaceAspect(ent);
|
||||||
|
break;
|
||||||
|
case "AspectMagicMissile":
|
||||||
|
ApplyMagicMissileAspect(ent);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ent.Comp.ChosenAspect = args.ProtoId;
|
||||||
|
|
||||||
|
_audio.PlayPvs(ent.Comp.AspectChosenSound, ent);
|
||||||
|
|
||||||
|
|
||||||
|
Dirty(ent);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void ApplyFireAspect(EntityUid uid) { }
|
||||||
|
|
||||||
|
protected virtual void ApplyFrostAspect(EntityUid uid) { }
|
||||||
|
|
||||||
|
protected virtual void ApplyLightningAspect(EntityUid uid) { }
|
||||||
|
|
||||||
|
private void ApplyBluespaceAspect(EntityUid uid)
|
||||||
|
{
|
||||||
|
var blink = EnsureComp<BlinkComponent>(uid);
|
||||||
|
blink.Distance = 15f;
|
||||||
|
blink.BlinkRate = 1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyMagicMissileAspect(EntityUid uid)
|
||||||
|
{
|
||||||
|
var gun = EnsureComp<GunComponent>(uid);
|
||||||
|
_gun.SetUseKey(gun, false);
|
||||||
|
_gun.SetSound(uid, new SoundPathSpecifier("/Audio/Weapons/Guns/Gunshots/Magic/staff_healing.ogg"));
|
||||||
|
_gun.SetFireRate(uid, 1.2f);
|
||||||
|
var ammoProvider = EnsureComp<BasicEntityAmmoProviderComponent>(uid);
|
||||||
|
ammoProvider.Proto = "ProjectileMagicMissile";
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsHoldingItemWithComponent<T>(EntityUid uid) where T : Component
|
||||||
|
{
|
||||||
|
return _hands.EnumerateHeld(uid).Any(HasComp<T>);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared._White.Wizard.SpellBlade;
|
||||||
|
|
||||||
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||||
|
public sealed partial class SpellBladeComponent : Component
|
||||||
|
{
|
||||||
|
[ViewVariables, AutoNetworkedField]
|
||||||
|
public string ChosenAspect = string.Empty;
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public List<EntProtoId> Aspects = new()
|
||||||
|
{
|
||||||
|
"AspectFire",
|
||||||
|
"AspectFrost",
|
||||||
|
"AspectLightning",
|
||||||
|
"AspectBluespace",
|
||||||
|
"AspectMagicMissile"
|
||||||
|
};
|
||||||
|
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public SoundSpecifier AspectChosenSound = new SoundPathSpecifier("/Audio/White/Magic/spellblade-aspect.ogg");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class SpellBladeSystemMessage(EntProtoId protoId) : BoundUserInterfaceMessage
|
||||||
|
{
|
||||||
|
public EntProtoId ProtoId = protoId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public enum SpellBladeUiKey : byte
|
||||||
|
{
|
||||||
|
Key
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ using Robust.Shared.Serialization;
|
|||||||
namespace Content.Shared._White.Wizard.Teleport;
|
namespace Content.Shared._White.Wizard.Teleport;
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public sealed class TeleportSpellEuiState : EuiStateBase
|
public sealed class WizardTeleportSpellEuiState : EuiStateBase
|
||||||
{
|
{
|
||||||
public Dictionary<int, string> Locations = new();
|
public Dictionary<int, string> Locations = new();
|
||||||
}
|
}
|
||||||
BIN
Resources/Audio/White/Magic/spellblade-aspect.ogg
Normal file
BIN
Resources/Audio/White/Magic/spellblade-aspect.ogg
Normal file
Binary file not shown.
@@ -176,3 +176,16 @@
|
|||||||
- type: Lightning
|
- type: Lightning
|
||||||
canArc: true
|
canArc: true
|
||||||
lightningPrototype: WizardLightning
|
lightningPrototype: WizardLightning
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: wizard lightning
|
||||||
|
id: WeakWizardLightning
|
||||||
|
parent: BaseLightning
|
||||||
|
noSpawn: true
|
||||||
|
components:
|
||||||
|
- type: Electrified
|
||||||
|
requirePower: false
|
||||||
|
ignoreInsulation: true
|
||||||
|
- type: Lightning
|
||||||
|
canArc: true
|
||||||
|
lightningPrototype: WeakWizardLightning
|
||||||
|
|||||||
@@ -236,3 +236,44 @@
|
|||||||
stunAmount: 2
|
stunAmount: 2
|
||||||
knockdownAmount: 2
|
knockdownAmount: 2
|
||||||
- type: TeslaProjectile
|
- type: TeslaProjectile
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: ProjectileMagicMissile
|
||||||
|
name: magic missile
|
||||||
|
description: asdf
|
||||||
|
parent: BaseBullet
|
||||||
|
noSpawn: true
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Weapons/Guns/Projectiles/magic.rsi
|
||||||
|
layers:
|
||||||
|
- state: spell
|
||||||
|
color: pink
|
||||||
|
- type: Projectile
|
||||||
|
damage:
|
||||||
|
groups:
|
||||||
|
Burn: 0
|
||||||
|
- type: StaminaDamageOnCollide
|
||||||
|
damage: 60
|
||||||
|
- type: Ammo
|
||||||
|
muzzleFlash: null
|
||||||
|
- type: Trail
|
||||||
|
splineIteratorType: CatmullRom
|
||||||
|
splineRendererType: Continuous
|
||||||
|
creationMethod: OnMove
|
||||||
|
lengthStep: 0.1
|
||||||
|
scale: 0.05, 0.0
|
||||||
|
lifetime: 1
|
||||||
|
randomWalk: 0.1, 0.001
|
||||||
|
gravity: 0.0, 0.0
|
||||||
|
texturePath: /Textures/White/Effects/Trails/Continuous/trail.png
|
||||||
|
gradientIteratorType: Linear
|
||||||
|
gradient:
|
||||||
|
- 1, 0, 0, 1
|
||||||
|
- 1, 1, 0, 0.85
|
||||||
|
- 0, 1, 0, 0.7
|
||||||
|
- 0, 1, 1, 0.55
|
||||||
|
- 0, 0, 1, 0.4
|
||||||
|
- 1, 0, 1, 0.25
|
||||||
|
- 1, 0, 0, 0.1
|
||||||
|
optionsConcealable: true
|
||||||
|
|||||||
@@ -36,7 +36,6 @@
|
|||||||
- HolyKatana
|
- HolyKatana
|
||||||
- MultiverseBlade
|
- MultiverseBlade
|
||||||
- VorpalScythe
|
- VorpalScythe
|
||||||
- SpellBlade
|
|
||||||
- PossessedBlade
|
- PossessedBlade
|
||||||
- ChainsawHand
|
- ChainsawHand
|
||||||
- HolyWhip
|
- HolyWhip
|
||||||
@@ -195,31 +194,6 @@
|
|||||||
sprite: White/Objects/Weapons/Chaplain/scythe-inhands.rsi
|
sprite: White/Objects/Weapons/Chaplain/scythe-inhands.rsi
|
||||||
- type: HolyWeapon
|
- type: HolyWeapon
|
||||||
|
|
||||||
- type: entity
|
|
||||||
name: клинок заклинаний
|
|
||||||
parent: HolyKatana
|
|
||||||
id: SpellBlade
|
|
||||||
description: Клинок, с шансом 20% наносящий критический удар.
|
|
||||||
components:
|
|
||||||
- type: Sprite
|
|
||||||
sprite: White/Objects/Weapons/Chaplain/spellblade.rsi
|
|
||||||
- type: MeleeWeapon
|
|
||||||
wideAnimationRotation: 135
|
|
||||||
damage:
|
|
||||||
types:
|
|
||||||
Slash: 18
|
|
||||||
- type: Clothing
|
|
||||||
sprite: White/Objects/Weapons/Chaplain/spellblade.rsi
|
|
||||||
slots:
|
|
||||||
- back
|
|
||||||
- suitStorage
|
|
||||||
- type: Crit
|
|
||||||
critChance: 20
|
|
||||||
critMultiplier: 2.5
|
|
||||||
- type: Item
|
|
||||||
sprite: White/Objects/Weapons/Chaplain/spellblade.rsi
|
|
||||||
- type: HolyWeapon
|
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: одержимый клинок
|
name: одержимый клинок
|
||||||
parent: HolyKatana
|
parent: HolyKatana
|
||||||
|
|||||||
@@ -21,3 +21,33 @@
|
|||||||
reflectProb: 0.4
|
reflectProb: 0.4
|
||||||
- type: Item
|
- type: Item
|
||||||
sprite: White/Objects/Weapons/Chaplain/hfrequency.rsi
|
sprite: White/Objects/Weapons/Chaplain/hfrequency.rsi
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: клинок заклинаний
|
||||||
|
parent: Katana
|
||||||
|
id: SpellBlade
|
||||||
|
description: Магический клинок, наделяемый силой одного из пяти аспектов.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: White/Objects/Weapons/Chaplain/spellblade.rsi
|
||||||
|
- type: MeleeWeapon
|
||||||
|
wideAnimationRotation: 135
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Slash: 30
|
||||||
|
- type: Clothing
|
||||||
|
sprite: White/Objects/Weapons/Chaplain/spellblade.rsi
|
||||||
|
slots:
|
||||||
|
- back
|
||||||
|
- suitStorage
|
||||||
|
- type: Item
|
||||||
|
sprite: White/Objects/Weapons/Chaplain/spellblade.rsi
|
||||||
|
- type: UserInterface
|
||||||
|
interfaces:
|
||||||
|
- key: enum.SpellBladeUiKey.Key
|
||||||
|
type: SpellBladeBUI
|
||||||
|
- type: ActivatableUI
|
||||||
|
key: enum.SpellBladeUiKey.Key
|
||||||
|
inHandsOnly: true
|
||||||
|
closeOnHandDeselect: true
|
||||||
|
- type: SpellBlade
|
||||||
|
|||||||
49
Resources/Prototypes/_White/Wizard/spellblade.yml
Normal file
49
Resources/Prototypes/_White/Wizard/spellblade.yml
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
- type: entity
|
||||||
|
name: Огонь
|
||||||
|
description: Клинок заклинаний наделяется способностью поджигать врагов. И тот, кто удерживает клинок в руках, становится неуязвимым к огню и высокой температуре.
|
||||||
|
id: AspectFire
|
||||||
|
noSpawn: true
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Magic/magicactions.rsi
|
||||||
|
state: fireball
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: Холод
|
||||||
|
description: Клинок заклинаний наделяется замораживать врагов. И тот, кто удерживает клинок в руках, становится неуязвимым к низкой температуре.
|
||||||
|
id: AspectFrost
|
||||||
|
noSpawn: true
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Magic/magicactions.rsi
|
||||||
|
state: icebeam_active
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: Молния
|
||||||
|
description: Клинок заклинаний наделяется способностью каждые 10 секунд при ударе излучать шоковый заряд, поражающий ближайшие цели.
|
||||||
|
id: AspectLightning
|
||||||
|
noSpawn: true
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Magic/magicactions.rsi
|
||||||
|
state: thunder
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: Блюспейс
|
||||||
|
description: Клинок заклинаний наделяется способностью телепортации на далёкое расстояние.
|
||||||
|
id: AspectBluespace
|
||||||
|
noSpawn: true
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Magic/magicactions.rsi
|
||||||
|
state: blink
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: Магическая Стрела
|
||||||
|
description: Клинок заклинаний наделяется способностью стрелять оглушающей магической стрелой.
|
||||||
|
id: AspectMagicMissile
|
||||||
|
noSpawn: true
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Magic/magicactions.rsi
|
||||||
|
state: magicmissile
|
||||||
@@ -247,3 +247,16 @@
|
|||||||
conditions:
|
conditions:
|
||||||
- !type:ListingLimitedStockCondition
|
- !type:ListingLimitedStockCondition
|
||||||
stock: 1
|
stock: 1
|
||||||
|
|
||||||
|
- type: listing
|
||||||
|
id: SpellBookSpellBlade
|
||||||
|
name: spellbook-spellblade-name
|
||||||
|
description: spellbook-spellblade-desc
|
||||||
|
productEntity: SpellBlade
|
||||||
|
cost:
|
||||||
|
SpellPoint: 2
|
||||||
|
categories:
|
||||||
|
- MagicItems
|
||||||
|
conditions:
|
||||||
|
- !type:ListingLimitedStockCondition
|
||||||
|
stock: 1
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 294 B |
@@ -54,6 +54,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "teleport"
|
"name": "teleport"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "icebeam_active"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user