Merge remote-tracking branch 'upstream/master'
@@ -7,6 +7,7 @@ using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Enums;
|
||||
using System.Numerics;
|
||||
using Content.Client.StatusIcon;
|
||||
using Content.Shared.StatusIcon.Components;
|
||||
using Content.Client.UserInterface.Systems;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -24,6 +25,7 @@ public sealed class EntityHealthBarOverlay : Overlay
|
||||
private readonly MobStateSystem _mobStateSystem;
|
||||
private readonly MobThresholdSystem _mobThresholdSystem;
|
||||
private readonly ProgressColorSystem _progressColor;
|
||||
private readonly StatusIconSystem _statusIcon;
|
||||
public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowFOV;
|
||||
public HashSet<string> DamageContainers = new();
|
||||
|
||||
@@ -34,6 +36,7 @@ public sealed class EntityHealthBarOverlay : Overlay
|
||||
_mobStateSystem = _entManager.System<MobStateSystem>();
|
||||
_mobThresholdSystem = _entManager.System<MobThresholdSystem>();
|
||||
_progressColor = _entManager.System<ProgressColorSystem>();
|
||||
_statusIcon = entManager.System<StatusIconSystem>();
|
||||
}
|
||||
|
||||
protected override void Draw(in OverlayDrawArgs args)
|
||||
@@ -70,6 +73,9 @@ public sealed class EntityHealthBarOverlay : Overlay
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!_statusIcon.IsVisible(uid))
|
||||
continue;
|
||||
|
||||
// we use the status icon component bounds if specified otherwise use sprite
|
||||
var bounds = _entManager.GetComponentOrNull<StatusIconComponent>(uid)?.Bounds ?? spriteComponent.Bounds;
|
||||
var worldPos = _transform.GetWorldPosition(xform, xformQuery);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Linq;
|
||||
using Content.Client.UserInterface.Systems.Chat;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Chat;
|
||||
using Content.Shared.GameTicking;
|
||||
@@ -10,7 +11,6 @@ using Robust.Client.Player;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Replays;
|
||||
@@ -31,7 +31,6 @@ namespace Content.Client.Popups
|
||||
[Dependency] private readonly IReplayRecordingManager _replayRecording = default!;
|
||||
[Dependency] private readonly ExamineSystemShared _examine = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly IClientNetManager _clientNet = default!;
|
||||
|
||||
public IReadOnlyList<WorldPopupLabel> WorldLabels => _aliveWorldLabels;
|
||||
public IReadOnlyList<CursorPopupLabel> CursorLabels => _aliveCursorLabels;
|
||||
@@ -94,6 +93,13 @@ namespace Content.Client.Popups
|
||||
|
||||
_aliveWorldLabels.Add(label);
|
||||
|
||||
// START WhiteDream
|
||||
if (!_isLogging)
|
||||
return;
|
||||
|
||||
if (!_examine.InRangeUnOccluded(_playerManager.LocalEntity!.Value, coordinates, 10))
|
||||
return;
|
||||
|
||||
var fontSizeDict = new Dictionary<PopupType, string>
|
||||
{
|
||||
{ PopupType.Medium, "12" },
|
||||
@@ -103,14 +109,16 @@ namespace Content.Client.Popups
|
||||
};
|
||||
|
||||
var fontsize = fontSizeDict.GetValueOrDefault(type, "10");
|
||||
var fontcolor = type is PopupType.LargeCaution or PopupType.MediumCaution or PopupType.SmallCaution ? "c62828" : "aeabc4";
|
||||
var fontcolor = type is PopupType.LargeCaution or PopupType.MediumCaution or PopupType.SmallCaution
|
||||
? "c62828"
|
||||
: "aeabc4";
|
||||
|
||||
if (_isLogging)
|
||||
{
|
||||
var wrappedMEssage = $"[font size={fontsize}][color=#{fontcolor}]{message}[/color][/font]";
|
||||
var chatMsg = new ChatMessage(ChatChannel.Emotes, message, wrappedMEssage, GetNetEntity(EntityUid.Invalid), null);
|
||||
_clientNet.DispatchLocalNetMessage(new MsgChatMessage { Message = chatMsg });
|
||||
}
|
||||
var chatMsg = new ChatMessage(ChatChannel.Emotes, message, wrappedMEssage,
|
||||
GetNetEntity(EntityUid.Invalid), null);
|
||||
_uiManager.GetUIController<ChatUIController>().ProcessChatMessage(chatMsg);
|
||||
|
||||
// END WhiteDream
|
||||
}
|
||||
|
||||
#region Abstract Method Implementations
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Ghost;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Mind.Components;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.NPC;
|
||||
@@ -34,9 +36,18 @@ public sealed class SSDIndicatorSystem : EntitySystem
|
||||
!_mobState.IsDead(uid) &&
|
||||
!HasComp<ActiveNPCComponent>(uid) &&
|
||||
TryComp<MindContainerComponent>(uid, out var mindContainer) &&
|
||||
mindContainer.ShowExamineInfo)
|
||||
mindContainer.ShowExamineInfo &&
|
||||
!IsAghosted(mindContainer)) // WD EDIT
|
||||
{
|
||||
args.StatusIcons.Add(_prototype.Index<StatusIconPrototype>(component.Icon));
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsAghosted(MindContainerComponent mindContainer) // WD
|
||||
{
|
||||
if (!TryComp(mindContainer.Mind, out MindComponent? mindComp))
|
||||
return false;
|
||||
|
||||
return TryComp(mindComp.VisitingEntity, out GhostComponent? ghost) && ghost.CanGhostInteract;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,9 @@ public sealed class StatusIconOverlay : Overlay
|
||||
if (icons.Count == 0)
|
||||
continue;
|
||||
|
||||
if (!_statusIcon.IsVisible(uid))
|
||||
continue;
|
||||
|
||||
var worldMatrix = Matrix3.CreateTranslation(worldPos);
|
||||
Matrix3.Multiply(scaleMatrix, worldMatrix, out var scaledWorld);
|
||||
Matrix3.Multiply(rotationMatrix, scaledWorld, out var matty);
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Ghost;
|
||||
using Content.Shared.StatusIcon;
|
||||
using Content.Shared.StatusIcon.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Client.StatusIcon;
|
||||
@@ -13,6 +16,10 @@ public sealed class StatusIconSystem : SharedStatusIconSystem
|
||||
{
|
||||
[Dependency] private readonly IConfigurationManager _configuration = default!;
|
||||
[Dependency] private readonly IOverlayManager _overlay = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerMan = default!;
|
||||
|
||||
private EntityQuery<GhostComponent> _ghostQuery;
|
||||
private EntityQuery<SpriteComponent> _spriteQuery;
|
||||
|
||||
private bool _globalEnabled;
|
||||
private bool _localEnabled;
|
||||
@@ -20,6 +27,9 @@ public sealed class StatusIconSystem : SharedStatusIconSystem
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
_ghostQuery = GetEntityQuery<GhostComponent>();
|
||||
_spriteQuery = GetEntityQuery<SpriteComponent>();
|
||||
|
||||
Subs.CVar(_configuration, CCVars.LocalStatusIconsEnabled, OnLocalStatusIconChanged, true);
|
||||
Subs.CVar(_configuration, CCVars.GlobalStatusIconsEnabled, OnGlobalStatusIconChanged, true);
|
||||
}
|
||||
@@ -59,5 +69,29 @@ public sealed class StatusIconSystem : SharedStatusIconSystem
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
return ev.StatusIcons;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For overlay to check if an entity can be seen.
|
||||
/// </summary>
|
||||
public bool IsVisible(EntityUid uid)
|
||||
{
|
||||
// ghosties can always see them
|
||||
var viewer = _playerMan.LocalSession?.AttachedEntity;
|
||||
if (_ghostQuery.HasComponent(viewer))
|
||||
return true;
|
||||
|
||||
if (_spriteQuery.TryGetComponent(uid, out var sprite) && !sprite.Visible)
|
||||
return false;
|
||||
|
||||
var ev = new StatusIconVisibleEvent(true);
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
return ev.Visible;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised on an entity to check if it should draw hud icons.
|
||||
/// Used to check invisibility etc inside the screen bounds.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public record struct StatusIconVisibleEvent(bool Visible);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Client.Interactable.Components;
|
||||
using Content.Client.StatusIcon;
|
||||
using Content.Shared.Stealth;
|
||||
using Content.Shared.Stealth.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
@@ -18,9 +19,12 @@ public sealed class StealthSystem : SharedStealthSystem
|
||||
base.Initialize();
|
||||
|
||||
_shader = _protoMan.Index<ShaderPrototype>("Stealth").InstanceUnique();
|
||||
|
||||
SubscribeLocalEvent<StealthComponent, ComponentShutdown>(OnShutdown);
|
||||
SubscribeLocalEvent<StealthComponent, ComponentStartup>(OnStartup);
|
||||
SubscribeLocalEvent<StealthComponent, BeforePostShaderRenderEvent>(OnShaderRender);
|
||||
|
||||
SubscribeLocalEvent<StealthComponent, StatusIconVisibleEvent>(OnStatusIconVisible);
|
||||
}
|
||||
|
||||
public override void SetEnabled(EntityUid uid, bool value, StealthComponent? component = null)
|
||||
@@ -92,5 +96,12 @@ public sealed class StealthSystem : SharedStealthSystem
|
||||
visibility = MathF.Max(0, visibility);
|
||||
args.Sprite.Color = new Color(visibility, visibility, 1, 1);
|
||||
}
|
||||
|
||||
private void OnStatusIconVisible(EntityUid uid, StealthComponent comp, ref StatusIconVisibleEvent args)
|
||||
{
|
||||
// no sechud seing invisible ninjas
|
||||
if (comp.Enabled)
|
||||
args.Visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Client.StatusIcon;
|
||||
using Content.Client.Storage.Components;
|
||||
using Content.Shared.Destructible;
|
||||
using Content.Shared.Foldable;
|
||||
@@ -29,6 +30,8 @@ public sealed class EntityStorageSystem : SharedEntityStorageSystem
|
||||
|
||||
SubscribeLocalEvent<EntityStorageComponent, ComponentGetState>(OnGetState);
|
||||
SubscribeLocalEvent<EntityStorageComponent, ComponentHandleState>(OnHandleState);
|
||||
|
||||
SubscribeLocalEvent<InsideEntityStorageComponent, StatusIconVisibleEvent>(OnStatusIconVisible);
|
||||
}
|
||||
|
||||
public override bool ResolveStorage(EntityUid uid, [NotNullWhen(true)] ref SharedEntityStorageComponent? component)
|
||||
@@ -40,4 +43,9 @@ public sealed class EntityStorageSystem : SharedEntityStorageSystem
|
||||
component = storage;
|
||||
return component != null;
|
||||
}
|
||||
|
||||
private void OnStatusIconVisible(EntityUid uid, InsideEntityStorageComponent comp, ref StatusIconVisibleEvent args)
|
||||
{
|
||||
args.Visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,8 @@ public sealed class AGhost : LocalizedCommands
|
||||
return;
|
||||
}
|
||||
|
||||
_entities.Dirty(mindId, mind); // WD
|
||||
|
||||
if (mind.VisitingEntity != default && _entities.TryGetComponent<GhostComponent>(mind.VisitingEntity, out var oldGhostComponent))
|
||||
{
|
||||
mindSystem.UnVisit(mindId, mind);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Server.Damage.Systems;
|
||||
using Content.Shared.Damage;
|
||||
using Robust.Shared.Audio;
|
||||
|
||||
namespace Content.Server.Damage.Components
|
||||
{
|
||||
@@ -15,5 +16,7 @@ namespace Content.Server.Damage.Components
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public DamageSpecifier Damage = default!;
|
||||
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)] // WD
|
||||
public SoundSpecifier? Sound;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ using Content.Shared.Effects;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Projectiles;
|
||||
using Content.Shared.Throwing;
|
||||
using Content.Shared.Weapons.Melee;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
@@ -28,7 +29,8 @@ namespace Content.Server.Damage.Systems
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<DamageOtherOnHitComponent, ThrowDoHitEvent>(OnDoHit);
|
||||
SubscribeLocalEvent<DamageOtherOnHitComponent, ThrowDoHitEvent>(OnDoHit,
|
||||
before: new[] {typeof(MeleeThrowOnHitSystem)}); // WD EDIT
|
||||
SubscribeLocalEvent<DamageOtherOnHitComponent, DamageExamineEvent>(OnDamageExamine);
|
||||
}
|
||||
|
||||
@@ -55,7 +57,7 @@ namespace Content.Server.Damage.Systems
|
||||
_color.RaiseEffect(Color.Red, new List<EntityUid>() { args.Target }, Filter.Pvs(args.Target, entityManager: EntityManager));
|
||||
}
|
||||
|
||||
_guns.PlayImpactSound(args.Target, dmg, null, false);
|
||||
_guns.PlayImpactSound(args.Target, dmg, component.Sound, component.Sound != null); // WD EDIT
|
||||
if (TryComp<PhysicsComponent>(uid, out var body) && body.LinearVelocity.LengthSquared() > 0f)
|
||||
{
|
||||
var direction = body.LinearVelocity.Normalized();
|
||||
|
||||
@@ -3,15 +3,12 @@ using Content.Server._Miracle.GulagSystem;
|
||||
using Content.Server.Actions;
|
||||
using Content.Server.Antag;
|
||||
using Content.Server.Bible.Components;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.GameTicking.Rules;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.NPC.Systems;
|
||||
using Content.Server.Objectives.Components;
|
||||
using Content.Server.Roles;
|
||||
using Content.Server.Roles.Jobs;
|
||||
using Content.Server.RoundEnd;
|
||||
using Content.Server.Shuttles.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Server.Storage.EntitySystems;
|
||||
using Content.Shared.Body.Systems;
|
||||
@@ -29,6 +26,7 @@ using Content.Shared._White;
|
||||
using Content.Shared._White.Cult.Components;
|
||||
using Content.Shared._White.Cult.Systems;
|
||||
using Content.Shared._White.Mood;
|
||||
using Content.Shared.Cloning;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.NPC.Systems;
|
||||
using Robust.Server.Player;
|
||||
@@ -72,10 +70,16 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
|
||||
SubscribeLocalEvent<CultistComponent, ComponentInit>(OnCultistComponentInit);
|
||||
SubscribeLocalEvent<CultistComponent, ComponentRemove>(OnCultistComponentRemoved);
|
||||
SubscribeLocalEvent<CultistComponent, MobStateChangedEvent>(OnCultistsStateChanged);
|
||||
SubscribeLocalEvent<CultistComponent, CloningEvent>(OnClone);
|
||||
|
||||
SubscribeLocalEvent<CultistRoleComponent, GetBriefingEvent>(OnGetBriefing);
|
||||
}
|
||||
|
||||
private void OnClone(Entity<CultistComponent> ent, ref CloningEvent args)
|
||||
{
|
||||
RemoveObjectiveAndRole(ent);
|
||||
}
|
||||
|
||||
protected override void Added(EntityUid uid, CultRuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args)
|
||||
{
|
||||
base.Added(uid, component, gameRule, args);
|
||||
@@ -178,6 +182,21 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveObjectiveAndRole(EntityUid uid)
|
||||
{
|
||||
if (!_mindSystem.TryGetMind(uid, out var mindId, out var mind))
|
||||
return;
|
||||
|
||||
var objectives = mind.Objectives.FindAll(HasComp<PickCultTargetComponent>);
|
||||
foreach (var obj in objectives)
|
||||
{
|
||||
_mindSystem.TryRemoveObjective(mindId, mind, mind.Objectives.IndexOf(obj));
|
||||
}
|
||||
|
||||
if (_roleSystem.MindHasRole<CultistRoleComponent>(mindId))
|
||||
_roleSystem.MindRemoveRole<CultistRoleComponent>(mindId);
|
||||
}
|
||||
|
||||
private void OnCultistComponentRemoved(EntityUid uid, CultistComponent component, ComponentRemove args)
|
||||
{
|
||||
var query = QueryActiveRules();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Threading;
|
||||
using Content.Server._White.Cult.GameRule;
|
||||
using Content.Server.Objectives.Components;
|
||||
using Content.Server.Popups;
|
||||
using Content.Server.Roles;
|
||||
@@ -8,6 +9,7 @@ using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared._White.Cult.Components;
|
||||
using Content.Shared._White.Mood;
|
||||
using Content.Shared.Jittering;
|
||||
using Content.Shared.Mind;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.Containers;
|
||||
@@ -40,6 +42,8 @@ public sealed partial class DeconvertCultist : ReagentEffect
|
||||
|
||||
args.EntityManager.System<StunSystem>()
|
||||
.TryParalyze(uid, TimeSpan.FromSeconds(component.HolyConvertTime + 5f), true);
|
||||
args.EntityManager.System<SharedJitteringSystem>()
|
||||
.DoJitter(uid, TimeSpan.FromSeconds(component.HolyConvertTime + 5f), true);
|
||||
var target = Identity.Name(uid, args.EntityManager);
|
||||
args.EntityManager.System<PopupSystem>()
|
||||
.PopupEntity(Loc.GetString("holy-water-started-converting", ("target", target)), uid);
|
||||
@@ -73,20 +77,8 @@ public sealed partial class DeconvertCultist : ReagentEffect
|
||||
entityManager.RemoveComponent<CultistComponent>(uid);
|
||||
entityManager.RemoveComponent<PentagramComponent>(uid);
|
||||
|
||||
var mindSystem = entityManager.System<SharedMindSystem>();
|
||||
var roleSystem = entityManager.System<RoleSystem>();
|
||||
|
||||
if (!mindSystem.TryGetMind(uid, out var mindId, out var mind))
|
||||
return;
|
||||
|
||||
var objectives = mind.Objectives.FindAll(entityManager.HasComponent<PickCultTargetComponent>);
|
||||
foreach (var obj in objectives)
|
||||
{
|
||||
mindSystem.TryRemoveObjective(mindId, mind, mind.Objectives.IndexOf(obj));
|
||||
}
|
||||
|
||||
if (roleSystem.MindHasRole<CultistRoleComponent>(mindId))
|
||||
roleSystem.MindRemoveRole<CultistRoleComponent>(mindId);
|
||||
var cultRuleSystem = entityManager.System<CultRuleSystem>();
|
||||
cultRuleSystem.RemoveObjectiveAndRole(uid);
|
||||
|
||||
entityManager.EventBus.RaiseLocalEvent(uid, new MoodRemoveEffectEvent("CultFocused"));
|
||||
}
|
||||
|
||||
@@ -159,6 +159,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
||||
_handsSystem.TryForcePickupAnyHand(msg.Performer, recallComponent.Item.Value);
|
||||
|
||||
msg.Handled = true;
|
||||
Speak(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ public sealed partial class WizardRuleComponent : Component
|
||||
[DataField]
|
||||
public ProtoId<NpcFactionPrototype> Faction = "Wizard";
|
||||
|
||||
public RoundEndBehavior RoundEndBehavior = RoundEndBehavior.Nothing;
|
||||
public RoundEndBehavior RoundEndBehavior = RoundEndBehavior.ShuttleCall;
|
||||
|
||||
[DataField]
|
||||
public string RoundEndTextSender = "comms-console-announcement-title-centcom";
|
||||
|
||||
@@ -545,7 +545,7 @@ namespace Content.Shared.Cuffs
|
||||
BreakOnWeightlessMove = false,
|
||||
BreakOnDamage = true,
|
||||
NeedHand = true,
|
||||
DistanceThreshold = 0.3f
|
||||
DistanceThreshold = 1f // shorter than default but still feels good
|
||||
};
|
||||
|
||||
if (!_doAfter.TryStartDoAfter(doAfterEventArgs))
|
||||
@@ -650,7 +650,7 @@ namespace Content.Shared.Cuffs
|
||||
BreakOnDamage = true,
|
||||
NeedHand = true,
|
||||
RequireCanInteract = false, // Trust in UncuffAttemptEvent
|
||||
DistanceThreshold = 0.3f
|
||||
DistanceThreshold = 1f // shorter than default but still feels good
|
||||
};
|
||||
|
||||
if (!_doAfter.TryStartDoAfter(doAfterEventArgs))
|
||||
|
||||
@@ -5,8 +5,8 @@ using Content.Shared.Charges.Systems;
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Ninja.Components;
|
||||
using Content.Shared.Physics;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Examine;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
@@ -21,7 +21,7 @@ public sealed class DashAbilitySystem : EntitySystem
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedChargesSystem _charges = default!;
|
||||
[Dependency] private readonly SharedHandsSystem _hands = default!;
|
||||
[Dependency] private readonly SharedInteractionSystem _interaction = default!;
|
||||
[Dependency] private readonly ExamineSystemShared _examine = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly ActionContainerSystem _actionContainer = default!;
|
||||
@@ -81,11 +81,10 @@ public sealed class DashAbilitySystem : EntitySystem
|
||||
_popup.PopupClient(Loc.GetString("dash-ability-no-charges", ("item", uid)), user, user);
|
||||
return;
|
||||
}
|
||||
|
||||
var origin = Transform(user).MapPosition;
|
||||
var origin = _transform.GetMapCoordinates(user);
|
||||
var target = args.Target.ToMap(EntityManager, _transform);
|
||||
// prevent collision with the user duh
|
||||
if (!_interaction.InRangeUnobstructed(origin, target, 0f, CollisionGroup.Opaque, uid => uid == user))
|
||||
if (!_examine.InRangeUnOccluded(origin, target, SharedInteractionSystem.MaxRaycastRange, null))
|
||||
{
|
||||
// can only dash if the destination is visible on screen
|
||||
_popup.PopupClient(Loc.GetString("dash-ability-cant-see", ("item", uid)), user, user);
|
||||
|
||||
@@ -59,7 +59,7 @@ public sealed class StepTriggerSystem : EntitySystem
|
||||
|
||||
if (component.Blacklist != null && TryComp<MapGridComponent>(transform.GridUid, out var grid))
|
||||
{
|
||||
var positon = _map.LocalToTile(uid, grid, transform.Coordinates);
|
||||
var positon = _map.LocalToTile(transform.GridUid.Value, grid, transform.Coordinates);
|
||||
var anch = _map.GetAnchoredEntitiesEnumerator(uid, grid, positon);
|
||||
|
||||
while (anch.MoveNext(out var ent))
|
||||
|
||||
@@ -47,6 +47,16 @@ public sealed partial class MeleeThrowOnHitComponent : Component
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
[AutoNetworkedField]
|
||||
public bool Enabled = true;
|
||||
|
||||
// WD START
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
[AutoNetworkedField]
|
||||
public float StunTime;
|
||||
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
[AutoNetworkedField]
|
||||
public bool ThrowOnThrowHit;
|
||||
// WD END
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared.Construction.Components;
|
||||
using Content.Shared.Stunnable;
|
||||
using Content.Shared.Throwing;
|
||||
using Content.Shared.Weapons.Melee.Components;
|
||||
using Content.Shared.Weapons.Melee.Events;
|
||||
using Robust.Shared.Physics;
|
||||
@@ -18,22 +20,67 @@ public sealed class MeleeThrowOnHitSystem : EntitySystem
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
||||
[Dependency] private readonly SharedStunSystem _stun = default!; // WD
|
||||
[Dependency] private readonly ThrownItemSystem _thrownItem = default!; // WD
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<MeleeThrowOnHitComponent, ThrowDoHitEvent>(OnDoHit); // WD
|
||||
|
||||
SubscribeLocalEvent<MeleeThrowOnHitComponent, MeleeHitEvent>(OnMeleeHit);
|
||||
SubscribeLocalEvent<MeleeThrownComponent, ComponentStartup>(OnThrownStartup);
|
||||
SubscribeLocalEvent<MeleeThrownComponent, ComponentShutdown>(OnThrownShutdown);
|
||||
SubscribeLocalEvent<MeleeThrownComponent, StartCollideEvent>(OnStartCollide);
|
||||
}
|
||||
|
||||
private void OnDoHit(Entity<MeleeThrowOnHitComponent> ent, ref ThrowDoHitEvent args) // WD
|
||||
{
|
||||
if (!ent.Comp.ThrowOnThrowHit)
|
||||
return;
|
||||
|
||||
if (!CanThrowOnHit(ent, args.Target))
|
||||
return;
|
||||
|
||||
if (!TryComp(ent, out PhysicsComponent? physics))
|
||||
return;
|
||||
|
||||
var velocity = physics.LinearVelocity.Normalized() * ent.Comp.Speed;
|
||||
|
||||
RemComp<MeleeThrownComponent>(args.Target);
|
||||
var thrownComp = new MeleeThrownComponent
|
||||
{
|
||||
Velocity = velocity,
|
||||
Lifetime = ent.Comp.Lifetime,
|
||||
MinLifetime = ent.Comp.MinLifetime
|
||||
};
|
||||
AddComp(args.Target, thrownComp);
|
||||
if (ent.Comp.StunTime != 0f)
|
||||
_stun.TryParalyze(args.Target, TimeSpan.FromSeconds(ent.Comp.StunTime), true);
|
||||
|
||||
_thrownItem.LandComponent(ent, args.Component, physics, false);
|
||||
_physics.SetLinearVelocity(ent, Vector2.Zero);
|
||||
}
|
||||
|
||||
private void OnMeleeHit(Entity<MeleeThrowOnHitComponent> ent, ref MeleeHitEvent args)
|
||||
{
|
||||
var (_, comp) = ent;
|
||||
if (!args.IsHit)
|
||||
return;
|
||||
|
||||
// WD START
|
||||
var stunTime = comp.StunTime;
|
||||
var speed = comp.Speed;
|
||||
var lifetime = comp.Lifetime;
|
||||
|
||||
if (args.Direction != null) // Heavy attack
|
||||
{
|
||||
stunTime = 0f;
|
||||
speed *= 0.5f;
|
||||
lifetime *= 0.5f;
|
||||
}
|
||||
// WD END
|
||||
|
||||
var mapPos = _transform.GetMapCoordinates(args.User).Position;
|
||||
foreach (var hit in args.HitEntities)
|
||||
{
|
||||
@@ -55,11 +102,13 @@ public sealed class MeleeThrowOnHitSystem : EntitySystem
|
||||
RaiseLocalEvent(hit, ref ev);
|
||||
var thrownComp = new MeleeThrownComponent
|
||||
{
|
||||
Velocity = angle.Normalized() * comp.Speed,
|
||||
Lifetime = comp.Lifetime,
|
||||
Velocity = angle.Normalized() * speed, // WD EDIT
|
||||
Lifetime = lifetime, // WD EDIT
|
||||
MinLifetime = comp.MinLifetime
|
||||
};
|
||||
AddComp(hit, thrownComp);
|
||||
if (stunTime != 0f)
|
||||
_stun.TryParalyze(hit, TimeSpan.FromSeconds(stunTime), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BIN
Resources/Audio/White/Magic/Mjolnir/hit.ogg
Normal file
BIN
Resources/Audio/White/Magic/Mjolnir/swing.ogg
Normal file
@@ -4271,3 +4271,140 @@
|
||||
id: 298
|
||||
time: '2024-06-12T20:28:18.0000000+00:00'
|
||||
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/349
|
||||
- author: Aviu
|
||||
changes:
|
||||
- message: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D \u043C\u044C\u0451\u043B\
|
||||
\u044C\u043D\u0438\u0440 \u0432 \u043A\u043D\u0438\u0433\u0443 \u0437\u0430\u043A\
|
||||
\u043B\u0438\u043D\u0430\u043D\u0438\u0439."
|
||||
type: Add
|
||||
id: 299
|
||||
time: '2024-06-13T23:56:59.0000000+00:00'
|
||||
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/350
|
||||
- author: Remuchi
|
||||
changes:
|
||||
- message: "\u0422\u0435\u043F\u0435\u0440\u044C \u0432\u0441\u043F\u043B\u044B\u0432\
|
||||
\u0430\u044E\u0449\u0438\u0435 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\
|
||||
\u044F \u043D\u0435 \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0430\u044E\u0442\
|
||||
\u0441\u044F \u0432 \u0447\u0430\u0442\u0435, \u0435\u0441\u043B\u0438 \u0438\
|
||||
\u0433\u0440\u043E\u043A \u0438\u0445 \u043D\u0435 \u0432\u0438\u0434\u0438\u0442"
|
||||
type: Fix
|
||||
id: 300
|
||||
time: '2024-06-14T11:47:15.0000000+00:00'
|
||||
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/354
|
||||
- author: Aviu
|
||||
changes:
|
||||
- message: "\u0423\u0431\u0440\u0430\u043D\u044B \u0431\u043E\u0442\u0438\u043D\u043A\
|
||||
\u0438 \u043A\u043E\u0441\u043C\u043E\u043D\u0438\u043D\u0434\u0437\u044F \u0441\
|
||||
\ \u0432\u0430\u0439\u0442\u0431\u043E\u043A\u0441\u0430."
|
||||
type: Remove
|
||||
id: 301
|
||||
time: '2024-06-14T14:01:37.0000000+00:00'
|
||||
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/353
|
||||
- author: Aviu
|
||||
changes:
|
||||
- message: "\u0411\u043E\u043B\u044C\u0448\u0435 \u043D\u0435\u043B\u044C\u0437\u044F\
|
||||
\ \u0441\u0433\u043E\u0440\u0435\u0442\u044C, \u0441\u0442\u043E\u044F \u043D\
|
||||
\u0430 \u043C\u043E\u0441\u0442\u0438\u043A\u0435 \u043D\u0430\u0434 \u043B\u0430\
|
||||
\u0432\u043E\u0439."
|
||||
type: Fix
|
||||
- message: "\u0423\u0432\u0435\u043B\u0438\u0447\u0435\u043D\u0430 \u0434\u0430\u043B\
|
||||
\u044C\u043D\u043E\u0441\u0442\u044C \u043D\u0430\u0434\u0435\u0432\u0430\u043D\
|
||||
\u0438\u044F \u043D\u0430\u0440\u0443\u0447\u043D\u0438\u043A\u043E\u0432."
|
||||
type: Tweak
|
||||
id: 302
|
||||
time: '2024-06-14T14:01:02.0000000+00:00'
|
||||
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/356
|
||||
- author: Aviu
|
||||
changes:
|
||||
- message: "\u041A\u0443\u043B\u044C\u0442\u0438\u0441\u0442\u044B \u0442\u0435\u043F\
|
||||
\u0435\u0440\u044C \u0442\u0440\u044F\u0441\u0443\u0442\u0441\u044F \u043F\u0440\
|
||||
\u0438 \u0434\u0435\u043A\u043E\u043D\u0432\u0435\u0440\u0442\u0430\u0446\u0438\
|
||||
\u0438."
|
||||
type: Add
|
||||
- message: "\u041F\u043E\u0441\u043B\u0435 \u043A\u043B\u043E\u043D\u0438\u0440\u043E\
|
||||
\u0432\u0430\u043D\u0438\u044F \u0443 \u043A\u0443\u043B\u044C\u0442\u0438\u0441\
|
||||
\u0442\u043E\u0432 \u043F\u0440\u043E\u043F\u0430\u0434\u0430\u0435\u0442 \u0446\
|
||||
\u0435\u043B\u044C, \u0440\u043E\u043B\u044C, \u0438 \u0438\u0445 \u043C\u043E\
|
||||
\u0436\u043D\u043E \u0441\u043D\u043E\u0432\u0430 \u0441\u043A\u043E\u043D\u0432\
|
||||
\u0435\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C."
|
||||
type: Fix
|
||||
- message: "\u0414\u0432\u0435\u0440\u044C \u043A\u0443\u043B\u044C\u0442\u0430\
|
||||
\ \u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0435\u043B\u044C\u0437\u044F\
|
||||
\ \u0440\u0430\u0437\u043E\u0431\u0440\u0430\u0442\u044C \u0420\u0426\u0414."
|
||||
type: Fix
|
||||
- message: "\u0423\u043C\u0435\u043D\u044C\u0448\u0435\u043D \u0441\u0442\u0440\u0443\
|
||||
\u043A\u0442\u0443\u0440\u043D\u044B\u0439 \u0443\u0440\u043E\u043D \u0443 \u0447\
|
||||
\u0435\u043B\u044E\u0441\u0442\u0435\u0439 \u0436\u0438\u0437\u043D\u0438."
|
||||
type: Tweak
|
||||
- message: "\u0423\u043C\u0435\u043D\u044C\u0448\u0435\u043D\u043E \u043A\u043E\u043B\
|
||||
\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u0434\u0440\u043E\u0431\u0438\u043B\
|
||||
\u043E\u043A \u0438 \u043F\u043A\u0430 \u0432 \u0430\u0432\u0442\u043E\u043C\
|
||||
\u0430\u0442\u0435 \u0443\u0442\u0438\u043B\u0438\u0437\u0430\u0442\u043E\u0440\
|
||||
\u043E\u0432."
|
||||
type: Tweak
|
||||
- message: "\u0421\u0442\u044F\u0436\u043A\u0438 \u0442\u0435\u043F\u0435\u0440\u044C\
|
||||
\ \u043D\u0435 \u0441\u043D\u0438\u043C\u0430\u044E\u0442\u0441\u044F \u0437\
|
||||
\u0430 3 \u0441\u0435\u043A\u0443\u043D\u0434\u044B."
|
||||
type: Tweak
|
||||
- message: "\u0412\u043E\u0437\u0432\u0440\u0430\u0449\u0435\u043D\u043E \u043C\u0430\
|
||||
\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u043E\u0435 \u0445\u0440\u0430\
|
||||
\u043D\u0438\u043B\u0438\u0449\u0435 \u0440\u0435\u0430\u0433\u0435\u043D\u0442\
|
||||
\u043E\u0432 \u0432 \u043A\u043E\u043F\u044C\u044F\u0445 5 \u0435\u0434\u0438\
|
||||
\u043D\u0438\u0446."
|
||||
type: Tweak
|
||||
- message: "\u041A\u0440\u043E\u0432\u0430\u0432\u043E\u0435 \u043A\u043E\u043F\u044C\
|
||||
\u0451 \u043C\u043E\u0436\u043D\u043E \u043F\u043E\u0432\u0435\u0441\u0438\u0442\
|
||||
\u044C \u043D\u0430 \u0431\u0440\u043E\u043D\u044E, \u043A\u0430\u043A \u0438\
|
||||
\ \u043E\u0441\u0442\u0430\u043B\u044C\u043D\u044B\u0435 \u043A\u043E\u043F\u044C\
|
||||
\u044F."
|
||||
type: Tweak
|
||||
id: 303
|
||||
time: '2024-06-14T14:01:26.0000000+00:00'
|
||||
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/355
|
||||
- author: Aviu
|
||||
changes:
|
||||
- message: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u044B \u043E\u043F\u0438\
|
||||
\u0441\u0430\u043D\u0438\u044F \u0432\u0441\u0435\u043C \u0437\u0430\u043A\u043B\
|
||||
\u0438\u043D\u0430\u043D\u0438\u044F\u043C \u043C\u0430\u0433\u0430."
|
||||
type: Add
|
||||
- message: "\u0420\u0435\u0436\u0438\u043C \u043C\u0430\u0433\u0430 \u0434\u043E\
|
||||
\u0431\u0430\u0432\u043B\u0435\u043D \u0432 \u0441\u0435\u043A\u0440\u0435\u0442\
|
||||
."
|
||||
type: Add
|
||||
- message: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0430 \u0431\u0440\u043E\
|
||||
\u043D\u044F \u043C\u0430\u0433\u0443\u0441\u0430 \u043D\u0430 \u0448\u0430\u0442\
|
||||
\u0442\u043B \u043C\u0430\u0433\u0430, \u043D\u043E \u0432 \u043D\u0435\u0439\
|
||||
\ \u043D\u0435\u043B\u044C\u0437\u044F \u043A\u0430\u0441\u0442\u043E\u0432\u0430\
|
||||
\u0442\u044C \u0431\u043E\u043B\u044C\u0448\u0438\u043D\u0441\u0442\u0432\u043E\
|
||||
\ \u0437\u0430\u043A\u043B\u0438\u043D\u0430\u043D\u0438\u0439."
|
||||
type: Add
|
||||
id: 304
|
||||
time: '2024-06-15T00:47:50.0000000+00:00'
|
||||
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/352
|
||||
- author: Aviu
|
||||
changes:
|
||||
- message: "\u041D\u0438\u043D\u0434\u0437\u044E \u0432 \u0441\u0442\u0435\u043B\
|
||||
\u0441\u0435 \u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0435 \u043F\u043E\u043A\
|
||||
\u0430\u0437\u044B\u0432\u0430\u044E\u0442 \u0445\u0443\u0434\u044B."
|
||||
type: Fix
|
||||
- message: "\u041F\u0440\u0438 \u0430\u0433\u043E\u0441\u0442\u0435 \u0443 \u043F\
|
||||
\u0435\u0440\u0441\u043E\u043D\u0430\u0436\u0430 \u0431\u043E\u043B\u044C\u0448\
|
||||
\u0435 \u043D\u0435 \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0430\u0435\u0442\
|
||||
\u0441\u044F \u0421\u0421\u0414 \u0438\u043D\u0434\u0438\u043A\u0430\u0442\u043E\
|
||||
\u0440."
|
||||
type: Fix
|
||||
- message: "\u041D\u0438\u043D\u0434\u0437\u044F \u0432 \u0441\u0442\u0435\u043B\
|
||||
\u0441\u0435 \u0442\u0435\u043F\u0435\u0440\u044C \u043C\u0435\u043D\u0435\u0435\
|
||||
\ \u0437\u0430\u043C\u0435\u0442\u0435\u043D."
|
||||
type: Tweak
|
||||
id: 305
|
||||
time: '2024-06-15T13:11:59.0000000+00:00'
|
||||
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/357
|
||||
- author: ThereDrD
|
||||
changes:
|
||||
- message: "\u0420\u0435\u0441\u043F\u0440\u0430\u0439\u0442 \u0441\u0432\u0438\u0442\
|
||||
\u043A\u0430"
|
||||
type: Add
|
||||
id: 306
|
||||
time: '2024-06-15T13:37:17.0000000+00:00'
|
||||
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/358
|
||||
|
||||
53
Resources/Locale/ru-RU/_white/wizard/spellbook.ftl
Normal file
@@ -0,0 +1,53 @@
|
||||
spellbook-fireball-name = { ent-ActionFireballSpell }
|
||||
spellbook-fireball-desc = { ent-ActionFireballSpell.desc }
|
||||
|
||||
spellbook-forcewall-name = { ent-ActionForcewallSpell }
|
||||
spellbook-forcewall-desc = { ent-ActionForcewallSpell.desc }
|
||||
|
||||
spellbook-knock-name = { ent-ActionKnock }
|
||||
spellbook-knock-desc = { ent-ActionKnock.desc }
|
||||
|
||||
spellbook-arc-name = { ent-ActionElectricArcSpell }
|
||||
spellbook-arc-desc = { ent-ActionElectricArcSpell.desc }
|
||||
|
||||
spellbook-force-name = { ent-ActionForceSpell }
|
||||
spellbook-force-desc = { ent-ActionForceSpell.desc }
|
||||
|
||||
spellbook-cards-name = { ent-ActionCardSpell }
|
||||
spellbook-cards-desc = { ent-ActionCardSpell.desc }
|
||||
|
||||
spellbook-blink-name = { ent-ActionBlinkSpell }
|
||||
spellbook-blink-desc = { ent-ActionBlinkSpell.desc }
|
||||
|
||||
spellbook-jaunt-name = { ent-ActionEtherealJauntSpell }
|
||||
spellbook-jaunt-desc = { ent-ActionEtherealJauntSpell.desc }
|
||||
|
||||
spellbook-emp-name = { ent-ActionEmpSpell }
|
||||
spellbook-emp-desc = { ent-ActionEmpSpell.desc }
|
||||
|
||||
spellbook-cluwne-name = { ent-ActionCluwneCurseSpell }
|
||||
spellbook-cluwne-desc = { ent-ActionCluwneCurseSpell.desc }
|
||||
|
||||
spellbook-clown-name = { ent-ActionBananaTouchSpell }
|
||||
spellbook-clown-desc = { ent-ActionBananaTouchSpell.desc }
|
||||
|
||||
spellbook-mime-name = { ent-ActionMimeTouchSpell }
|
||||
spellbook-mime-desc = { ent-ActionMimeTouchSpell.desc }
|
||||
|
||||
spellbook-recall-name = { ent-ActionInstantRecallSpell }
|
||||
spellbook-recall-desc = { ent-ActionInstantRecallSpell.desc }
|
||||
|
||||
spellbook-smite-name = { ent-ActionSmite }
|
||||
spellbook-smite-desc = { ent-ActionSmite.desc }
|
||||
|
||||
spellbook-hardsuit-name = Скафандр волшебника
|
||||
spellbook-hardsuit-desc = Украшенный магическими драгоценными камнями скафандр, функционирующий так же, как и обычная мантия волшебника, но в то же время является пригодным для использования в космосе и бронированным. Небольшое замедление. Теперь вы можете произносить заклинания в космосе и местах с низкой температурой! Имеет функцию энергетического щита,который защищает от всех снарядов. Щит разряжается при получении урона и автоматически заряжается.
|
||||
|
||||
spellbook-hfrequency-name = Высокочастотный клинок
|
||||
spellbook-hfrequency-desc = Невероятно мощный клинок, способный атаковать очень, ОЧЕНЬ быстро. Также клинок способен отражать выстрелы.
|
||||
|
||||
spellbook-spellblade-name = Клинок заклинаний
|
||||
spellbook-spellblade-desc = Клинок, наполненный магией, можно усилить, выбрав один из пяти аспектов.
|
||||
|
||||
spellbook-mjolnir-name = Мьёльнир
|
||||
spellbook-mjolnir-desc = Могучий двуручный молот Тора. Ударив им по врагам, вы заставите их отлететь от вас, а также оглушить на 1,5 секунды. Вы можете его бросить для достижения того же эффекта.
|
||||
44
Resources/Locale/ru-RU/_white/wizard/spells.ftl
Normal file
@@ -0,0 +1,44 @@
|
||||
ent-ActionElectricArcSpell = Электрическая дуга
|
||||
.desc = Выпускает из ваших рук мощную молнию, способную сразить любого члена экипажа. Альтернативный каст: выпускает взрывающуюся шаровую молнию. При зарядке: выпускает несколько молний вокруг вас. Не работает без волшебной мантии и шляпы.
|
||||
|
||||
ent-ActionForceSpell = Сила
|
||||
.desc = Притягивает все объекты и сущности в указанную точку. Альтернативный каст: Прицельно притягивает к вам предмет или сущность. При зарядке: Вместо притяжение в выбранную точку, отталкивает все объекты от заклинателя. С каждым уровнем повышается мощность отталкивания.
|
||||
|
||||
ent-ActionFireballSpell = Огненный шар
|
||||
.desc = Создает огненный шар, наносящий огромный урон при взрыве. Альтернативный каст: Поджигает одну цель на любом расстоянии, навешивая проклятие, при котором смерть от огня уничтожит тело. При зарядке: Поджигает все сущности вокруг, с каждым уровнем повышается сила поджога и радиус поражения. Не работает без волшебной мантии и шляпы.
|
||||
|
||||
ent-ActionCardSpell = Карты
|
||||
.desc = Настоящий козырь в рукаве! Вернее, целая колода таких. Выпускает несколько смертельных карт в одном направлении. Карты способны оглушить цель. Альтернативный каст: Превращает в карту любой предмет. В карту можно превратить только предметы. При зарядке: Выпускает карты вокруг вас, с каждым уровнем зарядки количество выпускаемых карт повышается.
|
||||
|
||||
ent-ActionForcewallSpell = Силовой барьер
|
||||
.desc = Создает перед заклинателем 3 барьера. Альтернативный каст: Позволяет поставить барьер 3x3 в любой точке. При зарядке: Барьеры появляются не перед магом, а вокруг него, с каждым уровнем будет повышаться количество барьеров. Не работает без волшебной мантии и шляпы.
|
||||
|
||||
ent-ActionBlinkSpell = Прыжок
|
||||
.desc = Переносит на несколько тайлов вперед.
|
||||
|
||||
ent-ActionEtherealJauntSpell = Потустороннее путешествие
|
||||
.desc = Создаёт вашу астральную форму, временно делая вас невидимым и способным проходить сквозь стены. Не работает без волшебной мантии и шляпы.
|
||||
|
||||
ent-ActionEmpSpell = ЭМИ
|
||||
.desc = Создаёт ЭМИ взрыв в огромном радиусе вокруг мага. Не работает без волшебной мантии и шляпы.
|
||||
|
||||
ent-ActionCluwneCurseSpell = Проклятье клувна
|
||||
.desc = Ужаснейшее проклятие, превращает цель в толстого и уродливого тупицу - клувень.
|
||||
|
||||
ent-ActionBananaTouchSpell = Банановое касание
|
||||
.desc = Превращает цель в клоуна.
|
||||
|
||||
ent-ActionMimeTouchSpell = Касание мима
|
||||
.desc = Превращает в мима любого члена экипажа, без возможности нарушить обет молчания.
|
||||
|
||||
ent-ActionInstantRecallSpell = Мгновенный призыв
|
||||
.desc = Привязывает к вашей душе отдельный предмет. Используйте это заклинание, удерживая предмет, чтобы пометить его. Снова примените заклинание и привязанный предмет телепортируется к вам в руку. Если вы отметили предмет и произнесли это заклинание, удерживая другой предмет, вы удалите исходную метку.
|
||||
|
||||
ent-ActionTeleportSpell = Телепортация
|
||||
.desc = Позволяет телепортироваться в любое место на станции! Переносит вас в выбранное место.
|
||||
|
||||
ent-ActionKnock = Стук
|
||||
.desc = Открывает все двери и шлюзы в радиусе 4 тайлов.
|
||||
|
||||
ent-ActionSmite = Кара
|
||||
.desc = Заряжает вашу руку мерзкой энергией, которую можно использовать для взрыва жертв. Заклинание требует, чтобы вы коснулись своей цели, поэтому вы не сможете использовать его в наручниках или будучи оглушённым. Не работает без волшебной мантии и шляпы.
|
||||
@@ -24,6 +24,18 @@ ent-WizardSurviveObjective = Переживете смену, устроив к
|
||||
ent-SpellBook = книга заклинаний
|
||||
.desc = Неземной фолиант, излучающий силу.
|
||||
|
||||
ent-ClothingHeadHatRealWizardFancy = волшебная шляпа
|
||||
.desc = Странный головной убор, который наверняка принадлежит настоящему магу.
|
||||
|
||||
ent-ClothingHeadHatRealWizardFancyAlt = волшебная шляпа
|
||||
.desc = Странный головной убор, который наверняка принадлежит настоящему магу.
|
||||
|
||||
ent-ClothingOuterRealWizardFancy = мантия волшебника
|
||||
.desc = Великолепная, украшенная драгоценными камнями мантия, которая, кажется, излучает силу.
|
||||
|
||||
ent-ClothingHeadHelmetWizardHelmArmored = шлем мага
|
||||
.desc = Странный головной убор, который наверняка принадлежит настоящему магу. Не обладает свойствами волшебной шляпы.
|
||||
|
||||
store-currency-display-spell-point = Очки заклинаний
|
||||
|
||||
store-category-spells-attack = Атакующие заклинания
|
||||
|
||||
@@ -17,10 +17,10 @@ ent-ClothingOuterArmorHeavyRed = красный тяжелый бронекос
|
||||
.desc = Тяжело бронированный костюм с красными вставками, способный защитить от высокого урона.
|
||||
.suffix = { "" }
|
||||
ent-ClothingOuterArmorMagusblue = синие доспехи магуса
|
||||
.desc = Синий бронекостюм, обеспечивающий хорошую защиту.
|
||||
.desc = Синий бронекостюм, обеспечивающий хорошую защиту. Не обладает свойствами волшебной мантии.
|
||||
.suffix = { "" }
|
||||
ent-ClothingOuterArmorMagusred = красные доспехи магуса
|
||||
.desc = Красный бронекостюм, обеспечивающий хорошую защиту.
|
||||
.desc = Красный бронекостюм, обеспечивающий хорошую защиту. Не обладает свойствами волшебной мантии.
|
||||
.suffix = { "" }
|
||||
ent-ClothingOuterArmorRiot = противоударный костюм
|
||||
.desc = Бронежилет с тяжелыми накладками для защиты в ближнем бою, идеально подходит для борьбы с правонарушителями на станции.
|
||||
|
||||
@@ -2050,6 +2050,18 @@ entities:
|
||||
- type: Transform
|
||||
pos: -5.52865,-9.359842
|
||||
parent: 2
|
||||
- proto: ClothingHeadHelmetWizardHelmArmored
|
||||
entities:
|
||||
- uid: 772
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -2.5,-1.5
|
||||
parent: 2
|
||||
- uid: 773
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,-1.5
|
||||
parent: 2
|
||||
- proto: ClothingMaskGasChameleon
|
||||
entities:
|
||||
- uid: 275
|
||||
@@ -2057,6 +2069,20 @@ entities:
|
||||
- type: Transform
|
||||
pos: -9.537922,-3.3987489
|
||||
parent: 2
|
||||
- proto: ClothingOuterArmorMagusblue
|
||||
entities:
|
||||
- uid: 771
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -2.505693,-1.8391577
|
||||
parent: 2
|
||||
- proto: ClothingOuterArmorMagusred
|
||||
entities:
|
||||
- uid: 770
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.4998147,-1.8497881
|
||||
parent: 2
|
||||
- proto: ClothingUniformJumpskirtColorBlack
|
||||
entities:
|
||||
- uid: 276
|
||||
|
||||
@@ -76640,13 +76640,6 @@ entities:
|
||||
- type: Transform
|
||||
pos: -15.657842,47.202713
|
||||
parent: 2
|
||||
- proto: ClothingShoesSpaceNinja
|
||||
entities:
|
||||
- uid: 10939
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 30.33621,-71.6811
|
||||
parent: 2
|
||||
- proto: ClothingUnderSocksBee
|
||||
entities:
|
||||
- uid: 10940
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
- type: vendingMachineInventory
|
||||
id: SalvageEquipmentInventory
|
||||
startingInventory:
|
||||
WeaponProtoKineticAccelerator: 4
|
||||
WeaponCrusher: 4
|
||||
WeaponProtoKineticAccelerator: 2
|
||||
WeaponCrusher: 2
|
||||
WeaponCrusherDagger: 4
|
||||
WeaponGrapplingGun: 3
|
||||
HandheldGPSBasic: 10
|
||||
|
||||
@@ -203,6 +203,18 @@
|
||||
- type: IngestionBlocker
|
||||
- type: IdentityBlocker
|
||||
|
||||
- type: entity
|
||||
parent: ClothingHeadHelmetWizardHelm
|
||||
id: ClothingHeadHelmetWizardHelmArmored
|
||||
components:
|
||||
- type: Armor
|
||||
modifiers:
|
||||
coefficients:
|
||||
Blunt: 0.8
|
||||
Slash: 0.8
|
||||
Piercing: 0.85
|
||||
Heat: 0.8
|
||||
|
||||
#Fire Helmet
|
||||
- type: entity
|
||||
parent: ClothingHeadLightBase
|
||||
|
||||
@@ -200,7 +200,7 @@
|
||||
sprite: Clothing/OuterClothing/Armor/heavyred.rsi
|
||||
|
||||
- type: entity
|
||||
parent: ClothingOuterArmorHeavy
|
||||
parent: ClothingOuterBaseLarge
|
||||
id: ClothingOuterArmorMagusblue
|
||||
name: blue magus armor
|
||||
description: An blue armored suit that provides good protection.
|
||||
@@ -209,9 +209,22 @@
|
||||
sprite: Clothing/OuterClothing/Armor/magusblue.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/OuterClothing/Armor/magusblue.rsi
|
||||
- type: Armor
|
||||
modifiers:
|
||||
coefficients:
|
||||
Blunt: 0.5
|
||||
Slash: 0.5
|
||||
Piercing: 0.6
|
||||
Heat: 0.5
|
||||
- type: ExplosionResistance
|
||||
damageCoefficient: 0.5
|
||||
- type: GroupExamine
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 1
|
||||
sprintModifier: 1
|
||||
|
||||
- type: entity
|
||||
parent: ClothingOuterArmorHeavy
|
||||
parent: ClothingOuterArmorMagusblue
|
||||
id: ClothingOuterArmorMagusred
|
||||
name: red magus armor
|
||||
description: A red armored suit that provides good protection.
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
- type: Clothing
|
||||
sprite: Clothing/OuterClothing/Suits/spaceninja.rsi
|
||||
- type: StealthClothing
|
||||
visibility: 1.1
|
||||
visibility: 0.5
|
||||
toggleAction: ActionTogglePhaseCloak
|
||||
- type: PressureProtection
|
||||
highPressureMultiplier: 0.6
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
parent: Handcuffs
|
||||
components:
|
||||
- type: Handcuff
|
||||
breakoutTime: 3
|
||||
cuffedRSI: Objects/Misc/cablecuffs.rsi
|
||||
bodyIconState: body-overlay
|
||||
color: forestgreen
|
||||
@@ -79,7 +78,6 @@
|
||||
size: Tiny
|
||||
storedRotation: 0
|
||||
- type: Handcuff
|
||||
breakoutTime: 3
|
||||
cuffedRSI: Objects/Misc/cablecuffs.rsi # cablecuffs will look fine
|
||||
bodyIconState: body-overlay
|
||||
breakOnRemove: true
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
damage:
|
||||
types:
|
||||
Blunt: 15
|
||||
Structural: 40
|
||||
Structural: 10
|
||||
soundHit:
|
||||
path: "/Audio/Weapons/smash.ogg"
|
||||
|
||||
@@ -89,4 +89,4 @@
|
||||
damage:
|
||||
types:
|
||||
Blunt: 20
|
||||
Structural: 60
|
||||
Structural: 20
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
melee:
|
||||
maxVol: 2
|
||||
maxVol: 5
|
||||
- type: MeleeChemicalInjector
|
||||
solution: melee
|
||||
- type: RefillableSolution
|
||||
|
||||
@@ -1244,7 +1244,7 @@
|
||||
name: force wall
|
||||
components:
|
||||
- type: TimedDespawn
|
||||
lifetime: 20
|
||||
lifetime: 9
|
||||
- type: Tag
|
||||
tags:
|
||||
- Wall
|
||||
|
||||
@@ -281,6 +281,7 @@
|
||||
sprite: Objects/Magic/magicactions.rsi
|
||||
state: summons
|
||||
event: !type:InstantRecallSpellEvent
|
||||
speech: "GAR YOK!"
|
||||
|
||||
- type: entity
|
||||
id: ActionTeleportSpell
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
- type: Clothing
|
||||
slots:
|
||||
- back
|
||||
- suitStorage
|
||||
- type: Wieldable
|
||||
- type: IncreaseDamageOnWield
|
||||
damage:
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
- type: Construction
|
||||
graph: AirlockGlassCult
|
||||
node: airlock
|
||||
- type: RCDDeconstructable
|
||||
deconstructable: false
|
||||
- type: PlacementReplacement
|
||||
key: walls
|
||||
- type: Appearance
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
types:
|
||||
Slash: 30
|
||||
- type: Clothing
|
||||
quickEquip: false
|
||||
sprite: White/Objects/Weapons/Chaplain/spellblade.rsi
|
||||
slots:
|
||||
- back
|
||||
@@ -51,3 +52,55 @@
|
||||
inHandsOnly: true
|
||||
closeOnHandDeselect: true
|
||||
- type: SpellBlade
|
||||
|
||||
- type: entity
|
||||
name: мьёльнир
|
||||
parent: BaseItem
|
||||
id: Mjolnir
|
||||
description: Могучий молот, заимствованный у Тора, бога грома. Он трещит от едва сдерживаемой силы.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: White/Objects/Weapons/mjolnir.rsi
|
||||
state: icon
|
||||
- type: MeleeWeapon
|
||||
wideAnimationRotation: -135
|
||||
attackRate: 0.75
|
||||
damage:
|
||||
types:
|
||||
Blunt: 25
|
||||
Structural: 20
|
||||
soundHit:
|
||||
path: /Audio/White/Magic/Mjolnir/hit.ogg
|
||||
soundSwing:
|
||||
path: /Audio/White/Magic/Mjolnir/swing.ogg
|
||||
- type: Wieldable
|
||||
- type: IncreaseDamageOnWield
|
||||
damage:
|
||||
types:
|
||||
Blunt: 15
|
||||
Structural: 60
|
||||
- type: Item
|
||||
size: Huge
|
||||
sprite: White/Objects/Weapons/mjolnir.rsi
|
||||
- type: Clothing
|
||||
quickEquip: false
|
||||
sprite: White/Objects/Weapons/mjolnir.rsi
|
||||
slots:
|
||||
- back
|
||||
- suitStorage
|
||||
- type: DisarmMalus
|
||||
- type: MeleeThrowOnHit
|
||||
lifetime: 0.05
|
||||
minLifetime: 0.01
|
||||
speed: 20
|
||||
stunTime: 1.5
|
||||
throwOnThrowHit: true
|
||||
- type: DamageOtherOnHit
|
||||
sound:
|
||||
path: /Audio/White/Magic/Mjolnir/hit.ogg
|
||||
damage:
|
||||
types:
|
||||
Blunt: 40
|
||||
Structural: 80
|
||||
- type: ChangeThrowForce
|
||||
throwForce: 20
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
- type: entity
|
||||
name: Холод
|
||||
description: Клинок заклинаний наделяется замораживать врагов. И тот, кто удерживает клинок в руках, становится неуязвимым к низкой температуре.
|
||||
description: Клинок заклинаний наделяется способностью замораживать врагов. И тот, кто удерживает клинок в руках, становится неуязвимым к низкой температуре.
|
||||
id: AspectFrost
|
||||
noSpawn: true
|
||||
components:
|
||||
|
||||
@@ -260,3 +260,16 @@
|
||||
conditions:
|
||||
- !type:ListingLimitedStockCondition
|
||||
stock: 1
|
||||
|
||||
- type: listing
|
||||
id: SpellBookMjolnir
|
||||
name: spellbook-mjolnir-name
|
||||
description: spellbook-mjolnir-desc
|
||||
productEntity: Mjolnir
|
||||
cost:
|
||||
SpellPoint: 2
|
||||
categories:
|
||||
- MagicItems
|
||||
conditions:
|
||||
- !type:ListingLimitedStockCondition
|
||||
stock: 1
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
- type: weightedRandom
|
||||
id: Secret
|
||||
weights:
|
||||
Traitor: 0.35
|
||||
Changeling: 0.15
|
||||
Nukeops: 0.15
|
||||
Traitor: 0.3
|
||||
Changeling: 0.14
|
||||
Nukeops: 0.14
|
||||
Cult: 0.15
|
||||
Revolutionary: 0.1
|
||||
Zombie: 0.05
|
||||
Survival: 0.05
|
||||
Wizard: 0.15
|
||||
Revolutionary: 0.04
|
||||
Zombie: 0.04
|
||||
Survival: 0.04
|
||||
|
||||
|
Before Width: | Height: | Size: 673 B After Width: | Height: | Size: 853 B |
|
After Width: | Height: | Size: 568 B |
BIN
Resources/Textures/White/Objects/Weapons/mjolnir.rsi/icon.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 686 B |
|
After Width: | Height: | Size: 681 B |
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"version": 1,
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/pull/49264/commits/d0dffe7ca643db2624424fdcebf45863f85c0448",
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"states": [
|
||||
{
|
||||
"name": "icon",
|
||||
"delays": [
|
||||
[
|
||||
2,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "inhand-left",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "inhand-right",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "wielded-inhand-left",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "wielded-inhand-right",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "equipped-BACKPACK",
|
||||
"directions": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 695 B |
|
After Width: | Height: | Size: 684 B |