Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Jabak
2024-06-13 09:07:23 +03:00
87 changed files with 1794 additions and 416 deletions

View File

@@ -3,7 +3,7 @@
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
Title="{Loc 'store-ui-default-title'}"
MinSize="512 512"
SetSize="512 512">
SetSize="768 512">
<BoxContainer Orientation="Vertical">
<BoxContainer Orientation="Vertical" VerticalExpand="True">
<BoxContainer Margin="4,4,4,4" Orientation="Horizontal">

View File

@@ -3,23 +3,19 @@ using Content.Client._White.Cult.UI.TeleportRunesList;
using Content.Client.Eui;
using Content.Shared.Eui;
using Content.Shared._White.Cult.UI;
using JetBrains.Annotations;
namespace Content.Client._White.Cult.UI.TeleportSpell;
public sealed class TeleportSpellEui : BaseEui
[UsedImplicitly]
public sealed class CultTeleportSpellEui : BaseEui
{
private TeleportRunesListWindow _window;
public TeleportSpellEui()
{
_window = new TeleportRunesListWindow();
}
private readonly TeleportRunesListWindow _window = new();
public override void Opened()
{
_window.OpenCentered();
_window.ItemSelected += (index, _) => SendMessage(new TeleportSpellTargetRuneSelected(){RuneUid = index});
_window.ItemSelected += (index, _) => SendMessage(new TeleportSpellTargetRuneSelected {RuneUid = index});
_window.OnClose += () => SendMessage(new CloseEuiMessage());
base.Opened();
@@ -33,7 +29,8 @@ public sealed class TeleportSpellEui : BaseEui
public override void HandleState(EuiStateBase state)
{
if(state is not TeleportSpellEuiState cast) return;
if (state is not CultTeleportSpellEuiState cast)
return;
_window.Clear();
_window.PopulateList(cast.Runes.Keys.ToList(), cast.Runes.Values.ToList());

View 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();
}
}

View File

@@ -0,0 +1,7 @@
using Content.Shared._White.Wizard.SpellBlade;
namespace Content.Client._White.Wizard.SpellBlade;
public sealed class SpellBladeSystem : SharedSpellBladeSystem
{
}

View File

@@ -0,0 +1,39 @@
using System.Linq;
using Content.Client._White.Cult.UI.TeleportRunesList;
using Content.Client.Eui;
using Content.Shared._White.Wizard.Teleport;
using Content.Shared.Eui;
using JetBrains.Annotations;
namespace Content.Client._White.Wizard.TeleportSpell;
[UsedImplicitly]
public sealed class WizardTeleportSpellEui : BaseEui
{
private readonly TeleportRunesListWindow _window = new();
public override void Opened()
{
_window.OpenCentered();
_window.ItemSelected +=
(index, _) => SendMessage(new TeleportSpellTargetLocationSelected {LocationUid = index});
_window.OnClose += () => SendMessage(new CloseEuiMessage());
base.Opened();
}
public override void Closed()
{
base.Closed();
_window.Close();
}
public override void HandleState(EuiStateBase state)
{
if (state is not WizardTeleportSpellEuiState cast)
return;
_window.Clear();
_window.PopulateList(cast.Locations.Keys.ToList(), cast.Locations.Values.ToList());
}
}

View File

@@ -1,6 +1,7 @@
using System.Diagnostics.CodeAnalysis;
using Content.Server.Administration.Logs;
using Content.Server.Atmos.Components;
using Content.Shared._White.Cult.Components;
using Content.Shared.Alert;
using Content.Shared.Atmos;
using Content.Shared.Damage;
@@ -262,7 +263,7 @@ public sealed class BarotraumaSystem : EntitySystem
voidAdaptation.ChemMultiplier = 0.75f;
ActNormalPressure(uid, barotrauma, pressure);
break;
case <= Atmospherics.HazardLowPressure:
case <= Atmospherics.HazardLowPressure when !HasComp<CultBuffComponent>(uid): // WD EDIT
ActLowPressure(uid, barotrauma);
break;
case >= Atmospherics.HazardHighPressure:
@@ -333,4 +334,4 @@ public sealed class BarotraumaSystem : EntitySystem
break;
}
}
}
}

View File

