diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs index 6e100fe656..5b952ce96f 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs @@ -205,7 +205,8 @@ public sealed partial class ExplosionSystem MapCoordinates epicenter, HashSet processed, string id, - float? fireStacks) + float? fireStacks, + bool ignoreResistances) // WD { var size = grid.Comp.TileSize; var gridBox = new Box2(tile * size, (tile + 1) * size); @@ -224,7 +225,7 @@ public sealed partial class ExplosionSystem // process those entities foreach (var (uid, xform) in list) { - ProcessEntity(uid, epicenter, damage, throwForce, id, xform, fireStacks); + ProcessEntity(uid, epicenter, damage, throwForce, id, xform, fireStacks, ignoreResistances); // WD EDIT } // process anchored entities @@ -234,7 +235,7 @@ public sealed partial class ExplosionSystem foreach (var entity in _anchored) { processed.Add(entity); - ProcessEntity(entity, epicenter, damage, throwForce, id, null, fireStacks); + ProcessEntity(entity, epicenter, damage, throwForce, id, null, fireStacks, ignoreResistances); // WD EDIT } // Walls and reinforced walls will break into girders. These girders will also be considered turf-blocking for @@ -270,7 +271,7 @@ public sealed partial class ExplosionSystem { // Here we only throw, no dealing damage. Containers n such might drop their entities after being destroyed, but // they should handle their own damage pass-through, with their own damage reduction calculation. - ProcessEntity(uid, epicenter, null, throwForce, id, xform, null); + ProcessEntity(uid, epicenter, null, throwForce, id, xform, null, ignoreResistances); // WD EDIT } return !tileBlocked; @@ -306,7 +307,8 @@ public sealed partial class ExplosionSystem MapCoordinates epicenter, HashSet processed, string id, - float? fireStacks) + float? fireStacks, + bool ignoreResistances) // WD { var gridBox = Box2.FromDimensions(tile * DefaultTileSize, new Vector2(DefaultTileSize, DefaultTileSize)); var worldBox = spaceMatrix.TransformBox(gridBox); @@ -322,7 +324,7 @@ public sealed partial class ExplosionSystem foreach (var (uid, xform) in state.Item1) { processed.Add(uid); - ProcessEntity(uid, epicenter, damage, throwForce, id, xform, fireStacks); + ProcessEntity(uid, epicenter, damage, throwForce, id, xform, fireStacks, ignoreResistances); } if (throwForce <= 0) @@ -336,7 +338,7 @@ public sealed partial class ExplosionSystem foreach (var (uid, xform) in list) { - ProcessEntity(uid, epicenter, null, throwForce, id, xform, fireStacks); + ProcessEntity(uid, epicenter, null, throwForce, id, xform, fireStacks, ignoreResistances); } } @@ -434,7 +436,8 @@ public sealed partial class ExplosionSystem float throwForce, string id, TransformComponent? xform, - float? fireStacksOnIgnite) + float? fireStacksOnIgnite, + bool ignoreResistances) // WD { if (originalDamage != null) { @@ -442,7 +445,7 @@ public sealed partial class ExplosionSystem foreach (var (entity, damage) in _toDamage) { // TODO EXPLOSIONS turn explosions into entities, and pass the the entity in as the damage origin. - _damageableSystem.TryChangeDamage(entity, damage, ignoreResistances: true); + _damageableSystem.TryChangeDamage(entity, damage, ignoreResistances: ignoreResistances); // WD EDIT } } @@ -827,7 +830,8 @@ sealed class Explosion Epicenter, ProcessedEntities, ExplosionType.ID, - ExplosionType.FireStacks); + ExplosionType.FireStacks, + ExplosionType.IgnoreResistances); // WD // If the floor is not blocked by some dense object, damage the floor tiles. if (canDamageFloor) @@ -845,7 +849,8 @@ sealed class Explosion Epicenter, ProcessedEntities, ExplosionType.ID, - ExplosionType.FireStacks); + ExplosionType.FireStacks, + ExplosionType.IgnoreResistances); // WD } if (!MoveNext()) diff --git a/Content.Server/Magic/MagicSystem.cs b/Content.Server/Magic/MagicSystem.cs index c970588ad7..a512446826 100644 --- a/Content.Server/Magic/MagicSystem.cs +++ b/Content.Server/Magic/MagicSystem.cs @@ -10,6 +10,7 @@ using Content.Shared.Body.Components; using Content.Shared.Coordinates.Helpers; using Content.Shared.Doors.Components; using Content.Shared.Doors.Systems; +using Content.Shared.Lock; using Content.Shared.Magic; using Content.Shared.Magic.Events; using Content.Shared.Maps; @@ -46,6 +47,7 @@ public sealed class MagicSystem : EntitySystem [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly ChatSystem _chat = default!; [Dependency] private readonly WizardSpellsSystem _wizardSpells = default!; + [Dependency] private readonly LockSystem _lock = default!; public override void Initialize() { @@ -177,6 +179,9 @@ public sealed class MagicSystem : EntitySystem if (TryComp(entity, out var doorComp) && doorComp.State is not DoorState.Open) _doorSystem.StartOpening(entity); + + if (TryComp(entity, out var lockComp) && lockComp.Locked) + _lock.Unlock(entity, null, lockComp); } } diff --git a/Content.Server/_White/Wizard/GravPulseOnStartup/GravPulseOnStartupComponent.cs b/Content.Server/_White/Wizard/GravPulseOnStartup/GravPulseOnStartupComponent.cs new file mode 100644 index 0000000000..e1fa2cf4b2 --- /dev/null +++ b/Content.Server/_White/Wizard/GravPulseOnStartup/GravPulseOnStartupComponent.cs @@ -0,0 +1,20 @@ +namespace Content.Server._White.Wizard.GravPulseOnStartup; + +[RegisterComponent] +public sealed partial class GravPulseOnStartupComponent : Component +{ + [DataField] + public float MaxRange; + + [DataField] + public float MinRange; + + [DataField] + public float BaseRadialAcceleration; + + [DataField] + public float BaseTangentialAcceleration; + + [DataField] + public float StunTime; +} diff --git a/Content.Server/_White/Wizard/GravPulseOnStartup/GravPulseOnStartupSystem.cs b/Content.Server/_White/Wizard/GravPulseOnStartup/GravPulseOnStartupSystem.cs new file mode 100644 index 0000000000..09e7eda5d7 --- /dev/null +++ b/Content.Server/_White/Wizard/GravPulseOnStartup/GravPulseOnStartupSystem.cs @@ -0,0 +1,22 @@ +using Content.Server.Singularity.EntitySystems; + +namespace Content.Server._White.Wizard.GravPulseOnStartup; + +public sealed class GravPulseOnStartupSystem : EntitySystem +{ + [Dependency] private readonly GravityWellSystem _gravityWell = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnStartup); + } + + private void OnStartup(Entity ent, ref ComponentStartup args) + { + var (uid, comp) = ent; + _gravityWell.GravPulse(Transform(uid).Coordinates, comp.MaxRange, comp.MinRange, comp.BaseRadialAcceleration, + comp.BaseTangentialAcceleration, comp.StunTime); + } +} diff --git a/Content.Server/_White/Wizard/Magic/TeslaProjectile/TeslaProjectileComponent.cs b/Content.Server/_White/Wizard/Magic/TeslaProjectile/TeslaProjectileComponent.cs index 9ffce14fd6..6d6ad5c348 100644 --- a/Content.Server/_White/Wizard/Magic/TeslaProjectile/TeslaProjectileComponent.cs +++ b/Content.Server/_White/Wizard/Magic/TeslaProjectile/TeslaProjectileComponent.cs @@ -1,4 +1,8 @@ namespace Content.Server._White.Wizard.Magic.TeslaProjectile; [RegisterComponent] -public sealed partial class TeslaProjectileComponent : Component {} +public sealed partial class TeslaProjectileComponent : Component +{ + [ViewVariables] + public EntityUid? Caster; +} diff --git a/Content.Server/_White/Wizard/Magic/TeslaProjectile/TeslaProjectileSystem.cs b/Content.Server/_White/Wizard/Magic/TeslaProjectile/TeslaProjectileSystem.cs index 44740f704d..e7b07d39b2 100644 --- a/Content.Server/_White/Wizard/Magic/TeslaProjectile/TeslaProjectileSystem.cs +++ b/Content.Server/_White/Wizard/Magic/TeslaProjectile/TeslaProjectileSystem.cs @@ -16,6 +16,6 @@ public sealed class TeslaProjectileSystem : EntitySystem private void OnStartCollide(Entity ent, ref ProjectileHitEvent args) { - _lightning.ShootRandomLightnings(ent, 2, 4, arcDepth:2); + _lightning.ShootRandomLightnings(ent, 3, 4, "WizardLightning", 2, false, ent.Comp.Caster); } } diff --git a/Content.Server/_White/Wizard/Magic/WizardSpellsSystem.cs b/Content.Server/_White/Wizard/Magic/WizardSpellsSystem.cs index 51c5a62052..3a43e05cf9 100644 --- a/Content.Server/_White/Wizard/Magic/WizardSpellsSystem.cs +++ b/Content.Server/_White/Wizard/Magic/WizardSpellsSystem.cs @@ -4,6 +4,7 @@ using Content.Server._White.Cult; using Content.Server._White.IncorporealSystem; using Content.Server._White.Wizard.Magic.Amaterasu; using Content.Server._White.Wizard.Magic.Other; +using Content.Server._White.Wizard.Magic.TeslaProjectile; using Content.Server._White.Wizard.Teleport; using Content.Server.Abilities.Mime; using Content.Server.Administration.Commands; @@ -86,6 +87,7 @@ public sealed class WizardSpellsSystem : EntitySystem { base.Initialize(); + SubscribeLocalEvent(OnArcaneBarrage); SubscribeLocalEvent(OnTimeStop); SubscribeLocalEvent(OnMindswapSpell); SubscribeLocalEvent(OnTeleportSpell); @@ -105,6 +107,29 @@ public sealed class WizardSpellsSystem : EntitySystem SubscribeLocalEvent(OnBeforeCastSpell); } + #region Arcane Barrage + + private void OnArcaneBarrage(ArcaneBarrageSpellEvent msg) + { + if (!CanCast(msg)) + return; + + var uid = msg.Performer; + + var entity = Spawn(msg.Prototype, Transform(uid).Coordinates); + if (!_handsSystem.TryPickupAnyHand(uid, entity)) + { + _popupSystem.PopupEntity(Loc.GetString("arcane-barrage-no-empty-hand"), uid, uid); + QueueDel(entity); + _actions.SetCooldown(msg.Action, TimeSpan.FromSeconds(1)); + return; + } + + msg.Handled = true; + } + + #endregion + #region Timestop private void OnTimeStop(StopTimeSpellEvent msg) @@ -803,6 +828,7 @@ public sealed class WizardSpellsSystem : EntitySystem userVelocity = physics.LinearVelocity; var ent = Spawn(msg.Prototype, spawnCoords); + EnsureComp(ent).Caster = msg.Performer; var direction = msg.Target.ToMapPos(EntityManager, _transformSystem) - spawnCoords.ToMapPos(EntityManager, _transformSystem); _gunSystem.ShootProjectile(ent, direction, userVelocity, msg.Performer, msg.Performer); diff --git a/Content.Server/_White/Wizard/Teleport/WizardTeleportSpellEui.cs b/Content.Server/_White/Wizard/Teleport/WizardTeleportSpellEui.cs index 2aa84f1f22..c9848c24bd 100644 --- a/Content.Server/_White/Wizard/Teleport/WizardTeleportSpellEui.cs +++ b/Content.Server/_White/Wizard/Teleport/WizardTeleportSpellEui.cs @@ -2,6 +2,8 @@ using Content.Server.Popups; using Content.Shared._White.Wizard.Teleport; using Content.Shared.Eui; +using Content.Shared.Movement.Pulling.Components; +using Content.Shared.Movement.Pulling.Systems; using Robust.Shared.Timing; namespace Content.Server._White.Wizard.Teleport; @@ -11,6 +13,7 @@ public sealed class WizardTeleportSpellEui : BaseEui [Dependency] private readonly EntityManager _entityManager = default!; private readonly SharedTransformSystem _transformSystem; private readonly TeleportLocationSystem _teleportLocation; + private readonly PullingSystem _pulling; private readonly PopupSystem _popupSystem; private readonly EntityUid _performer; @@ -22,6 +25,7 @@ public sealed class WizardTeleportSpellEui : BaseEui IoCManager.InjectDependencies(this); _transformSystem = _entityManager.System(); + _pulling = _entityManager.System(); _teleportLocation = _entityManager.System(); _popupSystem = _entityManager.System(); @@ -82,6 +86,19 @@ public sealed class WizardTeleportSpellEui : BaseEui _used = true; + // break pulls before portal enter so we dont break shit + if (_entityManager.TryGetComponent(_performer, out var pullable) && pullable.BeingPulled) + { + _pulling.TryStopPull(_performer, pullable); + } + + if (_entityManager.TryGetComponent(_performer, out var pulling) + && pulling.Pulling != null + && _entityManager.TryGetComponent(pulling.Pulling.Value, out var subjectPulling)) + { + _pulling.TryStopPull(pulling.Pulling.Value, subjectPulling); + } + var coords = locationTransform.Coordinates; _transformSystem.SetCoordinates(_performer, coords); diff --git a/Content.Server/_White/Wizard/WizardComponent.cs b/Content.Server/_White/Wizard/WizardComponent.cs index fdf5c7ec21..6d236c075f 100644 --- a/Content.Server/_White/Wizard/WizardComponent.cs +++ b/Content.Server/_White/Wizard/WizardComponent.cs @@ -4,4 +4,6 @@ namespace Content.Server._White.Wizard; [RegisterComponent] public sealed partial class WizardComponent : Component { + [ViewVariables(VVAccess.ReadWrite)] + public bool EndRoundOnDeath; } diff --git a/Content.Server/_White/Wizard/WizardRuleSystem.cs b/Content.Server/_White/Wizard/WizardRuleSystem.cs index b98f86c63e..9be04159db 100644 --- a/Content.Server/_White/Wizard/WizardRuleSystem.cs +++ b/Content.Server/_White/Wizard/WizardRuleSystem.cs @@ -125,7 +125,7 @@ public sealed class WizardRuleSystem : GameRuleSystem private void OnMobStateChanged(EntityUid uid, WizardComponent component, MobStateChangedEvent ev) { - if (ev.NewMobState == MobState.Dead) + if (ev.NewMobState == MobState.Dead && component.EndRoundOnDeath) CheckAnnouncement(); } @@ -149,7 +149,7 @@ public sealed class WizardRuleSystem : GameRuleSystem return; } - SetupWizardEntity(uid, wizardSpawner.Points, gear, profile); + SetupWizardEntity(uid, gear, profile, false); } private void OnMindAdded(EntityUid uid, WizardComponent component, MindAddedMessage args) @@ -280,11 +280,11 @@ public sealed class WizardRuleSystem : GameRuleSystem private void SetupWizardEntity( EntityUid mob, - int points, StartingGearPrototype gear, - HumanoidCharacterProfile? profile) + HumanoidCharacterProfile? profile, + bool endRoundOnDeath) { - EnsureComp(mob); + EnsureComp(mob).EndRoundOnDeath = endRoundOnDeath; profile ??= HumanoidCharacterProfile.RandomWithSpecies(); @@ -346,7 +346,7 @@ public sealed class WizardRuleSystem : GameRuleSystem return; } - SetupWizardEntity(mob, component.Points, gear, profile); + SetupWizardEntity(mob, gear, profile, true); var newMind = _mind.CreateMind(session.UserId, name); _mind.SetUserId(newMind, session.UserId); diff --git a/Content.Server/_White/Wizard/WizardSpawnerComponent.cs b/Content.Server/_White/Wizard/WizardSpawnerComponent.cs index 6af3413aa2..dcf902b1ea 100644 --- a/Content.Server/_White/Wizard/WizardSpawnerComponent.cs +++ b/Content.Server/_White/Wizard/WizardSpawnerComponent.cs @@ -10,9 +10,6 @@ public sealed partial class WizardSpawnerComponent : Component [DataField("name")] public string Name = "Ololo The Balls' Twister"; - [DataField("points")] - public int Points = 10; - [DataField("startingGear")] public ProtoId StartingGear = "WizardGear"; diff --git a/Content.Shared/Explosion/ExplosionPrototype.cs b/Content.Shared/Explosion/ExplosionPrototype.cs index df2fb18360..d194b62d47 100644 --- a/Content.Shared/Explosion/ExplosionPrototype.cs +++ b/Content.Shared/Explosion/ExplosionPrototype.cs @@ -110,6 +110,11 @@ public sealed partial class ExplosionPrototype : IPrototype [DataField("fireStates")] public int FireStates = 3; + // WD START + [DataField] + public bool IgnoreResistances = true; + // WD END + /// /// Basic function for linear interpolation of the _tileBreakChance and _tileBreakIntensity arrays /// diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs index c77817d2d3..3b7e48548b 100644 --- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs @@ -540,6 +540,10 @@ public abstract partial class SharedGunSystem : EntitySystem gun.UseKey = useKey; } + public void SetClumsyProof(GunComponent gun, bool clumsyProof) + { + gun.ClumsyProof = clumsyProof; + } public void SetProjectileSpeed(EntityUid weapon, float projectileSpeed) { if(!TryComp(weapon, out var gunComponent)) diff --git a/Content.Shared/_White/Cult/Systems/BoltBarrageSystem.cs b/Content.Shared/_White/Cult/Systems/BoltBarrageSystem.cs index 696605f99a..d3e90daa74 100644 --- a/Content.Shared/_White/Cult/Systems/BoltBarrageSystem.cs +++ b/Content.Shared/_White/Cult/Systems/BoltBarrageSystem.cs @@ -27,7 +27,7 @@ public sealed class BoltBarrageSystem : EntitySystem SubscribeLocalEvent(OnShootAttempt); SubscribeLocalEvent(OnGunShot); SubscribeLocalEvent(OnDrop); - SubscribeLocalEvent(OnUnequipHand); + SubscribeLocalEvent(OnUnequipHand); SubscribeLocalEvent(OnRemoveAttempt); SubscribeLocalEvent(OnEmptyShot); SubscribeLocalEvent(OnExamine); @@ -38,7 +38,7 @@ public sealed class BoltBarrageSystem : EntitySystem args.PushMarkup(Loc.GetString("bolt-barrage-component-extra-desc")); } - private void OnUnequipHand(Entity ent, ref UnequippedHandEvent args) + private void OnUnequipHand(Entity ent, ref GotUnequippedHandEvent args) { if (_net.IsServer && ent.Comp.Unremoveable) QueueDel(ent); @@ -82,12 +82,12 @@ public sealed class BoltBarrageSystem : EntitySystem private void OnShootAttempt(Entity ent, ref AttemptShootEvent args) { - if (!HasComp(args.User) && !HasComp(args.User)) + /*if (!HasComp(args.User) && !HasComp(args.User)) { args.Cancelled = true; args.Message = Loc.GetString("bolt-barrage-component-not-cultist"); return; - } + }*/ if (_hands.EnumerateHands(args.User).Any(hand => hand.IsEmpty)) return; diff --git a/Content.Shared/_White/Wizard/SpellBlade/SharedSpellBladeSystem.cs b/Content.Shared/_White/Wizard/SpellBlade/SharedSpellBladeSystem.cs index af0f27fa46..c940d36507 100644 --- a/Content.Shared/_White/Wizard/SpellBlade/SharedSpellBladeSystem.cs +++ b/Content.Shared/_White/Wizard/SpellBlade/SharedSpellBladeSystem.cs @@ -102,6 +102,7 @@ public abstract class SharedSpellBladeSystem : EntitySystem { var gun = EnsureComp(uid); _gun.SetUseKey(gun, false); + _gun.SetClumsyProof(gun, true); _gun.SetSound(uid, new SoundPathSpecifier("/Audio/Weapons/Guns/Gunshots/Magic/staff_healing.ogg")); _gun.SetFireRate(uid, 1.2f); var ammoProvider = EnsureComp(uid); diff --git a/Content.Shared/_White/Wizard/Timestop/FreezeContactsSystem.cs b/Content.Shared/_White/Wizard/Timestop/FreezeContactsSystem.cs index 6da9f64b5c..4db8bbecaa 100644 --- a/Content.Shared/_White/Wizard/Timestop/FreezeContactsSystem.cs +++ b/Content.Shared/_White/Wizard/Timestop/FreezeContactsSystem.cs @@ -8,6 +8,7 @@ using Content.Shared.Inventory.Events; using Content.Shared.Item; using Content.Shared.Movement.Events; using Content.Shared.Speech; +using Content.Shared.Standing.Systems; using Content.Shared.Throwing; using Robust.Shared.Containers; using Robust.Shared.Physics; @@ -30,11 +31,14 @@ public sealed class FreezeContactsSystem : EntitySystem SubscribeLocalEvent(OnEntityEnter); SubscribeLocalEvent(OnEntityExit); + SubscribeLocalEvent(OnInit); SubscribeLocalEvent(OnRemove); SubscribeLocalEvent(OnPreventCollide); SubscribeLocalEvent(OnGetInserted); + SubscribeLocalEvent(OnAttempt); + SubscribeLocalEvent(OnAttempt); SubscribeLocalEvent(OnAttempt); SubscribeLocalEvent(OnAttempt); SubscribeLocalEvent(OnAttempt); @@ -152,21 +156,25 @@ public sealed class FreezeContactsSystem : EntitySystem private void OnEntityEnter(Entity ent, ref StartCollideEvent args) { - var hadFrozen = HasComp(args.OtherEntity); - var frozen = EnsureComp(args.OtherEntity); + FreezeEm(args.OtherEntity, ent); + } - if (!TryComp(ent, out TimedDespawnComponent? timedDespawn)) + private void FreezeEm(EntityUid uid, EntityUid freezeContact) + { + if (HasComp(uid)) + return; + + var frozen = EnsureComp(uid); + + if (!TryComp(freezeContact, out TimedDespawnComponent? timedDespawn)) return; frozen.Lifetime = timedDespawn.Lifetime; - if (TryComp(args.OtherEntity, out TimedDespawnComponent? otherTimedDespawn)) + if (TryComp(uid, out TimedDespawnComponent? otherTimedDespawn)) otherTimedDespawn.Lifetime += timedDespawn.Lifetime; - if (hadFrozen) - return; - - if (!TryComp(args.OtherEntity, out ThrownItemComponent? thrownItem)) + if (!TryComp(uid, out ThrownItemComponent? thrownItem)) return; if (thrownItem.LandTime != null) diff --git a/Content.Shared/_White/Wizard/WizardEvents.cs b/Content.Shared/_White/Wizard/WizardEvents.cs index d3263f839d..aee755f6a8 100644 --- a/Content.Shared/_White/Wizard/WizardEvents.cs +++ b/Content.Shared/_White/Wizard/WizardEvents.cs @@ -193,4 +193,13 @@ public sealed partial class StopTimeSpellEvent : InstantActionEvent, ISpeakSpell public string? Speech { get; private set; } } +public sealed partial class ArcaneBarrageSpellEvent : InstantActionEvent, ISpeakSpell +{ + [DataField("prototype", required: true, customTypeSerializer: typeof(PrototypeIdSerializer))] + public string Prototype = default!; + + [DataField("speech")] + public string? Speech { get; private set; } +} + #endregion diff --git a/Resources/Locale/ru-RU/_white/wizard/scrolls.ftl b/Resources/Locale/ru-RU/_white/wizard/scrolls.ftl index 4a7e5c9d7e..5845ad0088 100644 --- a/Resources/Locale/ru-RU/_white/wizard/scrolls.ftl +++ b/Resources/Locale/ru-RU/_white/wizard/scrolls.ftl @@ -18,6 +18,7 @@ scroll-component-teleport = телепортацию scroll-component-smite = кару scroll-component-mindswap = подмену сознания scroll-component-timestop = остановку времени +scroll-component-barrage = магический залп ent-BaseScroll = магический свиток .desc = Этот древний пергамент, ставший реликвией в арканных преданиях, хранит в себе бесчисленные мистические заклятия и забытые заклинания. @@ -55,3 +56,5 @@ ent-ScrollMindswap = свиток подмены сознания .desc = { ent-BaseScroll.desc } ent-ScrollTimestop = свиток остановки времени .desc = { ent-BaseScroll.desc } +ent-ScrollArcaneBarrage = свиток магического залпа + .desc = { ent-BaseScroll.desc } diff --git a/Resources/Locale/ru-RU/_white/wizard/spellbook.ftl b/Resources/Locale/ru-RU/_white/wizard/spellbook.ftl index b4a0f7e1c2..45e09dcc68 100644 --- a/Resources/Locale/ru-RU/_white/wizard/spellbook.ftl +++ b/Resources/Locale/ru-RU/_white/wizard/spellbook.ftl @@ -46,6 +46,9 @@ spellbook-mindswap-desc = { ent-ActionMindswapSpell.desc } spellbook-timestop-name = { ent-ActionTimestopSpell } spellbook-timestop-desc = { ent-ActionTimestopSpell.desc } +spellbook-barrage-name = { ent-ActionArcaneBarrageSpell } +spellbook-barrage-desc = { ent-ActionArcaneBarrageSpell.desc } + spellbook-hardsuit-name = Скафандр волшебника spellbook-hardsuit-desc = Украшенный магическими драгоценными камнями скафандр, функционирующий так же, как и обычная мантия волшебника, но в то же время является пригодным для использования в космосе и бронированным. Небольшое замедление. Теперь вы можете произносить заклинания в космосе и местах с низкой температурой! Имеет функцию энергетического щита,который защищает от всех снарядов. Щит разряжается при получении урона и автоматически заряжается. diff --git a/Resources/Locale/ru-RU/_white/wizard/spells.ftl b/Resources/Locale/ru-RU/_white/wizard/spells.ftl index 84183b1aa7..bba48bccdc 100644 --- a/Resources/Locale/ru-RU/_white/wizard/spells.ftl +++ b/Resources/Locale/ru-RU/_white/wizard/spells.ftl @@ -38,7 +38,7 @@ ent-ActionTeleportSpell = Телепортация .desc = Позволяет телепортироваться в любое место на станции! Переносит вас в выбранное место. ent-ActionKnock = Стук - .desc = Открывает все двери и шлюзы в радиусе 4 тайлов. + .desc = Открывает все двери, шлюзы и шкафы в радиусе 5 тайлов. ent-ActionSmite = Кара .desc = Заряжает вашу руку мерзкой энергией, которую можно использовать для взрыва жертв. Заклинание требует, чтобы вы коснулись своей цели, поэтому вы не сможете использовать его в наручниках или будучи оглушённым. Не работает без волшебной мантии и шляпы. @@ -48,3 +48,6 @@ ent-ActionMindswapSpell = Подмена сознания ent-ActionTimestopSpell = Остановка времени .desc = Останавливает время в радиусе вокруг вас. Находящиеся под воздействием существа не смогут двигаться, а пролетающие мимо снаряды будут остановлены до окончания остановки времени. Не работает без волшебной мантии и шляпы. + +ent-ActionArcaneBarrageSpell = Магический залп + .desc = Выстрелите потоком магической энергии в ваших врагов с помощью этого мощного заклинания. Для использования требуются обе свободные руки. Не работает без волшебной мантии и шляпы. diff --git a/Resources/Locale/ru-RU/_white/wizard/wizard.ftl b/Resources/Locale/ru-RU/_white/wizard/wizard.ftl index 5fe80c6233..f704e32454 100644 --- a/Resources/Locale/ru-RU/_white/wizard/wizard.ftl +++ b/Resources/Locale/ru-RU/_white/wizard/wizard.ftl @@ -36,6 +36,11 @@ ent-ClothingOuterRealWizardFancy = мантия волшебника ent-ClothingHeadHelmetWizardHelmArmored = шлем мага .desc = Странный головной убор, который наверняка принадлежит настоящему магу. Не обладает свойствами волшебной шляпы. +ent-ArcaneBarrage = магический залп + .desc = Пиу Пиу Пиу. + +arcane-barrage-no-empty-hand = Вам нужна свободная рука для использования заклинания! + mindswap-success = Ваш разум подменили! mindswap-borer-failed = Его разумом кто-то управляет. diff --git a/Resources/Prototypes/Damage/modifier_sets.yml b/Resources/Prototypes/Damage/modifier_sets.yml index 682f23767d..7aea09d04c 100644 --- a/Resources/Prototypes/Damage/modifier_sets.yml +++ b/Resources/Prototypes/Damage/modifier_sets.yml @@ -15,7 +15,7 @@ Blunt: 0.5 Slash: 0.5 Piercing: 0.5 - Shock: 1.2 + Shock: 0 # for lightning explosions Structural: 0.5 flatReductions: Blunt: 10 @@ -26,7 +26,7 @@ - type: damageModifierSet id: StructuralMetallic coefficients: - Shock: 1.2 + Shock: 0 # for lightning explosions Heat: 1.2 flatReductions: Blunt: 10 @@ -42,6 +42,7 @@ Slash: 0.25 Piercing: 0.75 Heat: 0.9 + Shock: 0 # for lightning explosions flatReductions: Blunt: 5 @@ -50,7 +51,7 @@ coefficients: Blunt: 2 Piercing: 0.2 - Shock: 0.6 + Shock: 0 # for lightning explosions flatReductions: Piercing: 10 diff --git a/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml b/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml index d356b41577..ded521045e 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml @@ -546,6 +546,8 @@ Piercing: 0.9 Heat: 0.9 - type: WizardClothes + - type: FlashImmunity + - type: EyeProtection #Organic Space Suit - type: entity diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml index 1238cd3785..918406652a 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml @@ -697,7 +697,7 @@ - PowerCell - PowerCellSmall - type: EnergyDomeGenerator - damageEnergyDraw: 20 + damageEnergyDraw: 15 domePrototype: EnergyDomeSmallPink - type: ClothingSpeedModifier walkModifier: 0.9 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/magic.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/magic.yml index f5ebed108d..e98dc0a087 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/magic.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/magic.yml @@ -220,21 +220,21 @@ - type: Projectile damage: types: - Caustic: 10 + Shock: 10 - type: Sprite sprite: Structures/Power/Generation/Tesla/energy_miniball.rsi layers: - state: tesla_projectile shader: unshaded - type: Explosive - explosionType: Default - maxIntensity: 100 - intensitySlope: 0.1 - totalIntensity: 0.3 + explosionType: Shock + maxIntensity: 40 + intensitySlope: 6 + totalIntensity: 200 maxTileBreak: 0 - type: StunOnCollide - stunAmount: 2 - knockdownAmount: 2 + stunAmount: 6 + knockdownAmount: 6 - type: TeslaProjectile - type: entity @@ -276,4 +276,3 @@ - 0, 0, 1, 0.4 - 1, 0, 1, 0.25 - 1, 0, 0, 0.1 - optionsConcealable: true diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml index e8114c4c1b..78cc46c3f1 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml @@ -1441,4 +1441,45 @@ - type: Projectile damage: types: - Piercing: 20 + Piercing: 25 + +- type: entity + name: arcane bolt + id: ArcaneBolt + parent: BaseBullet + noSpawn: true + components: + - type: Sprite + sprite: White/Objects/Weapons/arcane_barrage.rsi + state: bullet + - type: Ammo + muzzleFlash: null + - type: Projectile + damage: + types: + Heat: 25 + - type: Fixtures + fixtures: + projectile: + shape: + !type:PhysShapeAabb + bounds: "-0.2,-0.2,0.2,0.2" + hard: false + mask: + - Opaque + fly-by: *flybyfixture + - type: Trail + splineIteratorType: Linear + splineRendererType: Continuous + creationMethod: OnMove + scale: 0.05, 0.0 + lifetime: 0.5 + randomWalk: 0.001, 0.001 + gravity: 0, 0 + gradient: + - 1, 0, 0.75, 1 + - 1, 0, 0.75, 0 + - type: PointLight + radius: 1.7 + color: purple + energy: 0.7 diff --git a/Resources/Prototypes/Magic/knock_spell.yml b/Resources/Prototypes/Magic/knock_spell.yml index d2a280ae5a..9869408e9b 100644 --- a/Resources/Prototypes/Magic/knock_spell.yml +++ b/Resources/Prototypes/Magic/knock_spell.yml @@ -15,4 +15,5 @@ sprite: Objects/Magic/magicactions.rsi state: knock event: !type:KnockSpellEvent + range: 5 speech: action-speech-spell-knock diff --git a/Resources/Prototypes/Magic/white.yml b/Resources/Prototypes/Magic/white.yml index ea81456334..0e84716b30 100644 --- a/Resources/Prototypes/Magic/white.yml +++ b/Resources/Prototypes/Magic/white.yml @@ -29,8 +29,8 @@ prototype: ProjectileTeslaBall posData: !type:TargetCasterPos - type: VariableUseDelay - useDelay: 6 - altUseDelay: 12 + useDelay: 5 + altUseDelay: 5 chargeUseDelay: 30 - type: entity @@ -361,3 +361,19 @@ event: !type:StopTimeSpellEvent prototype: Timestop speech: "TOKI YO TOMARE!" + +- type: entity + id: ActionArcaneBarrageSpell + name: Arcane barrage + noSpawn: true + components: + - type: Magic + requiresClothes: true + - type: InstantAction + useDelay: 75 + itemIconStyle: BigAction + icon: + sprite: Objects/Magic/magicactions.rsi + state: arcane_barrage + event: !type:ArcaneBarrageSpellEvent + prototype: ArcaneBarrage diff --git a/Resources/Prototypes/_White/Entities/Cult/Items/blood_barrage.yml b/Resources/Prototypes/_White/Entities/Cult/Items/blood_barrage.yml index ef84377f52..00914aa8e4 100644 --- a/Resources/Prototypes/_White/Entities/Cult/Items/blood_barrage.yml +++ b/Resources/Prototypes/_White/Entities/Cult/Items/blood_barrage.yml @@ -25,6 +25,8 @@ capacity: 25 - type: BoltBarrage - type: GiftIgnore + - type: CultItem + canPickUp: false - type: cultistFactoryProduction id: FactoryCultBloodBarrage diff --git a/Resources/Prototypes/_White/Entities/Effects/timestop.yml b/Resources/Prototypes/_White/Entities/Effects/timestop.yml index 83093521d5..7e1efe2314 100644 --- a/Resources/Prototypes/_White/Entities/Effects/timestop.yml +++ b/Resources/Prototypes/_White/Entities/Effects/timestop.yml @@ -29,3 +29,6 @@ - type: TimedDespawn lifetime: 10 - type: FreezeContacts + - type: GravPulseOnStartup # Because physics sucks + maxRange: 2.5 + baseRadialAcceleration: 0.1 diff --git a/Resources/Prototypes/_White/Objects/Scrolls/scrolls.yml b/Resources/Prototypes/_White/Objects/Scrolls/scrolls.yml index 9919612b0a..2acf9f759d 100644 --- a/Resources/Prototypes/_White/Objects/Scrolls/scrolls.yml +++ b/Resources/Prototypes/_White/Objects/Scrolls/scrolls.yml @@ -169,3 +169,12 @@ - type: Scroll actionId: ActionTimestopSpell learnPopup: scroll-component-timestop + +- type: entity + id: ScrollArcaneBarrage + parent: BaseScroll + name: "Arcane barrage scroll" + components: + - type: Scroll + actionId: ActionArcaneBarrageSpell + learnPopup: scroll-component-barrage diff --git a/Resources/Prototypes/_White/Wizard/magic_items.yml b/Resources/Prototypes/_White/Wizard/magic_items.yml index ab79803482..60836bd1d5 100644 --- a/Resources/Prototypes/_White/Wizard/magic_items.yml +++ b/Resources/Prototypes/_White/Wizard/magic_items.yml @@ -104,3 +104,31 @@ Structural: 80 - type: ChangeThrowForce throwForce: 20 + +- type: entity + name: arcane barrage + parent: BaseItem + id: ArcaneBarrage + description: Pew Pew Pew. + components: + - type: Sprite + sprite: White/Objects/Weapons/arcane_barrage.rsi + state: icon + - type: Item + size: Ginormous + sprite: White/Objects/Weapons/arcane_barrage.rsi + - type: AmmoCounter + - type: Gun + fireRate: 4 + selectedMode: SemiAuto + availableModes: + - SemiAuto + soundEmpty: null + soundGunshot: + path: /Audio/Weapons/emitter.ogg + clumsyProof: true + - type: BasicEntityAmmoProvider + proto: ArcaneBolt + capacity: 30 + - type: BoltBarrage + - type: GiftIgnore diff --git a/Resources/Prototypes/_White/Wizard/spellbook_catalog.yml b/Resources/Prototypes/_White/Wizard/spellbook_catalog.yml index 492aa26f6d..facb4cd742 100644 --- a/Resources/Prototypes/_White/Wizard/spellbook_catalog.yml +++ b/Resources/Prototypes/_White/Wizard/spellbook_catalog.yml @@ -110,6 +110,22 @@ - !type:ListingLimitedStockCondition stock: 1 +- type: listing + id: SpellBookArcaneBarrage + name: spellbook-barrage-name + description: spellbook-barrage-desc + icon: + sprite: Objects/Magic/magicactions.rsi + state: arcane_barrage + productEntity: ScrollArcaneBarrage + cost: + SpellPoint: 2 + categories: + - AttackSpells + conditions: + - !type:ListingLimitedStockCondition + stock: 1 + - type: listing id: SpellBookBlink name: spellbook-blink-name @@ -273,7 +289,7 @@ description: spellbook-hfrequency-desc productEntity: HighFrequencyBlade cost: - SpellPoint: 2 + SpellPoint: 1 categories: - MagicItems conditions: @@ -286,7 +302,7 @@ description: spellbook-spellblade-desc productEntity: SpellBlade cost: - SpellPoint: 2 + SpellPoint: 1 categories: - MagicItems conditions: diff --git a/Resources/Prototypes/explosion.yml b/Resources/Prototypes/explosion.yml index 1006d8d80b..1b2a4a1a50 100644 --- a/Resources/Prototypes/explosion.yml +++ b/Resources/Prototypes/explosion.yml @@ -150,3 +150,16 @@ fireColor: Green texturePath: /Textures/Effects/fire_greyscale.rsi fireStates: 3 + +- type: explosion + id: Shock + damagePerIntensity: + types: + Shock: 15 + tileBreakChance: [0] + tileBreakIntensity: [0] + lightColor: "#B3CEFF" + fireColor: "#B3CEFF" + texturePath: /Textures/Effects/fire_greyscale.rsi + fireStates: 3 + ignoreResistances: false diff --git a/Resources/Textures/Objects/Magic/magicactions.rsi/arcane_barrage.png b/Resources/Textures/Objects/Magic/magicactions.rsi/arcane_barrage.png new file mode 100644 index 0000000000..f4bc6ea89b Binary files /dev/null and b/Resources/Textures/Objects/Magic/magicactions.rsi/arcane_barrage.png differ diff --git a/Resources/Textures/Objects/Magic/magicactions.rsi/meta.json b/Resources/Textures/Objects/Magic/magicactions.rsi/meta.json index 5886bfc706..c651117d7d 100644 --- a/Resources/Textures/Objects/Magic/magicactions.rsi/meta.json +++ b/Resources/Textures/Objects/Magic/magicactions.rsi/meta.json @@ -63,6 +63,9 @@ }, { "name": "time" + }, + { + "name": "arcane_barrage" } ] } diff --git a/Resources/Textures/White/Objects/Weapons/arcane_barrage.rsi/bullet.png b/Resources/Textures/White/Objects/Weapons/arcane_barrage.rsi/bullet.png new file mode 100644 index 0000000000..1a7e268eb7 Binary files /dev/null and b/Resources/Textures/White/Objects/Weapons/arcane_barrage.rsi/bullet.png differ diff --git a/Resources/Textures/White/Objects/Weapons/arcane_barrage.rsi/icon.png b/Resources/Textures/White/Objects/Weapons/arcane_barrage.rsi/icon.png new file mode 100644 index 0000000000..f4bc6ea89b Binary files /dev/null and b/Resources/Textures/White/Objects/Weapons/arcane_barrage.rsi/icon.png differ diff --git a/Resources/Textures/White/Objects/Weapons/arcane_barrage.rsi/inhand-left.png b/Resources/Textures/White/Objects/Weapons/arcane_barrage.rsi/inhand-left.png new file mode 100644 index 0000000000..24aec5deb1 Binary files /dev/null and b/Resources/Textures/White/Objects/Weapons/arcane_barrage.rsi/inhand-left.png differ diff --git a/Resources/Textures/White/Objects/Weapons/arcane_barrage.rsi/inhand-right.png b/Resources/Textures/White/Objects/Weapons/arcane_barrage.rsi/inhand-right.png new file mode 100644 index 0000000000..d41f095f6a Binary files /dev/null and b/Resources/Textures/White/Objects/Weapons/arcane_barrage.rsi/inhand-right.png differ diff --git a/Resources/Textures/White/Objects/Weapons/arcane_barrage.rsi/meta.json b/Resources/Textures/White/Objects/Weapons/arcane_barrage.rsi/meta.json new file mode 100644 index 0000000000..a5c2a8d480 --- /dev/null +++ b/Resources/Textures/White/Objects/Weapons/arcane_barrage.rsi/meta.json @@ -0,0 +1,69 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "inhand-left", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "inhand-right", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "bullet" + } + ] +}