Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
9dc7a82
Апгрейды
Kai518 Nov 16, 2025
a99c852
Wizard Teleport Scroll (Teleport Location ECS) (#36424)
keronshb Apr 28, 2025
335b7fa
Fix wizard can teleport into the ATS wall (#40755)
opl- Oct 8, 2025
68c2cc6
Wizard: Smoke Spell (#35403)
keronshb Feb 22, 2025
e743855
Wizard: Repulse Spell (#35377)
keronshb Feb 22, 2025
b6f3e54
Mjollnir and Singularity Hammer for Wizard (#34446)
keronshb Feb 20, 2025
7c19c03
Разное
Kai518 Nov 16, 2025
e88a944
Текстуры, фиксы и апгрейды
Kai518 Nov 16, 2025
a764909
Wizard Fix - Summon Ghost Event no longer shows Admin Ghosts or Reven…
keronshb Feb 16, 2025
63e479d
Fix wizard's recharge spell not adding charges to wands that use Limi…
Winkarst-cpu Sep 14, 2025
527d866
Фиксики
Kai518 Nov 16, 2025
037fd47
Линтер
Kai518 Nov 17, 2025
a12fb6d
Еще линтер
Kai518 Nov 17, 2025
c6bbd37
Ошибок в линтере много не бывает
Kai518 Nov 17, 2025
327e8d7
Линтер...
Kai518 Nov 17, 2025
596055b
Всякое
Kai518 Nov 18, 2025
72cfec1
Улучшение полиморфов
Kai518 Nov 18, 2025
5e9f507
Экипировочка
Kai518 Nov 18, 2025
457199b
финальные штрихи
Kai518 Nov 18, 2025
cf9aa8b
Линтер
Kai518 Nov 18, 2025
98b549b
Папочки
Kai518 Nov 21, 2025
eac5fa2
Merge remote-tracking branch 'upstream/master' into MakeWizardGreatAg…
Kai518 Nov 21, 2025
f74fa6c
Merge branch 'MakeDirectoriesGreatAgain' into MakeWizardGreatAgainPar…
Kai518 Nov 22, 2025
e0a7423
Merge remote-tracking branch 'upstream/master' into MakeWizardGreatAg…
Kai518 Nov 23, 2025
53c8964
Линтер
Kai518 Nov 23, 2025
6dbefb4
Еще проверки
Kai518 Nov 23, 2025
d7d3cb8
Update Content.Server/Polymorph/Systems/PolymorphSystem.cs
Kai518 Nov 27, 2025
2779ef4
Update Content.Server/Polymorph/Systems/PolymorphSystem.cs
Kai518 Nov 27, 2025
5cc1992
Update Content.Shared/_White/Wizard/ApprenticeComponent.cs
Kai518 Nov 27, 2025
a8258d6
Update Content.Shared/_White/Wizard/ApprenticeComponent.cs
Kai518 Nov 27, 2025
1424310
Update Content.Shared/_White/Wizard/WizardComponent.cs
Kai518 Nov 27, 2025
95307f8
Update Content.Shared/_White/Wizard/WizardComponent.cs
Kai518 Nov 27, 2025
ba6f534
Update Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml
Kai518 Nov 27, 2025
a1084f8
Update Content.Shared/Magic/Components/MagicComponent.cs
Kai518 Nov 27, 2025
6ce816d
Update Content.Shared/Magic/Components/MagicComponent.cs
Kai518 Nov 27, 2025
3685230
Update Content.Shared/Carrying/CarryingComponent.cs
Kai518 Nov 27, 2025
13e2058
Update Content.Shared/_White/Wizard/Projectiles/TrailComponent.cs
Kai518 Nov 27, 2025
5559a11
Update Content.Shared/_White/Wizard/Projectiles/TrailComponent.cs
Kai518 Nov 27, 2025
36a63b4
Update Content.Client/_White/Wizard/Trail/TrailOverlay.cs
Kai518 Nov 27, 2025
ac713b8
Update Content.Shared/_White/Wizard/Projectiles/EntityTrailComponent.cs
Kai518 Nov 27, 2025
4bb65ce
Update Content.Shared/_White/Wizard/Projectiles/EntityTrailComponent.cs
Kai518 Nov 27, 2025
b0eb520
Update Content.Shared/_White/Wizard/Projectiles/EntityTrailSystem.cs
Kai518 Nov 27, 2025
22895b7
Update Content.Server/Carrying/CarryingSystem.cs
Kai518 Nov 27, 2025
7329fef
Update Content.Server/Carrying/CarryingSystem.cs
Kai518 Nov 27, 2025
53cacaa
Update Content.Server/Carrying/CarryingSystem.cs
Kai518 Nov 27, 2025
e32f801
Update Content.Server/Carrying/CarryingSystem.cs
Kai518 Nov 27, 2025
8b7c49e
Меня достало перезагружать страницу гита после каждого коммита
Kai518 Nov 27, 2025
86c3eb3
Merge branch 'MakeWizardGreatAgainPartTwo' of https://github.com/Kai5…
Kai518 Nov 27, 2025
265128a
скобочка
Kai518 Nov 27, 2025
43b3b4b
Update Content.Shared/Magic/SharedMagicSystem.cs
Kai518 Dec 16, 2025
5c922ce
Update Content.Shared/Magic/SharedMagicSystem.cs
Kai518 Dec 16, 2025
ee56424
Update Content.Shared/Magic/SharedMagicSystem.cs
Kai518 Dec 16, 2025
d7d81c0
Update Content.Shared/Magic/SharedMagicSystem.cs
Kai518 Dec 16, 2025
b542485
Update Content.Server/_White/Wizard/Systems/WizardJauntSystem.cs
Kai518 Dec 16, 2025
2868792
Update Content.Server/_White/Wizard/Systems/WizardJauntSystem.cs
Kai518 Dec 16, 2025
db82400
Update Content.Server/_White/Wizard/Systems/WizardJauntSystem.cs
Kai518 Dec 16, 2025
86479e9
Update Content.Server/_White/Wizard/Systems/WizardJauntSystem.cs
Kai518 Dec 16, 2025
d07b70a
Update Content.Server/_White/Wizard/Systems/WizardJauntSystem.cs
Kai518 Dec 16, 2025
4a83b78
Update Content.Shared/Magic/SharedMagicSystem.cs
Kai518 Dec 16, 2025
b7c7fbc
Update Content.Server/Power/EntitySystems/BatterySystem.cs
Kai518 Dec 16, 2025
83556a7
Update Content.Shared/_White/Wizard/SharedSpellsSystem.cs
Kai518 Dec 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions Content.Client/_White/Wizard/SpellsSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using System.Numerics;
using Content.Client.Animations;
using Content.Shared._White.Wizard;
using Content.Shared._White.Wizard.SupermatterHalberd;
using Content.Shared.StatusIcon.Components;


namespace Content.Client._White.Wizard;


public sealed class SpellsSystem : SharedSpellsSystem
{
[Dependency] private readonly RaysSystem _rays = default!;
public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<WizardComponent, GetStatusIconsEvent>(GetWizardIcon);
SubscribeLocalEvent<ApprenticeComponent, GetStatusIconsEvent>(GetApprenticeIcon);

SubscribeAllEvent<ChargeSpellRaysEffectEvent>(OnChargeEffect);
}

private void OnChargeEffect(ChargeSpellRaysEffectEvent ev)
{
var uid = GetEntity(ev.Uid);

CreateChargeEffect(uid, ev);
}

public override void CreateChargeEffect(EntityUid uid, ChargeSpellRaysEffectEvent ev)
{
if (!Timing.IsFirstTimePredicted || uid == EntityUid.Invalid)
return;

var rays = _rays.DoRays(TransformSystem.GetMapCoordinates(uid),
Color.Yellow,
Color.Fuchsia,
10,
15,
minMaxRadius: new Vector2(3f, 6f),
proto: "EffectRayCharge",
server: false);

if (rays == null)
return;

var track = EnsureComp<TrackUserComponent>(rays.Value);
track.User = uid;
}

private void GetWizardIcon(Entity<WizardComponent> ent, ref GetStatusIconsEvent args)
{
if (ProtoMan.TryIndex(ent.Comp.StatusIcon, out var iconPrototype))
args.StatusIcons.Add(iconPrototype);
}

private void GetApprenticeIcon(Entity<ApprenticeComponent> ent, ref GetStatusIconsEvent args)
{
if (ProtoMan.TryIndex(ent.Comp.StatusIcon, out var iconPrototype))
args.StatusIcons.Add(iconPrototype);
}
}
166 changes: 166 additions & 0 deletions Content.Client/_White/Wizard/Trail/TrailOverlay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
using System.Numerics;
using Content.Shared._White.Wizard.Projectiles;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Shared.Enums;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using DrawDepth = Content.Shared.DrawDepth.DrawDepth;

namespace Content.Client._White.Wizard.Trail;

public sealed class TrailOverlay : Overlay
{
public override OverlaySpace Space => OverlaySpace.WorldSpaceEntities;

private readonly IEntityManager _entManager;
private readonly IPrototypeManager _protoMan;
private readonly IGameTiming _timing;

private readonly SpriteSystem _sprite;
private readonly TransformSystem _transform;

public TrailOverlay(IEntityManager entManager, IPrototypeManager protoMan, IGameTiming timing)
{
ZIndex = (int) DrawDepth.Effects;

_entManager = entManager;
_protoMan = protoMan;
_timing = timing;
_sprite = _entManager.System<SpriteSystem>();
_transform = _entManager.System<TransformSystem>();
}

protected override void Draw(in OverlayDrawArgs args)
{
var eye = args.Viewport.Eye;

if (eye == null)
return;

var eyeRot = eye.Rotation;
var handle = args.WorldHandle;
var bounds = args.WorldAABB;

var xformQuery = _entManager.GetEntityQuery<TransformComponent>();
var spriteQuery = _entManager.GetEntityQuery<SpriteComponent>();

var query = _entManager.EntityQueryEnumerator<TrailComponent, TransformComponent>();
while (query.MoveNext(out _, out var trail, out var xform))
{
if (trail.TrailData.Count == 0)
continue;

var (position, rotation) = _transform.GetWorldPositionRotation(xform, xformQuery);

if (trail.Shader != null && _protoMan.TryIndex<ShaderPrototype>(trail.Shader, out var shaderProto))
handle.UseShader(shaderProto.InstanceUnique());
Comment on lines +54 to +57
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Шейдер может "протекать" на следующие трейлы.

Если трейл A имеет шейдер, а трейл B — нет, то трейл B будет отрисован с шейдером трейла A, поскольку handle.UseShader(null) вызывается только в конце всего цикла (строка 144), а не перед каждым трейлом.

Примените этот diff для сброса шейдера перед каждым трейлом:

+            handle.UseShader(null);
+
             if (trail.Shader != null && _protoMan.TryIndex<ShaderPrototype>(trail.Shader, out var shaderProto))
                 handle.UseShader(shaderProto.InstanceUnique());
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var (position, rotation) = _transform.GetWorldPositionRotation(xform, xformQuery);
if (trail.Shader != null && _protoMan.TryIndex<ShaderPrototype>(trail.Shader, out var shaderProto))
handle.UseShader(shaderProto.InstanceUnique());
var (position, rotation) = _transform.GetWorldPositionRotation(xform, xformQuery);
handle.UseShader(null);
if (trail.Shader != null && _protoMan.TryIndex<ShaderPrototype>(trail.Shader, out var shaderProto))
handle.UseShader(shaderProto.InstanceUnique());
🤖 Prompt for AI Agents
In Content.Client/_White/Wizard/Trail/TrailOverlay.cs around lines 54 to 57, the
code only sets a shader when one exists, allowing a previously set shader to
"leak" to subsequent trails; reset the shader before processing each trail so
trails without a shader don't inherit the prior one — call
handle.UseShader(null) (or otherwise clear the shader) immediately before
checking trail.Shader / attempting to set a new shader, or add an else branch
that explicitly calls handle.UseShader(null) when trail.Shader is null.


if (trail.RenderedEntity != null)
{
Direction? direction = null;
var rot = rotation;
switch (trail.RenderedEntityRotationStrategy)
{
case LerpPropertyData.RenderedEntityRotationStrategy.Trail:
{
var dirRot = rotation + eyeRot;
direction = dirRot.GetCardinalDir();
break;
}
case LerpPropertyData.RenderedEntityRotationStrategy.RenderedEntity:
rot = _transform.GetWorldRotation(trail.RenderedEntity.Value);
break;
}

Entity<SpriteComponent?> sprite = trail.RenderedEntity.Value;
if (!spriteQuery.Resolve(sprite, ref sprite.Comp))
continue;
foreach (var data in trail.TrailData)
{
if (data.Color.A <= 0.01f || data.Scale <= 0.01f || data.MapId != args.MapId)
continue;
var worldPosition = data.Position;
if (!bounds.Contains(worldPosition))
continue;
if (trail.RenderedEntityRotationStrategy == LerpPropertyData.RenderedEntityRotationStrategy.Particle)
{
rot = data.Angle;
direction = (rot + eyeRot).GetCardinalDir();
}
var originalColor = sprite.Comp.Color;
_sprite.SetColor(sprite, data.Color);
var originalScale = sprite.Comp.Scale;
_sprite.SetScale(sprite, originalScale * data.Scale);
_sprite.RenderSprite((sprite, sprite.Comp), handle, eyeRot, rot, worldPosition, direction);
_sprite.SetColor(sprite, originalColor);
_sprite.SetScale(sprite, originalScale);
}

}

if (trail.Sprite == null)
{
if (xform.MapID == args.MapId)
{
var start = trail.TrailData[^1].Position;
DrawTrailLine(start, position, trail.Color, trail.Scale, bounds, handle);
}

for (var i = 1; i < trail.TrailData.Count; i++)
{
var data = trail.TrailData[i];
var prevData = trail.TrailData[i - 1];

if (data.MapId == args.MapId && prevData.MapId == args.MapId)
DrawTrailLine(prevData.Position, data.Position, data.Color, data.Scale, bounds, handle);
}

continue;
}

var textureSize = _sprite.Frame0(trail.Sprite).Size;
var pos = -(Vector2) textureSize / 2f / EyeManager.PixelsPerMeter;
foreach (var data in trail.TrailData)
{
if (data.Color.A <= 0.01f || data.Scale <= 0.01f || data.MapId != args.MapId)
continue;

var worldPosition = data.Position;
if (!bounds.Contains(worldPosition))
continue;

var scaleMatrix = Matrix3x2.CreateScale(new Vector2(data.Scale, data.Scale));
var worldMatrix = Matrix3Helpers.CreateTranslation(worldPosition);

var time = _timing.CurTime > data.SpawnTime ? _timing.CurTime - data.SpawnTime : TimeSpan.Zero;
var texture = _sprite.GetFrame(trail.Sprite, time);

handle.SetTransform(Matrix3x2.Multiply(scaleMatrix, worldMatrix));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Трансформация может "протекать" на последующие трейлы.

Если трейл использует рендеринг по спрайту (строка 139), то SetTransform устанавливается внутри цикла, но сбрасывается только в конце (строка 145). Последующие трейлы, использующие другие пути рендеринга (RenderedEntity или линии), могут унаследовать состояние трансформации предыдущего трейла.

Примените этот diff для сброса трансформации перед каждым трейлом:

         var query = _entManager.EntityQueryEnumerator<TrailComponent, TransformComponent>();
         while (query.MoveNext(out _, out var trail, out var xform))
         {
+            handle.SetTransform(Matrix3x2.Identity);
+
             if (trail.TrailData.Count == 0)
                 continue;

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In Content.Client/_White/Wizard/Trail/TrailOverlay.cs around line 139 (and up
through line 145), a transform set via
handle.SetTransform(Matrix3x2.Multiply(scaleMatrix, worldMatrix)) inside the
sprite-rendering branch can leak into subsequently rendered trails that use
other render paths; before each trail iteration (and before any branch that sets
a transform) reset the drawing transform to identity (e.g., call
handle.ResetTransform() or SetTransform(Matrix3x2.Identity)) so each trail
starts with a clean transform, then apply the intended scale/world transform
only for the sprite path and keep the existing final reset at the end.

handle.DrawTexture(texture, pos, data.Angle, data.Color);
}
}

handle.UseShader(null);
handle.SetTransform(Matrix3x2.Identity);
}

private static void DrawTrailLine(
Vector2 start,
Vector2 end,
Color color,
float scale,
Box2 bounds,
DrawingHandleWorld handle
)
{
if (color.A <= 0.01f || scale <= 0.01f || !bounds.Contains(start) || !bounds.Contains(end))
return;
var halfScale = scale * 0.5f;
var direction = end - start;
var angle = direction.ToAngle();
var box = new Box2(start - new Vector2(0f, halfScale), start + new Vector2(direction.Length(), halfScale));
var boxRotated = new Box2Rotated(box, angle, start);
handle.DrawRect(boxRotated, color);
}
}
Loading
Loading