@@ -1,3 +1,4 @@
using Content.Server._White.Wizard.SpellBlade;
using Content.Server.Administration.Logs;
using Content.Server.Atmos.Components;
using Content.Server.IgnitionSource;
@@ -49,6 +50,7 @@ namespace Content.Server.Atmos.EntitySystems
[Dependency] private readonly UseDelaySystem _useDelay = default!;
[Dependency] private readonly AudioSystem _audio = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly SpellBladeSystem _spellBlade = default!; // WD
public const float MinimumFireStacks = -10f;
public const float MaximumFireStacks = 20f;
@@ -84,13 +86,19 @@ namespace Content.Server.Atmos.EntitySystems
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)
{
if (!TryComp<FlammableComponent>(entity, out var flammable))
continue;
AdjustFireStacks(entity, component.FireStacks, flammable);
if (component.FireStacks >= 0)
AdjustFireStacks(entity, fireStacks, flammable); // WD EDIT
if (fireStacks >= 0) // WD EDIT
Ignite(entity, args.Weapon, flammable, args.User);
}
}
@@ -203,8 +211,15 @@ namespace Content.Server.Atmos.EntitySystems
if (!flammable.OnFire && !otherFlammable.OnFire)
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 (weHold && !theyHold || theyHold && !weHold) // WD
return;
// Both are on fire -> equalize fire stacks.
var avg = (flammable.FireStacks + otherFlammable.FireStacks) / 2;
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.
if (flammable.OnFire)
{
if (theyHold) // WD
return;
otherFlammable.FireStacks += flammable.FireStacks / 2;
Ignite(otherUid, uid, otherFlammable);
if (flammable.CanExtinguish)
@@ -227,6 +244,8 @@ namespace Content.Server.Atmos.EntitySystems
}
else
{
if (weHold) // WD
return;
flammable.FireStacks += otherFlammable.FireStacks / 2;
Ignite(uid, otherUid, flammable);
if (otherFlammable.CanExtinguish)
@@ -436,7 +455,8 @@ namespace Content.Server.Atmos.EntitySystems
if (TryComp(uid, out TemperatureComponent? 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);
}

View File

@@ -1,5 +1,6 @@
using System.Linq;
using System.Numerics;
using Content.Server._White.Wizard.Magic;
using Content.Server.Body.Components;
using Content.Server.Body.Systems;
using Content.Server.Chat.Systems;
@@ -44,6 +45,7 @@ public sealed class MagicSystem : EntitySystem
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly ChatSystem _chat = default!;
[Dependency] private readonly WizardSpellsSystem _wizardSpells = default!;
public override void Initialize()
{
@@ -157,7 +159,7 @@ public sealed class MagicSystem : EntitySystem
private void OnKnockSpell(KnockSpellEvent args)
{
if (args.Handled)
if (!_wizardSpells.CanCast(args)) // WD EDIT
return;
args.Handled = true;
@@ -180,7 +182,7 @@ public sealed class MagicSystem : EntitySystem
private void OnSmiteSpell(SmiteSpellEvent ev)
{
if (ev.Handled)
if (!_wizardSpells.CanCast(ev)) // WD EDIT
return;
ev.Handled = true;

View File

@@ -1,4 +1,5 @@
using System.Linq;
using Content.Server._White.Wizard.SpellBlade;
using Content.Server.Administration.Logs;
using Content.Server.Atmos.Components;
using Content.Server.Atmos.EntitySystems;
@@ -22,6 +23,7 @@ public sealed class TemperatureSystem : EntitySystem
[Dependency] private readonly AtmosphereSystem _atmosphere = default!;
[Dependency] private readonly DamageableSystem _damageable = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly SpellBladeSystem _spellBlade = default!; // WD
/// <summary>
/// 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)
{
// 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)
{
_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)
{
if (TryComp(uid, out VoidAdaptationComponent? voidAdaptation)) // WD
// WD START
if (TryComp(uid, out VoidAdaptationComponent? voidAdaptation))
{
if (temperature.TakingDamage)
{
@@ -291,6 +305,17 @@ public sealed class TemperatureSystem : EntitySystem
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)
{
_adminLogger.Add(LogType.Temperature, $"{ToPrettyString(uid):entity} started taking low temperature damage");

View File

@@ -1,3 +1,4 @@
using Content.Server._White.Wizard.SpellBlade;
using Content.Server.Temperature.Components;
using Content.Server.Temperature.Systems;
using Content.Shared.Changeling;
@@ -10,6 +11,7 @@ namespace Content.Server._White.ChangeTemperatureOnCollide;
public sealed class LowTemperatureSlowdownSystem : EntitySystem
{
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifierSystem = default!;
[Dependency] private readonly SpellBladeSystem _spellBlade = default!;
public override void Initialize()
{
@@ -22,7 +24,8 @@ public sealed class LowTemperatureSlowdownSystem : EntitySystem
private void OnMoveSpeedRefresh(EntityUid uid, TemperatureComponent component,
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
: GetSpeedModifier(component.CurrentTemperature);
args.ModifySpeed(modifier, modifier);
@@ -32,7 +35,7 @@ public sealed class LowTemperatureSlowdownSystem : EntitySystem
OnTemperatureChangeEvent args)
{
// ReSharper disable once CompareOfFloatsByEqualityOperator
if(GetSpeedModifier(args.LastTemperature) == GetSpeedModifier(args.CurrentTemperature))
if (GetSpeedModifier(args.LastTemperature) == GetSpeedModifier(args.CurrentTemperature))
return;
_movementSpeedModifierSystem.RefreshMovementSpeedModifiers(uid, component);

View File

@@ -1,6 +1,6 @@
using Content.Server._White.Cult.Items.Components;
using Content.Server._White.Cult.TimedProduction;
using Content.Shared._White.Cult;
using Content.Shared._White.Cult.Components;
using Content.Shared._White.Cult.Pylon;
using Robust.Shared.Physics.Events;
using CultistComponent = Content.Shared._White.Cult.Components.CultistComponent;

View File

@@ -3,6 +3,7 @@ using System.Numerics;
using Content.Server.Atmos.Piping.Other.Components;
using Content.Server.Body.Components;
using Content.Server.Body.Systems;
using Content.Shared._White.Cult.Components;
using Content.Shared.Damage;
using Content.Shared.Doors.Components;
using Content.Shared.Interaction;

View File

@@ -148,7 +148,7 @@ public partial class CultSystem
_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);
eui.StateDirty();

View File

@@ -11,6 +11,7 @@ using Content.Shared.Mobs.Components;
using Content.Shared.Physics;
using Content.Shared.StatusEffect;
using Content.Shared._White.Cult;
using Content.Shared._White.Cult.Components;
namespace Content.Server._White.Cult.Runes.Systems;

View File

@@ -37,7 +37,6 @@ using Content.Shared._White.Cult.Components;
using Content.Shared._White.Cult.Runes;
using Content.Shared._White.Cult.UI;
using Content.Shared.Cuffs;
using Content.Shared.FixedPoint;
using Content.Shared.GameTicking;
using Content.Shared.Mindshield.Components;
using Content.Shared.Mobs.Systems;
@@ -597,13 +596,14 @@ public sealed partial class CultSystem : EntitySystem
private bool AddCultistBuff(EntityUid target, EntityUid user)
{
if (HasComp<CultBuffComponent>(target))
if (TryComp<CultBuffComponent>(target, out var buff) && buff.BuffTime > buff.BuffLimit)
{
_popupSystem.PopupEntity(Loc.GetString("cult-buff-already-buffed"), user, user);
return false;
}
EnsureComp<CultBuffComponent>(target);
buff = EnsureComp<CultBuffComponent>(target);
buff.BuffTime = buff.StartingBuffTime;
return true;
}
@@ -631,6 +631,18 @@ public sealed partial class CultSystem : EntitySystem
}
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 list = new List<int>();
@@ -641,7 +653,7 @@ public sealed partial class CultSystem : EntitySystem
if (teleportComponent.Label == null)
continue;
if (runeUid == rune)
if (runeUid == exceptRune)
continue;
if (!int.TryParse(runeUid.ToString(), out var intValue))
@@ -665,10 +677,6 @@ public sealed partial class CultSystem : EntitySystem
return false;
}
_entityManager.EnsureComponent<CultTeleportRuneProviderComponent>(user, out var providerComponent);
providerComponent.Targets = victims;
providerComponent.BaseRune = rune;
_ui.SetUiState(ui, new TeleportRunesListWindowBUIState(list, labels));
if (_ui.IsUiOpen(user, ui.UiKey))
@@ -868,7 +876,10 @@ public sealed partial class CultSystem : EntitySystem
return false;
if (!_mobState.IsDead(target, mobState))
{
_popupSystem.PopupEntity(Loc.GetString("cult-revive-rune-already-alive"), user, user);
return false;
}
var airlossGroup = _prototypeManager.Index<DamageGroupPrototype>("Airloss");
@@ -878,7 +889,10 @@ public sealed partial class CultSystem : EntitySystem
{
var afterHeal = damageable.TotalDamage - toHeal;
if (deadThreshold <= afterHeal)
{
_popupSystem.PopupEntity(Loc.GetString("cult-revive-rune-too-damaged"), user, user);
return false;
}
var asphyxType = _prototypeManager.Index<DamageTypePrototype>("Asphyxiation");
var bloodlossType = _prototypeManager.Index<DamageTypePrototype>("Bloodloss");

View File

@@ -10,7 +10,7 @@ using Robust.Shared.Timing;
namespace Content.Server._White.Cult.UI;
public sealed class TeleportSpellEui : BaseEui
public sealed class CultTeleportSpellEui : BaseEui
{
[Dependency] private readonly EntityManager _entityManager = default!;
private readonly SharedTransformSystem _transformSystem;
@@ -22,7 +22,7 @@ public sealed class TeleportSpellEui : BaseEui
private bool _used;
public TeleportSpellEui(EntityUid performer, EntityUid target)
public CultTeleportSpellEui(EntityUid performer, EntityUid target)
{
IoCManager.InjectDependencies(this);
@@ -39,7 +39,7 @@ public sealed class TeleportSpellEui : BaseEui
public override EuiStateBase GetNewState()
{
var runesQuery = _entityManager.EntityQueryEnumerator<CultRuneTeleportComponent>();
var state = new TeleportSpellEuiState();
var state = new CultTeleportSpellEuiState();
while (runesQuery.MoveNext(out var runeUid, out var rune))
{
@@ -110,4 +110,4 @@ public sealed class TeleportSpellEui : BaseEui
_transformSystem.SetCoordinates(_target, runeTransform.Coordinates);
Close();
}
}
}

View File

@@ -1,5 +1,5 @@
using System.Diagnostics;
using Content.Server._White.Cult.Structures;
using Content.Shared._White.Cult.Structures;
using Content.Shared._White.Keyhole.Components;
using Content.Shared._White.Keyhole;
using Content.Shared.DoAfter;
@@ -120,4 +120,4 @@ public sealed class KeyholeSystem : EntitySystem
_popupSystem.PopupEntity(Loc.GetString("key-pressed-in-keyform-message", ("user", user), ("key", uid)), uid);
}
}
}
}

View File

@@ -105,7 +105,7 @@ public sealed class WizardSpellsSystem : EntitySystem
if (!TryComp(msg.Performer, out ActorComponent? actor))
return;
var eui = new TeleportSpellEui(msg.Performer);
var eui = new WizardTeleportSpellEui(msg.Performer);
_euiManager.OpenEui(eui, actor.PlayerSession);
eui.StateDirty();
@@ -736,7 +736,7 @@ public sealed class WizardSpellsSystem : EntitySystem
RaiseLocalEvent(uid, new EnergyDomeClothesTurnOffEvent());
}
private bool CanCast(BaseActionEvent msg)
public bool CanCast(BaseActionEvent msg)
{
return !msg.Handled && CheckRequirements(msg.Action, msg.Performer) &&
!_statusEffectsSystem.HasStatusEffect(msg.Performer, "Incorporeal");

View File

@@ -0,0 +1,6 @@
namespace Content.Server._White.Wizard.SpellBlade;
[RegisterComponent]
public sealed partial class FireAspectComponent : Component
{
}

View File

@@ -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;
}

View File

@@ -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;
}

View 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);
}
}

View File

@@ -1,11 +1,17 @@
using Content.Server.Pinpointer;
using Content.Server.Station.Systems;
using Content.Server.Warps;
using Content.Shared.Coordinates.Helpers;
using Content.Shared.Maps;
using Content.Shared.Physics;
namespace Content.Server._White.Wizard.Teleport;
public sealed class TeleportLocationSystem : EntitySystem
{
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly TurfSystem _turf = default!;
public override void Initialize()
{
@@ -20,10 +26,30 @@ public sealed class TeleportLocationSystem : EntitySystem
if (!TryComp(ent, out WarpPointComponent? warpPoint) || warpPoint.Location == null)
return;
var newEnt = Spawn(null, Transform(ent).Coordinates);
var xForm = EnsureComp<TransformComponent>(newEnt);
_transformSystem.AttachToGridOrMap(newEnt, xForm);
var xForm = Transform(ent);
if (!CanTeleport(ent, xForm))
return;
var newEnt = Spawn(null, xForm.Coordinates);
var newXForm = EnsureComp<TransformComponent>(newEnt);
_transformSystem.AttachToGridOrMap(newEnt, newXForm);
var location = EnsureComp<TeleportLocationComponent>(newEnt);
location.Location = warpPoint.Location;
}
public bool CanTeleport(EntityUid uid, TransformComponent xForm)
{
var station = _station.GetOwningStation(uid, xForm);
if (!HasComp<TeleportLocationTargetStationComponent>(station))
return false;
var turf = xForm.Coordinates.SnapToGrid(EntityManager).GetTileRef(EntityManager);
if (turf == null)
return false;
return !_turf.IsTileBlocked(turf.Value, CollisionGroup.Impassable);
}
}

View File

@@ -0,0 +1,6 @@
namespace Content.Server._White.Wizard.Teleport;
[RegisterComponent]
public sealed partial class TeleportLocationTargetStationComponent : Component
{
}

View File

@@ -0,0 +1,95 @@
using Content.Server.EUI;
using Content.Server.Popups;
using Content.Shared._White.Wizard.Teleport;
using Content.Shared.Eui;
using Robust.Shared.Timing;
namespace Content.Server._White.Wizard.Teleport;
public sealed class WizardTeleportSpellEui : BaseEui
{
[Dependency] private readonly EntityManager _entityManager = default!;
private readonly SharedTransformSystem _transformSystem;
private readonly TeleportLocationSystem _teleportLocation;
private readonly PopupSystem _popupSystem;
private readonly EntityUid _performer;
private bool _used;
public WizardTeleportSpellEui(EntityUid performer)
{
IoCManager.InjectDependencies(this);
_transformSystem = _entityManager.System<SharedTransformSystem>();
_teleportLocation = _entityManager.System<TeleportLocationSystem>();
_popupSystem = _entityManager.System<PopupSystem>();
_performer = performer;
Timer.Spawn(TimeSpan.FromSeconds(60), Close);
}
public override EuiStateBase GetNewState()
{
var locationQuery = _entityManager.EntityQueryEnumerator<TeleportLocationComponent, TransformComponent>();
var state = new WizardTeleportSpellEuiState();
while (locationQuery.MoveNext(out var locationUid, out var locationComponent, out var transformComponent))
{
if (_teleportLocation.CanTeleport(locationUid, transformComponent))
state.Locations.Add((int) locationUid, locationComponent.Location);
}
return state;
}
public override void HandleMessage(EuiMessageBase msg)
{
base.HandleMessage(msg);
if (_used)
{
return;
}
if (msg is not TeleportSpellTargetLocationSelected cast)
{
return;
}
var transform = _entityManager.GetComponent<TransformComponent>(_performer);
var oldCoords = transform.Coordinates;
TransformComponent? locationTransform = null;
var teleportLocationQuery = _entityManager
.EntityQueryEnumerator<TeleportLocationComponent, TransformComponent>();
while (teleportLocationQuery.MoveNext(out var locationUid, out _, out var transformComponent))
{
if (locationUid == new EntityUid(cast.LocationUid))
{
locationTransform = transformComponent;
}
}
if (locationTransform is null)
{
_popupSystem.PopupEntity("Can't teleport", _performer, _performer);
DoStateUpdate();
return;
}
_used = true;
var coords = locationTransform.Coordinates;
_transformSystem.SetCoordinates(_performer, coords);
_transformSystem.AttachToGridOrMap(_performer, transform);
_entityManager.SpawnEntity("AdminInstantEffectSmoke10", oldCoords);
_entityManager.SpawnEntity("AdminInstantEffectSmoke10", coords);
Close();
}
}

View File

@@ -14,7 +14,7 @@ public sealed partial class WizardRuleComponent : Component
{
public readonly List<EntityUid> WizardMinds = new();
[ViewVariables(VVAccess.ReadWrite)]
[ViewVariables]
public EntityUid? TargetStation;
[DataField("minPlayers")]

View File

@@ -310,7 +310,7 @@ public sealed class WizardRuleSystem : GameRuleSystem<WizardRuleComponent>
if (meta.EntityPrototype?.ID != component.SpawnPointProto.Id)
continue;
if (xform.ParentUid != component.ShuttleMap)
if (xform.MapUid != component.ShuttleMap)
continue;
spawn = xform.Coordinates;

View File

@@ -24,7 +24,7 @@ public sealed partial class ChangelingComponent : Component
public float Accumulator;
[ViewVariables(VVAccess.ReadOnly)]
public float UpdateDelay = 8f;
public float UpdateDelay = 6f;
[ViewVariables(VVAccess.ReadOnly)]
public bool IsRegenerating;

View File

@@ -1,4 +1,5 @@
using System.Linq;
using Content.Shared._White.Cult.Structures;
using Content.Shared._White.Keyhole.Components;
using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
@@ -41,6 +42,7 @@ public abstract partial class SharedDoorSystem : EntitySystem
[Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!;
[Dependency] private readonly PryingSystem _pryingSystem = default!;
[Dependency] protected readonly SharedPopupSystem Popup = default!;
[Dependency] private readonly RunicDoorSystem _runicDoor = default!; // WD
[ValidatePrototypeId<TagPrototype>]
public const string DoorBumpTag = "DoorBumpOpener";
@@ -649,6 +651,9 @@ public abstract partial class SharedDoorSystem : EntitySystem
var otherUid = args.OtherEntity;
if (!_runicDoor.CanBumpOpen(uid, otherUid)) // WD
return;
if (Tags.HasTag(otherUid, DoorBumpTag))
TryOpen(uid, door, otherUid, quiet: door.State == DoorState.Denying);
}
@@ -762,6 +767,9 @@ public abstract partial class SharedDoorSystem : EntitySystem
{
foreach (var other in PhysicsSystem.GetContactingEntities(uid, physics, approximate: true))
{
if (!_runicDoor.CanBumpOpen(uid, other)) // WD
continue;
if (Tags.HasTag(other, DoorBumpTag) && TryOpen(uid, door, other, quiet: true))
break;
}

View File

@@ -533,6 +533,11 @@ public abstract partial class SharedGunSystem : EntitySystem
Dirty(gun);
}
// WD EDIT
public void SetUseKey(GunComponent gun, bool useKey)
{
gun.UseKey = useKey;
}
public void SetProjectileSpeed(EntityUid weapon, float projectileSpeed)
{
if(!TryComp<GunComponent>(weapon, out var gunComponent))

View File

@@ -1,10 +1,11 @@
using System.Numerics;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared._White.BetrayalDagger;
[RegisterComponent]
[RegisterComponent, NetworkedComponent]
public sealed partial class BlinkComponent : Component
{
[DataField, ViewVariables(VVAccess.ReadWrite)]

View File

@@ -1,6 +1,6 @@
using Robust.Shared.Prototypes;
namespace Content.Server._White.Cult;
namespace Content.Shared._White.Cult.Components;
[RegisterComponent]
public sealed partial class ConstructComponent : Component

View File

@@ -3,10 +3,16 @@ namespace Content.Shared._White.Cult.Components;
[RegisterComponent]
public sealed partial class CultBuffComponent : Component
{
[ViewVariables(VVAccess.ReadOnly), DataField("buffTime")]
[ViewVariables(VVAccess.ReadOnly), DataField]
public TimeSpan BuffTime = TimeSpan.FromSeconds(60);
[ViewVariables(VVAccess.ReadOnly), DataField]
public TimeSpan StartingBuffTime = TimeSpan.FromSeconds(60);
[ViewVariables(VVAccess.ReadOnly), DataField]
public TimeSpan BuffLimit = TimeSpan.FromSeconds(55);
public static float NearbyTilesBuffRadius = 1f;
public static readonly TimeSpan CultTileBuffTime = TimeSpan.FromSeconds(5);
public static readonly TimeSpan CultTileBuffTime = TimeSpan.FromSeconds(1);
}

View File

@@ -1,4 +1,4 @@
namespace Content.Server._White.Cult.Structures;
namespace Content.Shared._White.Cult.Structures;
[RegisterComponent]
public sealed partial class RunicDoorComponent : Component

View File

@@ -1,13 +1,13 @@
using Content.Server.Cuffs;
using Content.Server.Doors.Systems;
using Content.Shared._White.Chaplain;
using Content.Shared._White.Chaplain;
using Content.Shared.Doors;
using Content.Shared.Humanoid;
using Content.Shared.Stunnable;
using Content.Shared._White.Cult.Components;
using Content.Shared._White.Cult.Systems;
using Content.Shared.Cuffs;
using Content.Shared.Cuffs.Components;
using Content.Shared.Doors.Components;
using Content.Shared.Doors.Systems;
using Content.Shared.Mobs.Systems;
using Content.Shared.Prying.Components;
using Content.Shared.Weapons.Melee.Components;
@@ -18,17 +18,18 @@ using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
using CultistComponent = Content.Shared._White.Cult.Components.CultistComponent;
namespace Content.Server._White.Cult.Structures;
namespace Content.Shared._White.Cult.Structures;
public sealed class RunicDoorSystem : EntitySystem
{
[Dependency] private readonly DoorSystem _doorSystem = default!;
[Dependency] private readonly SharedDoorSystem _doorSystem = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly SharedStunSystem _stunSystem = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly OccluderSystem _occluder = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly CuffableSystem _cuffable = default!;
[Dependency] private readonly SharedCuffableSystem _cuffable = default!;
[Dependency] private readonly HolyWeaponSystem _holyWeapon = default!;
public override void Initialize()
@@ -125,7 +126,7 @@ public sealed class RunicDoorSystem : EntitySystem
TryComp(airlock, out ConcealableComponent? concealable) && concealable.Concealed)
return false;
var direction = Transform(user).MapPosition.Position - Transform(airlock).MapPosition.Position;
var direction = _transform.GetMapCoordinates(user).Position - _transform.GetMapCoordinates(airlock).Position;
var impulseVector = direction * 2000;
_physics.ApplyLinearImpulse(user, impulseVector);

View File

@@ -4,7 +4,7 @@ using Robust.Shared.Serialization;
namespace Content.Shared._White.Cult.UI;
[Serializable, NetSerializable]
public sealed class TeleportSpellEuiState : EuiStateBase
public sealed class CultTeleportSpellEuiState : EuiStateBase
{
public Dictionary<int, string> Runes = new();
}

View File

@@ -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>);
}
}

View File

@@ -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
}

View File

@@ -0,0 +1,16 @@
using Content.Shared.Eui;
using Robust.Shared.Serialization;
namespace Content.Shared._White.Wizard.Teleport;
[Serializable, NetSerializable]
public sealed class WizardTeleportSpellEuiState : EuiStateBase
{
public Dictionary<int, string> Locations = new();
}
[Serializable, NetSerializable]
public sealed class TeleportSpellTargetLocationSelected : EuiMessageBase
{
public int LocationUid;
}

Binary file not shown.

View File

@@ -4143,3 +4143,131 @@
id: 292
time: '2024-06-09T16:26:49.0000000+00:00'
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/342
- author: Valtos
changes:
- message: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u043E 13 \u043D\u043E\
\u0432\u044B\u0445 \u0433\u043E\u043B\u043E\u0441\u043E\u0432 TTS."
type: Add
id: 293
time: '2024-06-09T21:30:35.0000000+00:00'
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/344
- author: Aviu
changes:
- message: "\u041A\u043D\u0438\u0433\u0430 \u0437\u0430\u043A\u043B\u0438\u043D\u0430\
\u043D\u0438\u0439 \u0434\u043B\u044F \u043C\u0430\u0433\u0430."
type: Add
- message: "\u0412\u044B\u0441\u043E\u043A\u043E\u0447\u0430\u0441\u0442\u043E\u0442\
\u043D\u044B\u0439 \u043A\u043B\u0438\u043D\u043E\u043A \u0443\u0441\u0438\u043B\
\u0435\u043D, \u0443\u0431\u0440\u0430\u043D \u0438\u0437 \u043D\u0443\u043B\
\u0440\u043E\u0434\u0430 \u0438 \u043F\u0435\u0440\u0435\u043C\u0435\u0449\u0435\
\u043D \u0432 \u043A\u043D\u0438\u0433\u0443 \u0437\u0430\u043A\u043B\u0438\u043D\
\u0430\u043D\u0438\u0439."
type: Add
- message: "\u0412 \u0441\u043A\u0430\u0444\u0430\u043D\u0434\u0440\u0435 \u043C\
\u0430\u0433\u0430 \u0442\u0435\u043F\u0435\u0440\u044C \u043C\u043E\u0436\u043D\
\u043E \u043A\u0430\u0441\u0442\u043E\u0432\u0430\u0442\u044C \u0432\u0441\u0435\
\ \u0437\u0430\u043A\u043B\u0438\u043D\u0430\u043D\u0438\u044F."
type: Add
- message: "\u0421\u043A\u0430\u0444\u0430\u043D\u0434\u0440 \u043C\u0430\u0433\u0430\
\ \u0443\u0431\u0440\u0430\u043D \u0441 \u0448\u0430\u0442\u0442\u043B\u0430\
\ \u043C\u0430\u0433\u0430 \u0438 \u043F\u0435\u0440\u0435\u043C\u0435\u0449\
\u0435\u043D \u0432 \u043A\u043D\u0438\u0433\u0443 \u0437\u0430\u043A\u043B\u0438\
\u043D\u0430\u043D\u0438\u0439."
type: Add
- message: "\u0421\u0432\u0438\u0442\u043E\u043A \u043A\u0430\u0440\u044B."
type: Add
- message: "\u0423\u0431\u0440\u0430\u043D\u044B \u0432\u0441\u0435 \u0441\u0432\
\u0438\u0442\u043A\u0438 \u043A\u0440\u043E\u043C\u0435 \u0442\u0435\u043B\u0435\
\u043F\u043E\u0440\u0442\u0430\u0446\u0438\u0438 \u0441 \u0448\u0430\u0442\u0442\
\u043B\u0430 \u043C\u0430\u0433\u0430."
type: Remove
id: 294
time: '2024-06-10T10:57:32.0000000+00:00'
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/345
- author: Aviu
changes:
- message: "\u041A\u043B\u0438\u043D\u043E\u043A \u0437\u0430\u043A\u043B\u0438\u043D\
\u0430\u043D\u0438\u0439 \u0443\u0441\u0438\u043B\u0435\u043D \u0438 \u043F\u0435\
\u0440\u0435\u043C\u0435\u0449\u0435\u043D \u0438\u0437 \u043D\u0443\u043B\u0440\
\u043E\u0434\u0430 \u0432 \u043A\u043D\u0438\u0433\u0443 \u0437\u0430\u043A\u043B\
\u0438\u043D\u0430\u043D\u0438\u0439."
type: Add
- message: "\u0422\u0435\u043F\u0435\u0440\u044C \u043C\u043E\u0436\u043D\u043E\
\ \u0443\u0441\u0438\u043B\u0438\u0442\u044C \u043A\u043B\u0438\u043D\u043E\u043A\
\ \u0437\u0430\u043A\u043B\u0438\u043D\u0430\u043D\u0438\u0439, \u0432\u044B\
\u0431\u0440\u0430\u0432 1 \u0438\u0437 5 \u0430\u0441\u043F\u0435\u043A\u0442\
\u043E\u0432."
type: Add
- message: "\u0424\u0438\u043A\u0441 \u043D\u0435\u0440\u0430\u0431\u043E\u0442\u0430\
\u044E\u0449\u0435\u0433\u043E \u0437\u0430\u043A\u043B\u0438\u043D\u0430\u043D\
\u0438\u044F \u0442\u0435\u043B\u0435\u043F\u043E\u0440\u0442\u0430 \u043A\u0443\
\u043B\u044C\u0442\u0430."
type: Fix
id: 295
time: '2024-06-11T20:07:47.0000000+00:00'
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/346
- author: Aviu
changes:
- message: "\u0422\u0435\u043F\u0435\u0440\u044C \u0440\u0435\u0433\u0435\u043D\u0435\
\u0440\u0430\u0446\u0438\u044E \u0442\u043A\u0430\u043D\u0435\u0439 \u0438 \u0430\
\u0434\u0440\u0435\u043D\u0430\u043B\u0438\u043D \u043C\u043E\u0436\u043D\u043E\
\ \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u0432\
\ \u043A\u0440\u0438\u0442\u0435 \u0438 \u0432 \u0441\u0442\u0430\u043D\u0435\
."
type: Add
- message: "\u0423\u043C\u0435\u043D\u044C\u0448\u0435\u043D\u043E \u043A\u043E\u043B\
\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u043F\u0447\u0435\u043B \u0438\u0437\
\ \u0433\u043E\u043B\u043E\u0432\u044B \u0443\u043B\u044C\u044F \u043E\u0431\
\u0440\u0430\u0442\u043D\u043E \u0434\u043E 4."
type: Tweak
- message: "\u041D\u0435\u043C\u043D\u043E\u0433\u043E \u0443\u0435\u043B\u0438\u0447\
\u0435\u043D\u0430 \u0441\u043A\u043E\u0440\u043E\u0441\u0442\u044C \u0440\u0435\
\u0433\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u0438 \u0445\u0438\u043C\u0438\
\u043A\u0430\u0442\u043E\u0432."
type: Tweak
- message: "\u0424\u0438\u043A\u0441 \u043A\u0440\u0438\u0432\u043E\u0433\u043E\
\ \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F \u0430\u043B\
\u0435\u0440\u0442\u0430 \u0445\u0438\u043C\u0438\u043A\u0430\u0442\u043E\u0432\
\ \u0433\u0435\u043D\u043E\u043A\u0440\u0430\u0434\u0430."
type: Fix
id: 296
time: '2024-06-12T10:56:44.0000000+00:00'
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/347
- author: Aviu
changes:
- message: "\u0411\u0430\u0444\u0444 \u043A\u0443\u043B\u044C\u0442\u0430 \u0442\
\u0435\u043F\u0435\u0440\u044C \u0441\u043F\u0430\u0441\u0430\u0435\u0442 \u043E\
\u0442 \u043D\u0438\u0437\u043A\u043E\u0433\u043E \u0434\u0430\u0432\u043B\u0435\
\u043D\u0438\u044F."
type: Add
- message: "\u0414\u0432\u0435\u0440\u044C \u043A\u0443\u043B\u044C\u0442\u0430\
\ \u0442\u0435\u043F\u0435\u0440\u044C \u043F\u0440\u0435\u0434\u0438\u043A\u0442\
\u0435\u0434."
type: Add
- message: "\u041F\u0438\u043B\u043E\u043D \u0431\u043E\u043B\u044C\u0448\u0435\
\ \u043D\u0435 \u0432\u044B\u0440\u0430\u0431\u0430\u0442\u044B\u0432\u0430\u0435\
\u0442 \u043A\u0438\u0441\u043B\u043E\u0440\u043E\u0434."
type: Remove
- message: "\u0423\u043C\u0435\u043D\u044C\u0448\u0435\u043D\u043E \u0432\u0440\u0435\
\u043C\u044F \u0431\u0430\u0444\u0444\u0430 \u043E\u0442 \u043D\u0430\u0445\u043E\
\u0436\u0434\u0435\u043D\u0438\u044F \u043D\u0430 \u0442\u0430\u0439\u043B\u0435\
\ \u043A\u0443\u043B\u044C\u0442\u0430 \u0434\u043E 1 \u0441\u0435\u043A\u0443\
\u043D\u0434\u044B."
type: Tweak
- message: "\u0414\u0432\u0435\u0440\u044C \u043A\u0443\u043B\u044C\u0442\u0430\
\ \u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0435 \u043E\u0442\u043A\u0440\
\u044B\u0432\u0430\u0435\u0442\u0441\u044F, \u043A\u043E\u0433\u0434\u0430 \u043E\
\u043D\u0430 \u043D\u0435 \u0434\u043E\u043B\u0436\u043D\u0430."
type: Fix
id: 297
time: '2024-06-12T16:00:45.0000000+00:00'
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/348
- author: Warete
changes:
- message: "\u041F\u0435\u0440\u0435\u0432\u043E\u0434 \u0438 \u0432\u044B\u043D\
\u043E\u0441 \u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0451\u043D\u043D\u044B\
\u0445 \u043F\u043B\u0430\u043A\u0430\u0442\u043E\u0432"
type: Fix
id: 298
time: '2024-06-12T20:28:18.0000000+00:00'
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/349

View File

@@ -1,4 +1,4 @@
soul-shard-name = Душа { $soul }
soul-shard-name = Душа { $soul }
soul-shard-description = В этом камне заключена душа { $soul }
cult-too-much-empowers = Слишком много способностей
@@ -25,6 +25,7 @@ cult-ritual-prevented = Кто-то прервал ритуал.
cult-narsie-summoned = НАР'СИ ВОССТАЛ!
cult-revive-rune-already-alive = Он уже живой.
cult-revive-rune-no-charges = У рун воскрешения кончились заряды.
cult-revive-rune-too-damaged = Его ранения несовместимы с жизнью.
cult-summon-rune-need-minimum-cultists = Необходимо минимум 2 культиста.
cult-cultists-not-found = Культисты не обнаружены.
cult-blood-boil-rune-need-minimum = Необходимо минимум 3 культиста.

View File

@@ -45,7 +45,7 @@ ent-OfferingRune = руна предпонесения
.desc = Мгновенно превращает обычного члена экипажа в культиста, для чего требуется 2 культиста вокруг руны. Члена экипажа с имплантом защиты разума нельзя перевоплотить, можно только принести в жертву, для чего нужно 3 культиста, которые встанут вокруг руны. Если цель мертва, то она будет принесена в жертву, для чего требуется 1 культист.
ent-BuffRune = руна усиления
.desc = При активации усиливает вас, уменьшая затраты и ускоряя процесс подготовки заклинаний крови и черчения рун.
.desc = При активации усиливает вас, уменьшая затраты и ускоряя процесс подготовки заклинаний крови и черчения рун. Усиление также даёт иммунитет к низкому давлению.
ent-EmpoweringRune = руна могущества
.desc = Позволяет культистам приготовить до 5 заклинаний крови.

View File

@@ -15,6 +15,7 @@ scroll-component-clown = бананы
scroll-component-silence = тишину
scroll-component-recall = призыв
scroll-component-teleport = телепортацию
scroll-component-smite = кару
ent-BaseScroll = магический свиток
.desc = Этот древний пергамент, ставший реликвией в арканных преданиях, хранит в себе бесчисленные мистические заклятия и забытые заклинания.

View File

@@ -11,7 +11,7 @@ roles-antag-wizard-objective = Устройте хаос на станции
wizard-round-end-agent-name = космический волшебник
wizard-welcome = Вы - космический волшебник. Федерация Космических Волшебников отправила вас на станцию {$station}, дабы посеять хаос. Вы можете попасть на станцию с помощью гиперпрыжка или с помощью магии телепортации.
wizard-welcome = Вы - космический волшебник. Федерация Космических Волшебников отправила вас на станцию {$station}, дабы посеять хаос. Не разочаруйте их.
wizard-no-more-threat-announcement-shuttle-call = Судя по данным наших датчиков дальнего действия, магическая угроза была устранена. Эвакуационный шаттл скоро прибудет. Время прибытия: {$time} {$units}. Вы можете отозвать его, чтобы продлить смену.
wizard-no-more-threat-announcement = Судя по данным наших датчиков дальнего действия, магическая угроза была устранена. Шаттл уже вызван.
@@ -20,3 +20,13 @@ magic-component-missing-req = Недостающие требования! Ва
ent-WizardSurviveObjective = Переживете смену, устроив как можно больше хаоса.
.desc = Федерация Космических Волшебников отправила вас на станцию Nanotrasen, чтобы навести там смуту. Не разочаруйте их.
ent-SpellBook = книга заклинаний
.desc = Неземной фолиант, излучающий силу.
store-currency-display-spell-point = Очки заклинаний
store-category-spells-attack = Атакующие заклинания
store-category-spells-defence = Защитные заклинания
store-category-spells-utility = Вспомогательные заклинания
store-category-magic-items = Магические предметы

View File

@@ -112,4 +112,4 @@ alerts-changeling-chemicals-name = Химикаты
alerts-changeling-chemicals-desc = Наши химикаты.
alerts-cult-buff-name = Усиление
alerts-cult-buff-desc = Подготовка заклинаний крови занимает гораздо меньше времени, и вы не теряете столько крови при этом.
alerts-cult-buff-desc = Подготовка заклинаний крови занимает гораздо меньше времени, и вы не теряете столько крови при этом. Также вы неуязвимы к низкому давлению.

View File

@@ -154,7 +154,7 @@ ghost-role-information-onestar-mecha-description = Вы - эксперимент
ghost-role-information-onestar-mecha-rules = Используйте свое оружие, чтобы сеять хаос. Вы - антагонист.
ghost-role-information-remilia-name = Ремилия, фамильяр священника
ghost-role-information-remilia-description = Повинуйтесь своему хозяину. Ешь хаос.
ghost-role-information-remilia-description = Повинуйтесь своему хозяину. Ешьте фрукты.
ghost-role-information-remilia-rules = Вы - умная фруктовая летучая мышь. Следуйте за священником повсюду. Не создавайте никаких проблем, если только священник не прикажет вам это сделать.
ghost-role-information-cerberus-name = Цербер, злой фамильяр

View File

@@ -14,6 +14,8 @@ ent-AnomalyLocator = локатор аномалий
.desc = Устройство, предназначенное для помощи в обнаружении аномалий. Вы проверяли шахтеров?
ent-AnomalyLocatorEmpty = { ent-AnomalyLocator }
.desc = { ent-AnomalyLocator.desc }
ent-AnomalyScanner = сканер аномалий
.desc = Ручной сканер, предназначенный для сбора информации о различных аномальных объектах.
ent-TechnologyDiskRare = { ent-TechnologyDisk }
.desc = { ent-TechnologyDisk.desc }
ent-VendingMachineRestockChemVend = коробка пополнения ХимВенд

View File

@@ -30,8 +30,40 @@ ent-PosterLegitMime = Мим Постмодерн
.desc = Постмодернистское изображение мима, превосходно!
ent-PosterLegitCarpMount = Карп настенный
.desc = Carpe diem!
ent-PosterLegitPeriodicTable = Периодическая таблица элементов
.desc = Периодическая таблица элементов, от водорода до оганессона и всего, что между ними.
ent-PosterLegitVacation = Корпоративные льготы Nanotrasen: Отпуск
.desc = На этом информационном плакате представлена информация о некоторых призах, доступных в рамках программы NT Corporate Perks, включая двухнедельный отпуск на двоих на курорте Idyllus.
ent-PosterLegitNTTGC = Карты тактической игры "Нанотрасен
.desc = Реклама карт TCG от Nanotrasen: ПОКУПАЙТЕ БОЛЬШЕ КАРТ.
ent-PosterLegitRenault = Плакат Renault
.desc = Яп!
ent-PosterLegitSafetyMothDelam = Мотылек безопасности - Меры предосторожности при расслаивании!
.desc = Этот информационный плакат использует Safety Moth™, чтобы рассказать зрителям о необходимости прятаться в шкафах, когда кристалл суперматерии расслаивается, чтобы избежать галлюцинаций. Эвакуация может быть лучшей стратегией.
ent-PosterLegitSafetyMothEpi = Безопасная моль - Эпинефрин!
.desc = Этот информационный плакат использует Safety Moth™, чтобы проинформировать зрителей о необходимости помочь раненым/погибшим членам экипажа с их инъекторами эпинефрина. "Предотвратите гниение органов с помощью этого простого трюка!".
ent-PosterLegitSafetyMothHardhat = Моль безопасности - Каски!
.desc = Этот информационный плакат использует Safety Moth™, чтобы рассказать зрителю о необходимости носить каски в опасных местах. "Это как лампа для вашей головы!".
ent-PosterLegitSafetyMothMeth = Мотылек безопасности - Метамфетамин!
.desc = Этот информационный плакат использует Safety Moth™, чтобы рассказать зрителю о необходимости получить разрешение CMO перед приготовлением метамфетамина. "Держитесь ближе к заданной температуре и никогда не превышайте ее!" ...Вы никогда не должны делать это."
ent-PosterLegitSafetyMothPiping = Безопасная моль - Трубы!
.desc = ..Этот информационный плакат использует Safety Moth™, чтобы рассказать техникам по работе с атмосферой о правильных типах трубопроводов, которые необходимо использовать. "Трубы, а не насосы! Правильное размещение труб предотвращает плохую работу!".
ent-PosterContrabandInterdyne = Интердайн Фармасьютикалс: Для здоровья человечества!
.desc = Реклама клиник GeneClean компании Interdyne Pharmaceutics. Станьте хозяином своего тела!".
ent-PosterContrabandWaffleCorp = Сделай мне вафли: Отличные винтовки, экономичные цены!
.desc = Старая реклама винтовок Waffle Corp. "Лучшее оружие, низкие цены!"
ent-PosterContrabandMoth = Синди Моль - Ядерная операция!
.desc = Плакат, созданный по заказу Синдиката, на котором Syndie Moth™ говорит зрителю, что диск ядерной аутентификации должен быть незащищенным. "Мир никогда не был вариантом!" Ни один хороший сотрудник не станет слушать эту чушь.
ent-PosterContrabandEnlistGorlex = Записывайся!
.desc = Запишитесь в ряды мародеров Горлекса уже сегодня! Увидьте галактику, убейте корпорантов, получите деньги!"
ent-PosterContrabandDonk = DONK CO. ФИРМЕННАЯ ЕДА ДЛЯ МИКРОВОЛНОВОЙ ПЕЧИ
.desc = DONK CO. ФИРМЕННАЯ ЕДА ДЛЯ МИКРОВОЛНОВКИ: СДЕЛАНА ГОЛОДАЮЩИМИ СТУДЕНТАМИ КОЛЛЕДЖА, ДЛЯ ГОЛОДАЮЩИХ СТУДЕНТОВ КОЛЛЕДЖА".
ent-PosterContrabandCybersun600 = Cybersun: 600 лет" - юбилейный плакат
.desc = Художественный плакат, посвященный 600-летию непрерывной деятельности компании Cybersun Industries.
ent-BarberScissors = Парикмахерские ножницы
.desc = Способны изменить прическу по вашему вкусу.
ent-WallRock = скала
.desc = ""
.desc = Каменная порода
ent-WallRockGold = { ent-WallRock }
.desc = Рудная жила, богатая золотом.
ent-WallRockPlasma = { ent-WallRock }

View File

@@ -46,3 +46,28 @@ ent-CrateVendingMachineRestockSnacksFilled = ящик пополнения за
ent-CrateVendingMachineRestockTankDispenserFilled = ящик пополнения газовых баллонов
.desc = Содержит набор пополнения атмосферного или инженерного раздатчика газовых баллонов.
.suffix = { "" }
ent-CrateVendingMachineRestockAutoDrobeFilled = ящик пополнения Театрального шкафа
.desc = Содержит набор пополнения вещей для Театрального шкафа.
.suffix = { "" }
ent-CrateVendingMachineRestockDonutFilled = ящик для пополнения Пончики Монкинса
.desc = Содержит два набора пополнения для торгомата Пончики Монкинса.
.suffix = { "" }
ent-CrateVendingMachineRestockChangFilled = ящик для пополнения Мистера Чанга
.desc = Содержит два набора пополнения для торгомата Мистера Чанга.
.suffix = { "" }
ent-CrateVendingMachineRestockDiscountDansFilled = ящик для пополнения Дискаунтера Дэна
.desc = Содержит два набора пополнения для торгомата Дискаунтера Дэна.
.suffix = { "" }
ent-CrateVendingMachineRestockChefvendFilled = ящик для пополнения ШефШкафа
.desc = Содержит набор пополнения для ШефШкафа.
.suffix = { "" }
ent-CrateVendingMachineRestockGetmoreChocolateCorpFilled = ящик для пополнения Гетмор Шоколад Корп.
.desc = Содержит два набора пополнения для Гетмор Шоколад Корп.
.suffix = { "" }
ent-CrateVendingMachineRestockChemVendFilled = ящик для пополнения ХимВенд
.desc = Содержит набор пополнения для ХимВенд.
.suffix = { "" }
ent-CrateVendingMachineRestockHappyHonkFilled = ящик для пополнения ХэппиХонк
.desc = Содержит два набора пополнения для ХэппиХонк.
.suffix = { "" }

View File

@@ -52,3 +52,6 @@ ent-ClothingBackpackDuffelSyndicateMedicalBundle = { ent-ClothingBackpackDuffelS
ent-ClothingBackpackDuffelHolding = бездонный вещмешок
.desc = Вещмешок, открывающийся в локальный карман блюспейса.
.suffix = { "" }
ent-ClothingBackpackDuffelCBURN = вещмешок CBURN
.desc = Вещмешок, содержащий разнообразное оборудование для биологической защиты.
.suffix = { "" }

View File

@@ -49,3 +49,15 @@ ent-ClothingBeltSuspenders = подтяжки
ent-ClothingBeltWand = пояс для палочек
.desc = Пояс, предназначенный для хранения различных волшебных палочек. Поясная сумка, полная экзотической магии.
.suffix = { "" }
ent-ClothingBeltChef = пояс шеф повара
.desc = Пояс, для хранения кухонных ножей и приправ для быстрого доступа.
.suffix = { "" }
ent-ClothingBeltMedicalEMT = пояс парамедика
.desc = Пояс, идеально подходит для хранения различного оборудования для экстренной медицинской помощи.
.suffix = { "" }
ent-ClothingBeltMedicalEMTFilled = { ent-ClothingBeltMedicalEMT }
.desc = { ClothingBeltMedicalEMT.desc }
ent-ClothingBeltQuiver = колчан
.desc = Вмещает до 15 стрел и плотно прилегает к талии.
.suffix = { "" }

View File

@@ -24,6 +24,8 @@ ent-ClothingHandsGlovesColorYellow = изолированные перчатки
.desc = Эти перчатки защищают пользователя от поражения электрическим током.
ent-ClothingHandsGlovesColorYellowBudget = дешёвые изолированные перчатки
.desc = Всего лишь дешёвая подделка заветных перчаток - не может быть, чтобы это плохо кончилось.
ent-ClothingHandsGlovesFingerlessInsulated = беспалые изолированные перчатки
.desc = Изолированные перчатки устойчивые к ударам током, по крайней мере, раньше.
ent-ClothingHandsGlovesConducting = { ent-ClothingHandsGlovesColorYellow }
.suffix = Проводящий
.desc = { ent-ClothingHandsGlovesColorYellow.desc }
.desc = { ent-ClothingHandsGlovesColorYellow.desc }

View File

@@ -115,3 +115,20 @@ ent-GasRecyclerMachineCircuitboard = переработчик газа (маши
ent-APECircuitboard = М.А.К.А.К. (машинная плата)
.desc = Печатная плата излучателя аномальных частиц
.suffix = { "" }
ent-FlatpackerMachineCircuitboard = Флэтпакер 1001 (машинная плата)
.desc = Печатная плата Флэтпакер 1001
ent-ArtifactCrusherMachineCircuitboard = дробитель артефактов (машинная плата)
.desc = Печатная плата дробителя артефактов
.suffix = { "" }
ent-AnomalySynchronizerCircuitboard = синхронизатор артефактов (машинная плата)
.desc = Печатная плата синхронизатора артефактов
.suffix = { "" }
ent-PortableGeneratorJrPacmanMachineCircuitboard = плата портативной генераторной машины типа J.R.P.A.C.M.A.N.
.desc = Печатная плата портативного генератора J.R.P.A.C.M.A.N.
.suffix = { "" }
ent-PortableGeneratorPacmanMachineCircuitboard = плата портативной генераторной машины типа P.A.C.M.A.N.
.desc = Печатная плата портативного генератора P.A.C.M.A.N.
.suffix = { "" }
ent-PortableGeneratorSuperPacmanMachineCircuitboard = плата портативной генераторной машины типа S.U.P.E.R.P.A.C.M.A.N.
.desc = Печатная плата портативного генератора S.U.P.E.R.P.A.C.M.A.N.
.suffix = { "" }

View File

@@ -70,3 +70,6 @@ ent-VendingMachineRestockRobotics = набор пополнения Роботе
ent-VendingMachineRestockHappyHonk = набор пополнения Хэппи Хонк Мил
.desc = Для начала поместите эту коробку, полную веселья, в гнездо для пополнения запасов на диспенсере Хэппи Хонк Мил.
.suffix = { "" }
ent-VendingMachineRestockChefvend = набор пополнения Шеф Шкафа
.desc = Коробка наполненная вещами, для самого лучшего Шеф повара вашей кухни.
.suffix = { "" }

View File

@@ -0,0 +1,3 @@
ent-WeaponGauntletGorilla = Перчатка G.O.R.I.L.L.A.
.desc = Надежное исследовательское оборудование. При использовании ядра аномалии один удар может запускать аномальные объекты в воздух.
.suffix = { "" }

View File

@@ -4,3 +4,9 @@ ent-MachineArtifactAnalyzer = анализатор артефактов
ent-MachineTraversalDistorter = поперечный искатель
.desc = Прибор, способный влиять на открываемые цепочки эффектов артефактов.
.suffix = { "" }
ent-MachineArtifactCrusher = дробитель артефактов
.desc = Лучше не совать в него свои пальцы...
.suffix = { "" }
ent-MachineAnomalySynchronizer = синхронизатор артефактов
.desc = Сложное устройство, считывающее изменения в аномальных волнах и преобразующее их в энергетические сигналы.
.suffix = { "" }

View File

@@ -22,3 +22,6 @@ ent-UniformPrinter = принтер униформы
ent-OreProcessor = переработчик руды
.desc = Он производит металлические листы и слитки из руды.
.suffix = { "" }
ent-MachineFlatpacker = Флэтпакер 1001
.desc = Промышленная машина, используемая для ускорения строительства машин на станции.
.suffix = { "" }

View File

@@ -0,0 +1,13 @@
ent-PortableGeneratorJrPacman = Портативный генератор типа J.R.P.A.C.M.A.N.
.desc = Небольшой генератор, способный обеспечить электроэнергией отдельные помещения в случае чрезвычайных ситуаций.
Работает на сварочном топливе и рассчитан на мощность до 8 кВт.
Рассчитан на возраст от 3 лет и старше.
.suffix = { "" }
ent-PortableGeneratorPacman = Портативный генератор типа P.A.C.M.A.N.
.desc = Гибкий резервный генератор для питания разнообразного оборудования.
Работает от твердых плазменных листов и рассчитан на мощность до 30 кВт.
.suffix = { "" }
ent-PortableGeneratorSuperPacman = Портативный генератор типа S.U.P.E.R.P.A.C.M.A.N.
.desc = Усовершенствованный генератор для питания отделов.
Работает на урановых листах и рассчитан на мощность до 50 кВт.
.suffix = { "" }

View File

@@ -0,0 +1,2 @@
ent-PetCarrier = переноска для животных
.desc = Позволяет с комфортом переносить крупных животных.

View File

@@ -53,7 +53,7 @@ changeling-ability-changeling-lesser-form = Примитивная форма
changeling-ability-changeling-lesser-form-desc = Превращает в самую примитивную форму. Полезно для побега из наручников. Стоит 5 химикатов.
changeling-ability-bees = Выпустить пчёл
changeling-ability-bees-desc = Выпускает 6 агрессивных пчёл из улья.
changeling-ability-bees-desc = Выпускает 4 агрессивных пчелы из улья.
ent-ActionChangelingShop = Эволюции
.desc = Эволюционируйте и развивайтесь.

View File

@@ -67,3 +67,16 @@ tts-voice-name-poppysweeting = Поппи Добринг
tts-voice-name-narrator_d3 = Рассказчик
tts-voice-name-tosh = Габриэль Тош
tts-voice-name-tychus = Тайкус Финдли
tts-voice-name-boris-petrov = Борис Петров
tts-voice-name-karina-petrova = Карина Петрова
tts-voice-name-kate-smirnova = Катя Смирнова
tts-voice-name-semen-baburin = Семён Бабурин
tts-voice-name-tihonov = Лейтенант Тихонов
tts-voice-name-uther = Утер Светоносный
tts-voice-name-female-commander = Женщина командир
tts-voice-name-lord-harkon = Лорд Харкон
tts-voice-name-serana = Серана
tts-voice-name-moira-brown = Мойра Браун
tts-voice-name-robert-maccready = Робер МакКриди
tts-voice-name-threedog = Тридогнайт
tts-voice-name-threedog-radio = Тридогнайт Радио

File diff suppressed because it is too large Load Diff

View File

@@ -76,6 +76,9 @@
event: !type:ExtractionStingActionEvent
canTargetSelf: false
useDelay: 1
whitelist:
components:
- HumanoidAppearance
- type: entity
id: ActionTransformSting
@@ -89,6 +92,9 @@
event: !type:TransformStingActionEvent
canTargetSelf: false
useDelay: 1
whitelist:
components:
- HumanoidAppearance
- type: entity
id: ActionBlindSting
@@ -102,6 +108,10 @@
event: !type:BlindStingActionEvent
canTargetSelf: false
useDelay: 1
whitelist:
components:
- HumanoidAppearance
- Blindable
- type: entity
id: ActionMuteSting
@@ -115,6 +125,9 @@
event: !type:MuteStingActionEvent
canTargetSelf: false
useDelay: 1
whitelist:
components:
- HumanoidAppearance
- type: entity
id: ActionHallucinationSting
@@ -128,6 +141,9 @@
event: !type:HallucinationStingActionEvent
canTargetSelf: false
useDelay: 1
whitelist:
components:
- HumanoidAppearance
- type: entity
id: ActionCryoSting
@@ -141,11 +157,15 @@
event: !type:CryoStingActionEvent
canTargetSelf: false
useDelay: 1
whitelist:
components:
- HumanoidAppearance
- Temperature
- type: entity
id: ActionAdrenalineSacs
name: changeling-ability-adrenaline-sacks
description: changeling-ability-adrenaline-sacks.desc
description: changeling-ability-adrenaline-sacks-desc
noSpawn: true
components:
- type: InstantAction
@@ -153,6 +173,8 @@
icon: White/Actions/changeling.rsi/adrenaline_sacs.png
event: !type:AdrenalineSacsActionEvent
useDelay: 1
checkConsciousness: false
checkCanInteract: false
- type: LesserFormRestricted
- type: entity
@@ -166,6 +188,8 @@
icon: White/Actions/changeling.rsi/fleshmend.png
event: !type:FleshmendActionEvent
useDelay: 1
checkConsciousness: false
checkCanInteract: false
- type: LesserFormRestricted
- type: entity

View File

@@ -1,6 +1,5 @@
- type: alert
id: Chemicals
category: Health #it's like ghostie health
icons:
- sprite: /Textures/Interface/Alerts/essence_counter.rsi
state: essence0

View File

@@ -545,6 +545,7 @@
Slash: 0.9
Piercing: 0.9
Heat: 0.9
- type: WizardClothes
#Organic Space Suit
- type: entity

View File

@@ -703,6 +703,7 @@
useRate: 0
- type: UseDelay
delay: 10.0
- type: WizardClothes
#Ling Space Suit
- type: entity

View File

@@ -176,3 +176,16 @@
- type: Lightning
canArc: true
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

View File

@@ -33,12 +33,12 @@
prototypes:
- PosterContrabandFreeTonto
- PosterContrabandAtmosiaDeclarationIndependence
- PosterContrabandFunPolice
#- PosterContrabandFunPolice
- PosterContrabandLustyExomorph
- PosterContrabandSyndicateRecruitment
- PosterContrabandClown
- PosterContrabandSmoke
- PosterContrabandGreyTide
#- PosterContrabandGreyTide
- PosterContrabandMissingGloves
- PosterContrabandHackingGuide
- PosterContrabandRIPBadger
@@ -91,7 +91,7 @@
- PosterContrabandEnlistGorlex
- PosterContrabandInterdyne
- PosterContrabandWaffleCorp
- PosterContrabandMissingSpacepen
#- PosterContrabandMissingSpacepen # HAHAHAHAHAAH
chance: 1
- type: entity
@@ -135,12 +135,12 @@
- PosterLegit50thAnniversaryVintageReprint
- PosterLegitFruitBowl
- PosterLegitPDAAd
- PosterLegitEnlist
#- PosterLegitEnlist
- PosterLegitNanomichiAd
- PosterLegit12Gauge
- PosterLegitHighClassMartini
- PosterLegitTheOwl
- PosterLegitNoERP
#- PosterLegitNoERP
- PosterLegitCarbonDioxide
- PosterLegitDickGumshue
- PosterLegitThereIsNoGasGiant

View File

@@ -236,3 +236,44 @@
stunAmount: 2
knockdownAmount: 2
- 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

View File

@@ -120,4 +120,10 @@
id: BaseStationAllEventsEligible
abstract: true
components:
- type: StationEventEligible # For when someone makes this more granular in the future.
- type: StationEventEligible # For when someone makes this more granular in the future.
- type: entity
id: BaseStationTeleportLocation
abstract: true
components:
- type: TeleportLocationTargetStation

View File

@@ -25,6 +25,7 @@
- BaseStationSiliconLawCrewsimov
- BaseStationAllEventsEligible
- BaseStationNanotrasen
- BaseStationTeleportLocation
noSpawn: true
components:
- type: Transform

View File

@@ -4,12 +4,11 @@
description: This spell opens nearby doors.
noSpawn: true
components:
- type: Magic
requiresClothes: false
- type: InstantAction
useDelay: 8
itemIconStyle: BigAction
checkCanInteract: false
alwaysPlaySound: false
icon:
sprite: Objects/Magic/magicactions.rsi
state: knock

View File

@@ -1,9 +1,11 @@
- type: entity
- type: entity
id: ActionSmite
name: Smite
description: Instantly gibs a target.
noSpawn: true
components:
- type: Magic
requiresClothes: true
- type: EntityTargetAction
useDelay: 60
itemIconStyle: BigAction
@@ -12,6 +14,7 @@
- Body
canTargetSelf: false
interactOnMiss: false
alwaysPlaySound: false
sound: !type:SoundPathSpecifier
path: /Audio/Magic/disintegrate.ogg
icon:

View File

@@ -217,6 +217,9 @@
noSpawn: true
components:
- type: EntityTargetAction
whitelist:
components:
- HumanoidAppearance
canTargetSelf: false
range: 3
useDelay: 60
@@ -233,6 +236,9 @@
noSpawn: true
components:
- type: EntityTargetAction
whitelist:
components:
- HumanoidAppearance
canTargetSelf: false
range: 3
useDelay: 30
@@ -249,6 +255,9 @@
noSpawn: true
components:
- type: EntityTargetAction
whitelist:
components:
- HumanoidAppearance
canTargetSelf: false
range: 3
useDelay: 30
@@ -278,8 +287,6 @@
name: Teleport
noSpawn: true
components:
- type: Magic
requiresClothes: true
- type: InstantAction
checkCanInteract: false
useDelay: 60

View File

@@ -21,7 +21,6 @@
- type: FlashImmunity
- type: EyeProtection
- type: HiveHead
beesAmount: 6
- type: entity
id: ActionReleaseBees

View File

@@ -69,11 +69,6 @@
graph: CultPylon
node: pylon
- type: Concealable
- type: AtmosDevice
- type: GasMiner
maxExternalPressure: 100
spawnAmount: 10
spawnGas: Oxygen
- type: entity
id: AltarTome

View File

@@ -36,8 +36,6 @@
- HolyKatana
- MultiverseBlade
- VorpalScythe
- HighFrequencyBlade
- SpellBlade
- PossessedBlade
- ChainsawHand
- HolyWhip
@@ -196,54 +194,6 @@
sprite: White/Objects/Weapons/Chaplain/scythe-inhands.rsi
- type: HolyWeapon
- type: entity
name: высокочастотный клинок
parent: HolyKatana
id: HighFrequencyBlade
description: Клинок, способный отражать выстрелы.
components:
- type: Sprite
sprite: White/Objects/Weapons/Chaplain/hfrequency.rsi
- type: MeleeWeapon
damage:
types:
Slash: 18
- type: Clothing
sprite: White/Objects/Weapons/Chaplain/hfrequency.rsi
slots:
- back
- suitStorage
- type: Reflect
reflectProb: 0.33
- type: Item
sprite: White/Objects/Weapons/Chaplain/hfrequency.rsi
- 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
name: одержимый клинок
parent: HolyKatana

View File

@@ -142,3 +142,12 @@
- type: Scroll
actionId: ActionTeleportSpell
learnPopup: scroll-component-teleport
- type: entity
id: ScrollSmite
parent: BaseScroll
name: "Smite scroll"
components:
- type: Scroll
actionId: ActionSmite
learnPopup: scroll-component-smite

View File

@@ -0,0 +1,53 @@
- type: entity
name: высокочастотный клинок
parent: Katana
id: HighFrequencyBlade
description: Клинок, атакующий с невероятной быстротой, а также способный отражать выстрелы.
components:
- type: Sprite
sprite: White/Objects/Weapons/Chaplain/hfrequency.rsi
- type: MeleeWeapon
autoAttack: true
attackRate: 4
damage:
types:
Slash: 10
- type: Clothing
sprite: White/Objects/Weapons/Chaplain/hfrequency.rsi
slots:
- back
- suitStorage
- type: Reflect
reflectProb: 0.4
- type: Item
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

View 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

View File

@@ -0,0 +1,63 @@
- type: entity
id: SpellBook
parent: BaseItem
name: spell book
description: An unearthly tome that glows with power.
components:
- type: Sprite
sprite: Objects/Misc/books.rsi
layers:
- state: paper
- state: cover_old
color: "#473F40"
- state: decor_wingette
color: "#352D2F"
- state: icon_stars
color: gold
- type: UserInterface
interfaces:
- key: enum.StoreUiKey.Key
type: StoreBoundUserInterface
- type: ActivatableUI
key: enum.StoreUiKey.Key
- type: Store
preset: StorePresetSpellBook
balance:
SpellPoint: 10
- type: GiftIgnore
- type: storePreset
id: StorePresetSpellBook
storeName: Spell Book
categories:
- AttackSpells
- DefenceSpells
- UtilitySpells
- MagicItems
currencyWhitelist:
- SpellPoint
- type: currency
id: SpellPoint
displayName: store-currency-display-spell-point
canWithdraw: false
- type: storeCategory
id: AttackSpells
name: store-category-spells-attack
priority: 0
- type: storeCategory
id: DefenceSpells
name: store-category-spells-defence
priority: 1
- type: storeCategory
id: UtilitySpells
name: store-category-spells-utility
priority: 2
- type: storeCategory
id: MagicItems
name: store-category-magic-items
priority: 3

View File

@@ -0,0 +1,262 @@
- type: listing
id: SpellBookFireball
name: spellbook-fireball-name
description: spellbook-fireball-desc
icon:
sprite: Objects/Magic/magicactions.rsi
state: fireball
productEntity: ScrollFireball
cost:
SpellPoint: 2
categories:
- AttackSpells
conditions:
- !type:ListingLimitedStockCondition
stock: 1
- type: listing
id: SpellBookForcewall
name: spellbook-forcewall-name
description: spellbook-forcewall-desc
productEntity: ScrollForcewall
icon:
sprite: Objects/Magic/magicactions.rsi
state: shield
cost:
SpellPoint: 1
categories:
- DefenceSpells
conditions:
- !type:ListingLimitedStockCondition
stock: 1
- type: listing
id: SpellBookKnock
name: spellbook-knock-name
description: spellbook-knock-desc
productEntity: ScrollKnock
icon:
sprite: Objects/Magic/magicactions.rsi
state: knock
cost:
SpellPoint: 1
categories:
- UtilitySpells
conditions:
- !type:ListingLimitedStockCondition
stock: 1
- type: listing
id: SpellBookArc
name: spellbook-arc-name
description: spellbook-arc-desc
productEntity: ScrollArc
icon:
sprite: Objects/Magic/magicactions.rsi
state: thunder
cost:
SpellPoint: 2
categories:
- AttackSpells
conditions:
- !type:ListingLimitedStockCondition
stock: 1
- type: listing
id: SpellBookForce
name: spellbook-force-name
description: spellbook-force-desc
productEntity: ScrollForce
icon:
sprite: Objects/Magic/magicactions.rsi
state: push
cost:
SpellPoint: 2
categories:
- UtilitySpells
conditions:
- !type:ListingLimitedStockCondition
stock: 1
- type: listing
id: SpellBookCards
name: spellbook-cards-name
description: spellbook-cards-desc
productEntity: ScrollCards
icon:
sprite: Objects/Magic/card.rsi
state: icon
cost:
SpellPoint: 2
categories:
- AttackSpells
conditions:
- !type:ListingLimitedStockCondition
stock: 1
- type: listing
id: SpellBookBlink
name: spellbook-blink-name
description: spellbook-blink-desc
productEntity: ScrollBlink
icon:
sprite: Objects/Magic/magicactions.rsi
state: blink
cost:
SpellPoint: 1
categories:
- UtilitySpells
conditions:
- !type:ListingLimitedStockCondition
stock: 1
- type: listing
id: SpellBookEtherealJaunt
name: spellbook-jaunt-name
description: spellbook-jaunt-desc
productEntity: ScrollEtherealJaunt
icon:
sprite: Objects/Magic/magicactions.rsi
state: jaunt
cost:
SpellPoint: 2
categories:
- UtilitySpells
conditions:
- !type:ListingLimitedStockCondition
stock: 1
- type: listing
id: SpellBookEmp
name: spellbook-emp-name
description: spellbook-emp-desc
productEntity: ScrollEmp
icon:
sprite: Objects/Magic/magicactions.rsi
state: emp_new
cost:
SpellPoint: 1
categories:
- DefenceSpells
conditions:
- !type:ListingLimitedStockCondition
stock: 1
- type: listing
id: SpellBookCluwneCurse
name: spellbook-cluwne-name
description: spellbook-cluwne-desc
productEntity: ScrollCluwneCurse
icon:
sprite: Objects/Magic/magicactions.rsi
state: cluwne
cost:
SpellPoint: 2
categories:
- UtilitySpells
conditions:
- !type:ListingLimitedStockCondition
stock: 1
- type: listing
id: SpellBookBananaTouch
name: spellbook-clown-name
description: spellbook-clown-desc
productEntity: ScrollBananaTouch
icon:
sprite: Objects/Magic/magicactions.rsi
state: clown
cost:
SpellPoint: 1
categories:
- UtilitySpells
conditions:
- !type:ListingLimitedStockCondition
stock: 1
- type: listing
id: SpellBookMimeTouch
name: spellbook-mime-name
description: spellbook-mime-desc
productEntity: ScrollMimeTouch
icon:
sprite: Objects/Magic/magicactions.rsi
state: mime_curse
cost:
SpellPoint: 1
categories:
- UtilitySpells
conditions:
- !type:ListingLimitedStockCondition
stock: 1
- type: listing
id: SpellBookInstantRecall
name: spellbook-recall-name
description: spellbook-recall-desc
productEntity: ScrollInstantRecall
icon:
sprite: Objects/Magic/magicactions.rsi
state: summons
cost:
SpellPoint: 1
categories:
- UtilitySpells
conditions:
- !type:ListingLimitedStockCondition
stock: 1
- type: listing
id: SpellBookSmite
name: spellbook-smite-name
description: spellbook-smite-desc
productEntity: ScrollSmite
icon:
sprite: Objects/Magic/magicactions.rsi
state: gib
cost:
SpellPoint: 2
categories:
- AttackSpells
conditions:
- !type:ListingLimitedStockCondition
stock: 1
- type: listing
id: SpellBookHardsuit
name: spellbook-hardsuit-name
description: spellbook-hardsuit-desc
productEntity: ClothingOuterHardsuitWizard
cost:
SpellPoint: 4
categories:
- MagicItems
conditions:
- !type:ListingLimitedStockCondition
stock: 1
- type: listing
id: SpellBookHighFrequencyBlade
name: spellbook-hfrequency-name
description: spellbook-hfrequency-desc
productEntity: HighFrequencyBlade
cost:
SpellPoint: 2
categories:
- MagicItems
conditions:
- !type:ListingLimitedStockCondition
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

View File

@@ -42,6 +42,7 @@
head: ClothingHeadHatRealWizardFancy
outerClothing: ClothingOuterRealWizardFancy
shoes: ClothingShoesWizard
pocket1: SpellBook
innerClothingSkirt: ClothingUniformJumpskirtColorDarkBlue
satchel: ClothingBackpackSatchelFilled
duffelbag: ClothingBackpackDuffelFilled

View File

@@ -762,3 +762,80 @@
sex: Male
speaker: tychus
- type: ttsVoice
name: tts-voice-name-boris-petrov
sex: Male
speaker: boris_petrov_father_tb
id: BorisPetrovFatherTb
- type: ttsVoice
name: tts-voice-name-karina-petrova
sex: Female
speaker: karina_petrova_tb
id: KarinaPetrovaTb
- type: ttsVoice
name: tts-voice-name-kate-smirnova
sex: Female
speaker: kate_smirnova_tb
id: KateSmirnovaTb
- type: ttsVoice
name: tts-voice-name-semen-baburin
sex: Male
speaker: semen_baburin_tb
id: SemenBaburinTb
- type: ttsVoice
name: tts-voice-name-tihonov
sex: Male
speaker: tihonov_tb
id: TihonovTb
- type: ttsVoice
name: tts-voice-name-uther
sex: Male
speaker: uther_hs
id: UtherHs
- type: ttsVoice
name: tts-voice-name-female-commander
sex: Female
speaker: female_commander
id: FemaleCommander
- type: ttsVoice
name: tts-voice-name-lord-harkon
sex: Male
speaker: lord_harkon
id: LordHarkon
- type: ttsVoice
name: tts-voice-name-serana
sex: Female
speaker: serana
id: Serana
- type: ttsVoice
name: tts-voice-name-moira-brown
sex: Female
speaker: moira_brown
id: MoiraBrown
- type: ttsVoice
name: tts-voice-name-robert-maccready
sex: Male
speaker: robert_maccready
id: RobertMaccready
- type: ttsVoice
name: tts-voice-name-threedog
sex: Male
speaker: threedog
id: Threedog
- type: ttsVoice
name: tts-voice-name-threedog-radio
sex: Male
speaker: threedog_radio
id: ThreedogRadio

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 B

View File

@@ -54,6 +54,9 @@
},
{
"name": "teleport"
},
{
"name": "icebeam_active"
}
]
}