Новые эффекты взрывов (#1410)
Co-authored-by: Vero <73014819+vero5123@users.noreply.github.com> Co-authored-by: Whisper <121047731+QuietlyWhisper@users.noreply.github.com> Co-authored-by: DrSmugleaf <10968691+DrSmugleaf@users.noreply.github.com>
This commit is contained in:
parent
26f5302d6a
commit
6c8050eb1e
40 changed files with 910 additions and 9 deletions
|
|
@ -1,3 +1,5 @@
|
|||
using Content.Client._RMC14.Explosion;
|
||||
using Content.Client._RMC14.Xenonids.Screech;
|
||||
using Content.Client._Sunrise.Entry;
|
||||
using Content.Client._Sunrise.ServersHub;
|
||||
using Content.Client.Administration.Managers;
|
||||
|
|
@ -174,6 +176,10 @@ namespace Content.Client.Entry
|
|||
_parallaxManager.LoadDefaultParallax();
|
||||
|
||||
_overlayManager.AddOverlay(new SingularityOverlay());
|
||||
// Sunrise edit start
|
||||
_overlayManager.AddOverlay(new RMCExplosionShockWaveOverlay());
|
||||
_overlayManager.AddOverlay(new RMCXenoScreechShockWaveOverlay());
|
||||
// Sunrise edit end
|
||||
_overlayManager.AddOverlay(new RadiationPulseOverlay());
|
||||
_chatManager.Initialize();
|
||||
_clientPreferencesManager.Initialize();
|
||||
|
|
|
|||
101
Content.Client/_RMC14/Explosion/RMCExplosionShockWaveOverlay.cs
Normal file
101
Content.Client/_RMC14/Explosion/RMCExplosionShockWaveOverlay.cs
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
using System.Numerics;
|
||||
using Content.Shared._RMC14.Explosion.Components;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client._RMC14.Explosion;
|
||||
|
||||
public sealed class RMCExplosionShockWaveOverlay : Overlay, IEntityEventSubscriber
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
|
||||
private SharedTransformSystem? _xformSystem;
|
||||
|
||||
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
||||
public override bool RequestScreenTexture => true;
|
||||
|
||||
private readonly ShaderInstance _shader;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum number of distortions that can be shown on screen at a time.
|
||||
/// </summary>
|
||||
public const int MaxCount = 10;
|
||||
|
||||
public RMCExplosionShockWaveOverlay()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
_shader = _prototypeManager.Index<ShaderPrototype>("RMCShockWave").Instance().Duplicate();
|
||||
}
|
||||
|
||||
private readonly Vector2[] _positions = new Vector2[MaxCount];
|
||||
private readonly float[] _falloffPower = new float[MaxCount];
|
||||
private readonly float[] _sharpness = new float[MaxCount];
|
||||
private readonly float[] _width = new float[MaxCount];
|
||||
private readonly float[] _times = new float[MaxCount];
|
||||
private int _count;
|
||||
|
||||
private readonly TimeSpan _timeCompensation = TimeSpan.FromSeconds(0.2f);
|
||||
|
||||
protected override bool BeforeDraw(in OverlayDrawArgs args)
|
||||
{
|
||||
if (args.Viewport.Eye == null || _xformSystem is null && !_entMan.TrySystem(out _xformSystem))
|
||||
return false;
|
||||
|
||||
var query = _entMan.EntityQueryEnumerator<RMCExplosionShockWaveComponent, TransformComponent>();
|
||||
|
||||
_count = 0;
|
||||
|
||||
while (query.MoveNext(out var uid, out var distortion, out var xform))
|
||||
{
|
||||
if (xform.MapID != args.MapId)
|
||||
continue;
|
||||
|
||||
var mapPos = _xformSystem.GetWorldPosition(uid);
|
||||
|
||||
var tempCoords = args.Viewport.WorldToLocal(mapPos);
|
||||
|
||||
// normalized coords, 0 - 1 plane. This is pure hell, we subtract 1 because fragment calculates from the bottom and local goes from the top of the viewport
|
||||
tempCoords.Y = 1 - (tempCoords.Y / args.Viewport.Size.Y);
|
||||
tempCoords.X /= args.Viewport.Size.X;
|
||||
|
||||
var currentTime = (float)(_timing.CurTime - distortion.CreationTime - _timeCompensation).TotalSeconds;
|
||||
currentTime = Math.Clamp(currentTime, 0.1f, float.MaxValue);
|
||||
|
||||
_positions[_count] = tempCoords;
|
||||
_falloffPower[_count] = distortion.FalloffPower ?? 20f; // Sunrise edit - фолбек
|
||||
_sharpness[_count] = distortion.Sharpness;
|
||||
_width[_count] = distortion.Width ?? 0.8f;
|
||||
_times[_count] = currentTime;
|
||||
_count++;
|
||||
|
||||
if (_count == MaxCount)
|
||||
break;
|
||||
}
|
||||
|
||||
return _count > 0;
|
||||
}
|
||||
|
||||
protected override void Draw(in OverlayDrawArgs args)
|
||||
{
|
||||
if (ScreenTexture == null || args.Viewport.Eye == null)
|
||||
return;
|
||||
|
||||
_shader?.SetParameter("renderScale", args.Viewport.RenderScale * args.Viewport.Eye.Scale);
|
||||
_shader?.SetParameter("count", _count);
|
||||
_shader?.SetParameter("position", _positions);
|
||||
_shader?.SetParameter("falloffPower", _falloffPower);
|
||||
_shader?.SetParameter("sharpness", _sharpness);
|
||||
_shader?.SetParameter("width", _width);
|
||||
_shader?.SetParameter("time", _times);
|
||||
_shader?.SetParameter("SCREEN_TEXTURE", ScreenTexture);
|
||||
|
||||
var worldHandle = args.WorldHandle;
|
||||
worldHandle.UseShader(_shader);
|
||||
worldHandle.DrawRect(args.WorldBounds, Color.White);
|
||||
worldHandle.UseShader(null);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
using System.Numerics;
|
||||
using Content.Shared._RMC14.Xenonids.Screech;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client._RMC14.Xenonids.Screech;
|
||||
|
||||
public sealed class RMCXenoScreechShockWaveOverlay : Overlay, IEntityEventSubscriber
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
|
||||
private SharedTransformSystem? _xformSystem;
|
||||
|
||||
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
||||
public override bool RequestScreenTexture => true;
|
||||
|
||||
private readonly ShaderInstance _shader;
|
||||
|
||||
public RMCXenoScreechShockWaveOverlay()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
_shader = _prototypeManager.Index<ShaderPrototype>("RMCXenoScreechShockWave").Instance().Duplicate();
|
||||
}
|
||||
|
||||
private Vector2 _position;
|
||||
private float _waveStrength;
|
||||
private float _waveSpeed;
|
||||
private float _downScale;
|
||||
protected override bool BeforeDraw(in OverlayDrawArgs args)
|
||||
{
|
||||
if (args.Viewport.Eye == null || _xformSystem is null && !_entMan.TrySystem(out _xformSystem))
|
||||
return false;
|
||||
|
||||
var query = _entMan.EntityQueryEnumerator<RMCXenoScreechShockWaveComponent, TransformComponent>();
|
||||
|
||||
if (query.MoveNext(out var uid, out var distortion, out var xform))
|
||||
{
|
||||
if (xform.MapID != args.MapId)
|
||||
return false;
|
||||
|
||||
var mapPos = _xformSystem.GetWorldPosition(uid);
|
||||
var tempCoords = args.Viewport.WorldToLocal(mapPos);
|
||||
|
||||
// normalized coords, 0 - 1 plane. This is pure hell, we subtract 1 because fragment calculates from the bottom and local goes from the top of the viewport
|
||||
tempCoords.Y = 1 - (tempCoords.Y / args.Viewport.Size.Y);
|
||||
tempCoords.X /= args.Viewport.Size.X;
|
||||
|
||||
_position = tempCoords;
|
||||
_waveStrength = distortion.WaveStrength;
|
||||
_waveSpeed = distortion.WaveSpeed;
|
||||
_downScale = distortion.DownScale;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override void Draw(in OverlayDrawArgs args)
|
||||
{
|
||||
if (ScreenTexture == null || args.Viewport.Eye == null)
|
||||
return;
|
||||
|
||||
_shader?.SetParameter("position", _position);
|
||||
_shader?.SetParameter("waveSpeed", _waveSpeed);
|
||||
_shader?.SetParameter("downScale", _downScale);
|
||||
_shader?.SetParameter("waveStrength", _waveStrength);
|
||||
_shader?.SetParameter("SCREEN_TEXTURE", ScreenTexture);
|
||||
|
||||
var worldHandle = args.WorldHandle;
|
||||
worldHandle.UseShader(_shader);
|
||||
worldHandle.DrawRect(args.WorldBounds, Color.White);
|
||||
worldHandle.UseShader(null);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
using Content.Shared._RMC14.Explosion.Components;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client._RMC14._Sunrise.Explosion;
|
||||
|
||||
public sealed class ClientExplosionShockWaveSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<RMCExplosionShockWaveComponent, ComponentInit>(OnInit);
|
||||
}
|
||||
|
||||
private void OnInit(Entity<RMCExplosionShockWaveComponent> ent, ref ComponentInit args)
|
||||
{
|
||||
ent.Comp.CreationTime = _timing.CurTime;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
using System.Numerics;
|
||||
using Content.Shared._RMC14.Explosion;
|
||||
using Robust.Client.Animations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Animations;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Client._RMC14._Sunrise.Explosion;
|
||||
|
||||
// Омг это же партикл систем за 1$
|
||||
public sealed class RMCExplosionSystem : SharedRMCExplosionSystem
|
||||
{
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
[Dependency] private readonly AnimationPlayerSystem _player = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
|
||||
private const string SmokeTrack = "smoke-animation";
|
||||
private const string ExplosionTrack = "explosion-animation";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ExplosionSmokeEffectComponent, ComponentStartup>(OnSmokeStartup);
|
||||
SubscribeLocalEvent<ExplosionEffectComponent, ComponentStartup>(OnExplosionStartup);
|
||||
}
|
||||
|
||||
private void OnSmokeStartup(Entity<ExplosionSmokeEffectComponent> ent, ref ComponentStartup args)
|
||||
{
|
||||
if (!TryComp<SpriteComponent>(ent, out var sprite))
|
||||
return;
|
||||
|
||||
var targetX = 2f + _random.NextFloat(-ExplosionSmokeEffectComponent.Variation, ExplosionSmokeEffectComponent.Variation);
|
||||
var targetY = 2f + _random.NextFloat(-ExplosionSmokeEffectComponent.Variation, ExplosionSmokeEffectComponent.Variation);
|
||||
|
||||
var animation = new Animation()
|
||||
{
|
||||
Length = TimeSpan.FromSeconds(ent.Comp.LifeTime),
|
||||
AnimationTracks =
|
||||
{
|
||||
new AnimationTrackComponentProperty()
|
||||
{
|
||||
Property = nameof(SpriteComponent.Offset),
|
||||
ComponentType = typeof(SpriteComponent),
|
||||
InterpolationMode = AnimationInterpolationMode.Linear,
|
||||
KeyFrames =
|
||||
{
|
||||
new AnimationTrackProperty.KeyFrame(sprite.Offset, 0f),
|
||||
new AnimationTrackProperty.KeyFrame(new Vector2(targetX, targetY), ent.Comp.LifeTime),
|
||||
},
|
||||
},
|
||||
new AnimationTrackComponentProperty()
|
||||
{
|
||||
Property = nameof(SpriteComponent.Color),
|
||||
ComponentType = typeof(SpriteComponent),
|
||||
InterpolationMode = AnimationInterpolationMode.Linear,
|
||||
KeyFrames =
|
||||
{
|
||||
new AnimationTrackProperty.KeyFrame(sprite.Color, 0f),
|
||||
new AnimationTrackProperty.KeyFrame(GetTransparentColor(sprite.Color), ent.Comp.LifeTime),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
_player.Play(ent, animation, SmokeTrack);
|
||||
}
|
||||
|
||||
private void OnExplosionStartup(Entity<ExplosionEffectComponent> ent, ref ComponentStartup args)
|
||||
{
|
||||
if (!TryComp<SpriteComponent>(ent, out var sprite))
|
||||
return;
|
||||
|
||||
sprite.Scale = new Vector2(ent.Comp.SizeModifier);
|
||||
_sprite.SetAutoAnimateSync(sprite, ent.Comp.LifeTime);
|
||||
}
|
||||
|
||||
private static Color GetTransparentColor(Color color)
|
||||
{
|
||||
return new Color(color.R, color.G, color.B, 0f);
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,8 @@ using Content.Shared.Stealth.Components;
|
|||
using Content.Shared.Damage.Components;
|
||||
using Content.Server.Radio.Components;
|
||||
using Content.Shared._Sunrise.CollectiveMind;
|
||||
using Content.Shared._RMC14.Xenonids.Screech;
|
||||
using Content.Shared.Coordinates;
|
||||
|
||||
namespace Content.Server.Changeling;
|
||||
|
||||
|
|
@ -263,6 +265,10 @@ public sealed partial class ChangelingSystem : EntitySystem
|
|||
|
||||
_popup.PopupEntity(Loc.GetString("changeling-stasis-exit"), uid, uid);
|
||||
|
||||
// Sunrise edit start
|
||||
StartScreech(uid);
|
||||
// Sunrise edit end
|
||||
|
||||
comp.IsInStasis = false;
|
||||
|
||||
args.Handled = true;
|
||||
|
|
@ -637,4 +643,17 @@ public sealed partial class ChangelingSystem : EntitySystem
|
|||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// Sunrise edit start
|
||||
private void StartScreech(EntityUid uid, XenoScreechComponent? component = null, bool playSound = true)
|
||||
{
|
||||
if (!Resolve(uid, ref component))
|
||||
return;
|
||||
|
||||
if (playSound)
|
||||
_audio.PlayPvs(component.Sound, uid);
|
||||
|
||||
SpawnAttachedTo(component.Effect, uid.ToCoordinates());
|
||||
}
|
||||
// Sunrise edit end
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ using Content.Shared.Mobs.Components;
|
|||
using Content.Server.Stunnable;
|
||||
using Content.Shared.Jittering;
|
||||
using System.Linq;
|
||||
using Content.Shared._RMC14.Xenonids.Screech;
|
||||
using Content.Shared.Forensics.Components;
|
||||
using Content.Shared.Radio;
|
||||
|
||||
|
|
@ -266,6 +267,10 @@ public sealed partial class ChangelingSystem : EntitySystem
|
|||
{
|
||||
_audio.PlayPvs(comp.ShriekSound, uid);
|
||||
|
||||
// Sunrise edit start
|
||||
StartScreech(uid, playSound: false);
|
||||
// Sunrise edit end
|
||||
|
||||
var center = Transform(uid).MapPosition;
|
||||
var gamers = Filter.Empty();
|
||||
gamers.AddInRange(center, comp.ShriekPower, _player, EntityManager);
|
||||
|
|
@ -607,6 +612,10 @@ public sealed partial class ChangelingSystem : EntitySystem
|
|||
RemComp<ThirstComponent>(uid);
|
||||
EnsureComp<ZombieImmuneComponent>(uid);
|
||||
|
||||
// Sunrise edit start
|
||||
EnsureComp<XenoScreechComponent>(uid);
|
||||
// Sunrise edit end
|
||||
|
||||
// add actions
|
||||
foreach (var actionId in comp.BaseChangelingActions)
|
||||
_actions.AddAction(uid, actionId);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using Content.Shared.Explosion;
|
|||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
using System.Text.Json.Serialization;
|
||||
using Content.Shared._Sunrise.Explosion;
|
||||
|
||||
namespace Content.Server.EntityEffects.Effects;
|
||||
|
||||
|
|
@ -45,7 +46,7 @@ public sealed partial class ExplosionReactionEffect : EntityEffect
|
|||
/// </summary>
|
||||
[DataField]
|
||||
public float IntensityPerUnit = 1;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Factor used to scale the explosion intensity when calculating tile break chances. Allows for stronger
|
||||
/// explosives that don't space tiles, without having to create a new explosion-type prototype.
|
||||
|
|
@ -68,6 +69,11 @@ public sealed partial class ExplosionReactionEffect : EntityEffect
|
|||
intensity = MathF.Min((float) reagentArgs.Quantity * IntensityPerUnit, MaxTotalIntensity);
|
||||
}
|
||||
|
||||
// Sunrise edit start
|
||||
args.EntityManager.System<SharedSunriseExplosionSystem>()
|
||||
.TryAddExplosionEffect(args.TargetEntity, ExplosionType);
|
||||
// Sunrise edit end
|
||||
|
||||
args.EntityManager.System<ExplosionSystem>()
|
||||
.QueueExplosion(
|
||||
args.TargetEntity,
|
||||
|
|
|
|||
|
|
@ -37,9 +37,15 @@ public sealed partial class ExplosionSystem
|
|||
/// <summary>
|
||||
/// Constructor for the shared <see cref="ExplosionEvent"/> using the server-exclusive explosion classes.
|
||||
/// </summary>
|
||||
private EntityUid CreateExplosionVisualEntity(MapCoordinates epicenter, string prototype, Matrix3x2 spaceMatrix, ExplosionSpaceTileFlood? spaceData, IEnumerable<ExplosionGridTileFlood> gridData, List<float> iterationIntensity)
|
||||
private EntityUid CreateExplosionVisualEntity(MapCoordinates epicenter, ExplosionPrototype prototype, Matrix3x2 spaceMatrix, ExplosionSpaceTileFlood? spaceData, IEnumerable<ExplosionGridTileFlood> gridData, List<float> iterationIntensity)
|
||||
{
|
||||
var explosionEntity = Spawn(null, MapCoordinates.Nullspace);
|
||||
|
||||
// Sunrise added start
|
||||
if (prototype.EffectType != ExplosionEffectType.Standard)
|
||||
return explosionEntity;
|
||||
// Sunrise added end
|
||||
|
||||
var comp = AddComp<ExplosionVisualsComponent>(explosionEntity);
|
||||
|
||||
foreach (var grid in gridData)
|
||||
|
|
@ -49,7 +55,7 @@ public sealed partial class ExplosionSystem
|
|||
|
||||
comp.SpaceTiles = spaceData?.TileLists;
|
||||
comp.Epicenter = epicenter;
|
||||
comp.ExplosionType = prototype;
|
||||
comp.ExplosionType = prototype.ID; // Sunrise edit
|
||||
comp.Intensity = iterationIntensity;
|
||||
comp.SpaceMatrix = spaceMatrix;
|
||||
comp.SpaceTileSize = spaceData?.TileSize ?? DefaultTileSize;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using Content.Server.Atmos.Components;
|
|||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.NodeContainer.EntitySystems;
|
||||
using Content.Server.NPC.Pathfinding;
|
||||
using Content.Shared._RMC14.Explosion;
|
||||
using Content.Shared.Camera;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Damage;
|
||||
|
|
@ -319,6 +320,14 @@ public sealed partial class ExplosionSystem : SharedExplosionSystem
|
|||
};
|
||||
_explosionQueue.Enqueue(boom);
|
||||
_queuedExplosions.Add(boom);
|
||||
|
||||
// Sunrise added start
|
||||
if (!cause.HasValue)
|
||||
return;
|
||||
|
||||
var ev = new CMExplosiveTriggeredEvent();
|
||||
RaiseLocalEvent(cause.Value, ref ev);
|
||||
// Sunrise added end
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -339,7 +348,8 @@ public sealed partial class ExplosionSystem : SharedExplosionSystem
|
|||
|
||||
var (area, iterationIntensity, spaceData, gridData, spaceMatrix) = results.Value;
|
||||
|
||||
var visualEnt = CreateExplosionVisualEntity(pos, queued.Proto.ID, spaceMatrix, spaceData, gridData.Values, iterationIntensity);
|
||||
// Sunrise edit - queued.Proto.ID -> queued.Proto
|
||||
var visualEnt = CreateExplosionVisualEntity(pos, queued.Proto, spaceMatrix, spaceData, gridData.Values, iterationIntensity);
|
||||
|
||||
// camera shake
|
||||
CameraShake(iterationIntensity.Count * 4f, pos, queued.TotalIntensity);
|
||||
|
|
|
|||
8
Content.Server/_Sunrise/Explosions/RMCExplosionSystem.cs
Normal file
8
Content.Server/_Sunrise/Explosions/RMCExplosionSystem.cs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
using Content.Shared._RMC14.Explosion;
|
||||
|
||||
namespace Content.Server._Sunrise.Explosions;
|
||||
|
||||
public sealed class RMCExplosionSystem : SharedRMCExplosionSystem
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
using Content.Shared.Damage;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Explosion;
|
||||
|
|
@ -110,6 +111,11 @@ public sealed partial class ExplosionPrototype : IPrototype
|
|||
[DataField("fireStates")]
|
||||
public int FireStates = 3;
|
||||
|
||||
// Sunrise added start
|
||||
[DataField]
|
||||
public ExplosionEffectType EffectType = ExplosionEffectType.Fancy;
|
||||
// Sunrise added end
|
||||
|
||||
/// <summary>
|
||||
/// Basic function for linear interpolation of the _tileBreakChance and _tileBreakIntensity arrays
|
||||
/// </summary>
|
||||
|
|
@ -133,3 +139,11 @@ public sealed partial class ExplosionPrototype : IPrototype
|
|||
return _tileBreakChance[i - 1] + slope * (intensity - _tileBreakIntensity[i - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum ExplosionEffectType : byte
|
||||
{
|
||||
Standard,
|
||||
Fancy,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -193,9 +193,9 @@ public abstract partial class SharedProjectileSystem : EntitySystem
|
|||
}
|
||||
}
|
||||
|
||||
public void SetShooter(EntityUid id, ProjectileComponent component, EntityUid shooterId)
|
||||
public void SetShooter(EntityUid id, ProjectileComponent component, EntityUid? shooterId = null)
|
||||
{
|
||||
if (component.Shooter == shooterId)
|
||||
if (component.Shooter == shooterId || shooterId == null)
|
||||
return;
|
||||
|
||||
component.Shooter = shooterId;
|
||||
|
|
|
|||
|
|
@ -484,7 +484,7 @@ public abstract partial class SharedGunSystem : EntitySystem
|
|||
Physics.SetLinearVelocity(uid, finalLinear, body: physics);
|
||||
|
||||
var projectile = EnsureComp<ProjectileComponent>(uid);
|
||||
Projectiles.SetShooter(uid, projectile, user ?? gunUid);
|
||||
Projectiles.SetShooter(uid, projectile, user);
|
||||
projectile.Weapon = gunUid;
|
||||
|
||||
// Sunrise-Start
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._RMC14.Explosion;
|
||||
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
[Access(typeof(SharedRMCExplosionSystem))]
|
||||
public sealed partial class CMExplosionEffectComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public EntProtoId? Explosion = "CMExplosionEffectGrenade";
|
||||
|
||||
[DataField]
|
||||
public EntProtoId? ShockWave = "RMCExplosionEffectGrenadeShockWave";
|
||||
|
||||
// Sunrise added
|
||||
[DataField]
|
||||
public EntProtoId? Smoke = "ExplosionEffectSmoke";
|
||||
// Sunrise added
|
||||
}
|
||||
|
||||
// Sunrise added start
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class ExplosionSmokeEffectComponent : Component
|
||||
{
|
||||
public const float AnimationDuration = 2.5f;
|
||||
public const float Variation = 1f;
|
||||
|
||||
[DataField, AutoNetworkedField]
|
||||
public float LifeTime = AnimationDuration;
|
||||
}
|
||||
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class ExplosionEffectComponent : Component
|
||||
{
|
||||
public const float AnimationDuration = 2.5f;
|
||||
|
||||
[DataField, AutoNetworkedField]
|
||||
public float LifeTime = AnimationDuration;
|
||||
|
||||
[DataField, AutoNetworkedField]
|
||||
public float SizeModifier = 2f;
|
||||
}
|
||||
// Sunrise added end
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared._RMC14.Explosion.Components
|
||||
{
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
[AutoGenerateComponentState]
|
||||
public sealed partial class RMCExplosionShockWaveComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The rate at which the wave fades, lower values means it's active for longer.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public float? FalloffPower = 20f;
|
||||
|
||||
/// <summary>
|
||||
/// How sharp the wave distortion is. Higher values make the wave more pronounced.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public float Sharpness = 5.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Width of the wave.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public float? Width = 0.8f;
|
||||
|
||||
[DataField]
|
||||
public TimeSpan CreationTime;
|
||||
}
|
||||
}
|
||||
122
Content.Shared/_RMC14/Explosion/SharedRMCExplosionSystem.cs
Normal file
122
Content.Shared/_RMC14/Explosion/SharedRMCExplosionSystem.cs
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
using Content.Shared._RMC14.Explosion.Components;
|
||||
using Content.Shared._Sunrise.Helpers;
|
||||
using Content.Shared.Explosion.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Spawners;
|
||||
|
||||
namespace Content.Shared._RMC14.Explosion;
|
||||
|
||||
public abstract class SharedRMCExplosionSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
|
||||
private const float MinSmokeCountPer100 = 12f;
|
||||
private const float MaxSmokeCountPer100 = 17f;
|
||||
|
||||
private const float SmokeSpawnRadiusPer100 = 2f;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<CMExplosionEffectComponent, CMExplosiveTriggeredEvent>(OnExplosionEffectTriggered);
|
||||
}
|
||||
|
||||
private void OnExplosionEffectTriggered(Entity<CMExplosionEffectComponent> ent, ref CMExplosiveTriggeredEvent args)
|
||||
{
|
||||
DoEffect(ent);
|
||||
}
|
||||
|
||||
// Sunrise edit start
|
||||
public void DoEffect(Entity<CMExplosionEffectComponent> ent)
|
||||
{
|
||||
if (!TryComp<ExplosiveComponent>(ent, out var explosionComponent))
|
||||
return;
|
||||
|
||||
if (ent.Comp.ShockWave is { } shockwave)
|
||||
{
|
||||
var wave = SpawnNextToOrDrop(shockwave, ent);
|
||||
ModifyShockwave(wave, explosionComponent);
|
||||
}
|
||||
|
||||
if (ent.Comp.Explosion is { } explosion)
|
||||
{
|
||||
var explosionEntity = SpawnNextToOrDrop(explosion, ent);
|
||||
CreateFancyExplosionEffect(explosionEntity, explosionComponent);
|
||||
}
|
||||
|
||||
if (ent.Comp.Smoke is { } smoke)
|
||||
CreateFancySmoke(ent, explosionComponent, smoke);
|
||||
}
|
||||
|
||||
private void ModifyShockwave(EntityUid wave, ExplosiveComponent explosionComponent)
|
||||
{
|
||||
// Дальше идут просто числа, которые я придумал особо не думая, мб нужно подумать
|
||||
// Но идея в том, чтобы чем сильнее взрыв, тем сильнее эффект и наоборот
|
||||
// TODO: Реализовать радиус действия волны и убрать стандартные значения в компоненте
|
||||
|
||||
if (TryComp<RMCExplosionShockWaveComponent>(wave, out var waveComponent))
|
||||
{
|
||||
waveComponent.FalloffPower ??= explosionComponent.TotalIntensity / 4f;
|
||||
waveComponent.Width ??= Math.Clamp(explosionComponent.TotalIntensity / 200f, 0.1f, 0.5f);
|
||||
|
||||
Dirty(wave, waveComponent);
|
||||
}
|
||||
|
||||
if (TryComp<TimedDespawnComponent>(wave, out var timedDespawnComponent))
|
||||
timedDespawnComponent.Lifetime = Math.Clamp(explosionComponent.TotalIntensity / 50f, 0.1f, 0.8f);
|
||||
}
|
||||
|
||||
private void CreateFancyExplosionEffect(EntityUid explosionEntity, ExplosiveComponent explosionComponent)
|
||||
{
|
||||
if (!TryComp<TimedDespawnComponent>(explosionEntity, out var timedDespawnComponent))
|
||||
return;
|
||||
|
||||
if (!TryComp<ExplosionEffectComponent>(explosionEntity, out var explosionEffectComponent))
|
||||
return;
|
||||
|
||||
var sizeModifier = Math.Clamp(explosionComponent.TotalIntensity / 50f, 1f, 12f);
|
||||
explosionEffectComponent.SizeModifier = sizeModifier;
|
||||
explosionEffectComponent.LifeTime = timedDespawnComponent.Lifetime;
|
||||
|
||||
Dirty(explosionEntity, explosionEffectComponent);
|
||||
}
|
||||
|
||||
private void CreateFancySmoke(Entity<CMExplosionEffectComponent> ent, ExplosiveComponent explosionComponent, EntProtoId smokeId)
|
||||
{
|
||||
var modifier = explosionComponent.TotalIntensity / 100f;
|
||||
|
||||
var smokeCount = _random.NextFloat(MinSmokeCountPer100 * modifier, MaxSmokeCountPer100 * modifier);
|
||||
var coords = Transform(ent).Coordinates;
|
||||
var modifiedRadius = Math.Clamp(SmokeSpawnRadiusPer100 * modifier, 2f, 10f);
|
||||
|
||||
for (var i = 0; i < smokeCount; i++)
|
||||
{
|
||||
var smoke = Spawn(smokeId, coords.GetRandomInRadius(modifiedRadius));
|
||||
|
||||
if (!TryComp<TimedDespawnComponent>(smoke, out var timedDespawnComponent))
|
||||
continue;
|
||||
|
||||
if (!TryComp<ExplosionSmokeEffectComponent>(smoke, out var explosionSmokeEffectComponent))
|
||||
continue;
|
||||
|
||||
timedDespawnComponent.Lifetime = ExplosionSmokeEffectComponent.AnimationDuration + _random.NextFloat(-ExplosionSmokeEffectComponent.Variation, ExplosionSmokeEffectComponent.Variation);
|
||||
|
||||
// Это нужно, чтобы анимация на клиенте знала, когда мы решили заканчиваться
|
||||
explosionSmokeEffectComponent.LifeTime = timedDespawnComponent.Lifetime;
|
||||
Dirty(smoke, explosionSmokeEffectComponent);
|
||||
}
|
||||
}
|
||||
// Sunrise edit end
|
||||
|
||||
public void TryDoEffect(Entity<CMExplosionEffectComponent?> ent)
|
||||
{
|
||||
if (!Resolve(ent, ref ent.Comp, false))
|
||||
return;
|
||||
|
||||
DoEffect((ent, ent.Comp));
|
||||
}
|
||||
}
|
||||
|
||||
[ByRefEvent]
|
||||
public readonly record struct CMExplosiveTriggeredEvent;
|
||||
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared._RMC14.Xenonids.Screech;
|
||||
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
[AutoGenerateComponentState]
|
||||
public sealed partial class RMCXenoScreechShockWaveComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The speed of each individual wave from the center axis.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public float WaveSpeed = 15.3f;
|
||||
|
||||
/// <summary>
|
||||
/// The size of each wave in its width and distortion effect
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public float WaveStrength = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The scale of the effect, lower number means a larger total area while smaller numbers downscale it and reduce the effected area.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public float DownScale = 1f;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._RMC14.Xenonids.Screech;
|
||||
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class XenoScreechComponent : Component
|
||||
{
|
||||
[DataField, AutoNetworkedField]
|
||||
public EntProtoId Effect = "CMEffectScreechShort";
|
||||
|
||||
[DataField, AutoNetworkedField]
|
||||
public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/_RMC14/Xeno/alien_queen_screech.ogg", AudioParams.Default.WithVolume(-7).WithPlayOffset(1.4f));
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
using Content.Shared._RMC14.Explosion;
|
||||
using Content.Shared.Explosion;
|
||||
using Content.Shared.Explosion.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._Sunrise.Explosion;
|
||||
|
||||
public sealed class SharedSunriseExplosionSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ExplosiveComponent, ComponentInit>(OnInit);
|
||||
}
|
||||
|
||||
private void OnInit(Entity<ExplosiveComponent> ent, ref ComponentInit args)
|
||||
{
|
||||
TryAddExplosionEffect(ent, ent.Comp.ExplosionType);
|
||||
}
|
||||
|
||||
public bool TryAddExplosionEffect(EntityUid uid, string explosionType)
|
||||
{
|
||||
if (!_prototype.TryIndex<ExplosionPrototype>(explosionType, out var explosionPrototype))
|
||||
return false;
|
||||
|
||||
if (explosionPrototype.EffectType != ExplosionEffectType.Fancy)
|
||||
return false;
|
||||
|
||||
EnsureComp<CMExplosionEffectComponent>(uid);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
39
Content.Shared/_Sunrise/Helpers/CoordinatesHelpers.cs
Normal file
39
Content.Shared/_Sunrise/Helpers/CoordinatesHelpers.cs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
using System.Numerics;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Shared._Sunrise.Helpers;
|
||||
|
||||
public static class EntityCoordinatesExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Генерирует случайные координаты в заданном радиусе от исходных координат.
|
||||
/// </summary>
|
||||
/// <param name="origin">Исходные координаты.</param>
|
||||
/// <param name="radius">Радиус для генерации случайной точки.</param>
|
||||
/// <param name="rand">Опциональный экземпляр Random для контроля генерации.</param>
|
||||
/// <returns>Новые координаты в пределах радиуса.</returns>
|
||||
public static EntityCoordinates GetRandomInRadius(this EntityCoordinates origin, float radius, IRobustRandom? rand = null)
|
||||
{
|
||||
if (radius < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(radius), "Radius cannot be negative.");
|
||||
|
||||
if (radius == 0)
|
||||
return origin;
|
||||
|
||||
rand ??= IoCManager.Resolve<IRobustRandom>();
|
||||
|
||||
// Генерируем угол и расстояние.
|
||||
var angle = rand.NextDouble() * Math.Tau; // 0..2π
|
||||
var distance = Math.Sqrt(rand.NextDouble()) * radius; // Равномерное распределение
|
||||
|
||||
// Преобразуем в декартовы координаты.
|
||||
var x = (float)(distance * Math.Cos(angle));
|
||||
var y = (float)(distance * Math.Sin(angle));
|
||||
|
||||
// Смещаем относительно исходной позиции.
|
||||
var newPosition = origin.Position + new Vector2(x, y);
|
||||
|
||||
return new EntityCoordinates(origin.EntityId, newPosition);
|
||||
}
|
||||
}
|
||||
BIN
Resources/Audio/_RMC14/Xeno/alien_queen_screech.ogg
Normal file
BIN
Resources/Audio/_RMC14/Xeno/alien_queen_screech.ogg
Normal file
Binary file not shown.
|
|
@ -59,4 +59,4 @@
|
|||
- type: Construction
|
||||
graph: PipeBomb
|
||||
node: cable
|
||||
defaultTarget: pipebomb
|
||||
defaultTarget: pipebomb
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@
|
|||
enabled: false
|
||||
- type: NukeLabel
|
||||
- type: Nuke
|
||||
explosionType: Default
|
||||
explosionType: DefaultStandardEffect # Sunrise edit
|
||||
maxIntensity: 100
|
||||
intensitySlope: 5
|
||||
totalIntensity: 5000000
|
||||
|
|
|
|||
16
Resources/Prototypes/_RMC14/Effects/explosive.yml
Normal file
16
Resources/Prototypes/_RMC14/Effects/explosive.yml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
- type: entity
|
||||
id: CMExplosionEffectGrenade
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _RMC14/Effects/grenade_explosion.rsi
|
||||
state: grenade
|
||||
- type: ExplosionEffect # Sunrise
|
||||
- type: TimedDespawn
|
||||
lifetime: 0.6
|
||||
|
||||
- type: entity
|
||||
id: RMCExplosionEffectGrenadeShockWave
|
||||
components:
|
||||
- type: TimedDespawn
|
||||
lifetime: 0.5
|
||||
- type: RMCExplosionShockWave
|
||||
35
Resources/Prototypes/_RMC14/Effects/screech.yml
Normal file
35
Resources/Prototypes/_RMC14/Effects/screech.yml
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
- type: entity
|
||||
# Just fades out with no movement animation
|
||||
id: CMEffectScreech
|
||||
categories: [ HideSpawnMenu ]
|
||||
components:
|
||||
- type: TimedDespawn
|
||||
lifetime: 3.2
|
||||
- type: RMCXenoScreechShockWave
|
||||
- type: Sprite
|
||||
sprite: _RMC14/Effects/xeno_screech.rsi
|
||||
noRot: true
|
||||
state: screech
|
||||
drawdepth: Effects
|
||||
- type: EffectVisuals
|
||||
- type: Tag
|
||||
tags:
|
||||
- HideContextMenu
|
||||
|
||||
- type: entity
|
||||
# Just fades out with no movement animation
|
||||
id: CMEffectScreechShort
|
||||
categories: [ HideSpawnMenu ]
|
||||
components:
|
||||
- type: TimedDespawn
|
||||
lifetime: 1.4
|
||||
- type: RMCXenoScreechShockWave
|
||||
- type: Sprite
|
||||
sprite: _RMC14/Effects/xeno_screech.rsi
|
||||
noRot: true
|
||||
state: screech
|
||||
drawdepth: Effects
|
||||
- type: EffectVisuals
|
||||
- type: Tag
|
||||
tags:
|
||||
- HideContextMenu
|
||||
9
Resources/Prototypes/_RMC14/Shaders/shaders.yml
Normal file
9
Resources/Prototypes/_RMC14/Shaders/shaders.yml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
- type: shader
|
||||
id: RMCShockWave
|
||||
kind: source
|
||||
path: "/Textures/_RMC14/Shaders/shock_wave.swsl"
|
||||
|
||||
- type: shader
|
||||
id: RMCXenoScreechShockWave
|
||||
kind: source
|
||||
path: "/Textures/_RMC14/Shaders/screech_shock_wave.swsl"
|
||||
11
Resources/Prototypes/_Sunrise/Entities/Effects/explosion.yml
Normal file
11
Resources/Prototypes/_Sunrise/Entities/Effects/explosion.yml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
- type: entity
|
||||
id: ExplosionEffectSmoke
|
||||
components:
|
||||
- type: Sprite
|
||||
drawdepth: Effects
|
||||
sprite: _Sunrise/Effects/explosion_smoke.rsi
|
||||
state: smoke
|
||||
shader: unshaded
|
||||
- type: ExplosionSmokeEffect
|
||||
- type: TimedDespawn
|
||||
lifetime: 5
|
||||
14
Resources/Prototypes/_Sunrise/explosion.yml
Normal file
14
Resources/Prototypes/_Sunrise/explosion.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
- type: explosion
|
||||
id: DefaultStandardEffect
|
||||
damagePerIntensity:
|
||||
types:
|
||||
Heat: 5
|
||||
Blunt: 5
|
||||
Piercing: 5
|
||||
tileBreakChance: [0, 0.5, 1]
|
||||
tileBreakIntensity: [0, 10, 30]
|
||||
tileBreakRerollReduction: 20
|
||||
lightColor: Orange
|
||||
texturePath: /Textures/Effects/fire.rsi
|
||||
fireStates: 3
|
||||
effectType: Standard
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 7.7 KiB |
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"version": 1,
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "Taken from cmss13 at https://github.com/cmss13-devs/cmss13/blob/add6123ac6b3263f257e4b233ef5a8fea5d3d317/icons/effects/explosion.dmi",
|
||||
"size": {
|
||||
"x": 48,
|
||||
"y": 48
|
||||
},
|
||||
"states": [
|
||||
{
|
||||
"name": "grenade",
|
||||
"delays": [
|
||||
[
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
26
Resources/Textures/_RMC14/Effects/xeno_screech.rsi/meta.json
Normal file
26
Resources/Textures/_RMC14/Effects/xeno_screech.rsi/meta.json
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"version": 1,
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "Taken from cmss13 at https://github.com/cmss13-devs/cmss13/blob/d5b119380250ea512db2a5319e36592c7f604250/icons/effects/xeno_screech.dmi",
|
||||
"size": {
|
||||
"x": 64,
|
||||
"y": 64
|
||||
},
|
||||
"states": [
|
||||
{
|
||||
"name": "screech",
|
||||
"delays": [
|
||||
[
|
||||
0.2,
|
||||
0.2,
|
||||
0.2,
|
||||
0.2,
|
||||
0.2,
|
||||
0.2,
|
||||
0.2,
|
||||
0.2
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
Resources/Textures/_RMC14/Effects/xeno_screech.rsi/screech.png
Normal file
BIN
Resources/Textures/_RMC14/Effects/xeno_screech.rsi/screech.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
28
Resources/Textures/_RMC14/Shaders/screech_shock_wave.swsl
Normal file
28
Resources/Textures/_RMC14/Shaders/screech_shock_wave.swsl
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
uniform sampler2D SCREEN_TEXTURE;
|
||||
uniform highp float waveStrength;
|
||||
uniform highp vec2 position;
|
||||
uniform highp float waveSpeed;
|
||||
uniform highp float downScale;
|
||||
|
||||
void fragment()
|
||||
{
|
||||
highp vec2 st = UV;
|
||||
highp vec2 WaveCentre = position;
|
||||
highp float ratio = SCREEN_PIXEL_SIZE.y / SCREEN_PIXEL_SIZE.x * 0.5;
|
||||
WaveCentre.y *= ratio;
|
||||
highp float dist = distance(vec2(st.x, st.y * ratio), WaveCentre) * downScale;
|
||||
highp float val = dist;
|
||||
highp float a = 3.0;
|
||||
highp float cosFuns = cos(val * 20.0 - TIME * waveSpeed);
|
||||
highp float powFuns = pow(val * 2.5, a);
|
||||
highp float limtedPowFuns = 0.5 * pow(a / (a + powFuns), 2.0);
|
||||
highp float finalRes = smoothstep(0.0, 1.0, limtedPowFuns * cosFuns) * waveStrength;
|
||||
highp vec3 col = finalRes * vec3(1.0);
|
||||
st = st * 2.0 - 1.0;
|
||||
st *= 1.0 + finalRes * 0.1;
|
||||
st = st * 0.5 + 0.5;
|
||||
highp vec4 texCol = zTextureSpec(SCREEN_TEXTURE, st);
|
||||
texCol += (texCol * finalRes) / (dist * 10.0);
|
||||
|
||||
COLOR = texCol;
|
||||
}
|
||||
40
Resources/Textures/_RMC14/Shaders/shock_wave.swsl
Normal file
40
Resources/Textures/_RMC14/Shaders/shock_wave.swsl
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
uniform sampler2D SCREEN_TEXTURE;
|
||||
uniform highp vec2 renderScale;
|
||||
uniform lowp int count;
|
||||
uniform highp vec2[10] position;
|
||||
uniform highp float[10] sharpness;
|
||||
uniform highp float[10] width;
|
||||
uniform highp float[10] falloffPower;
|
||||
uniform highp float[10] time;
|
||||
|
||||
void fragment() {
|
||||
highp vec2 coord = FRAGCOORD.xy * SCREEN_PIXEL_SIZE.xy;
|
||||
highp float ratio = SCREEN_PIXEL_SIZE.y / SCREEN_PIXEL_SIZE.x * 0.6;
|
||||
|
||||
highp vec2 totalOffset = vec2(0.0);
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
highp vec2 WaveCentre = position[i];
|
||||
|
||||
highp float Dist = distance(
|
||||
vec2(coord.x, coord.y * ratio),
|
||||
vec2(WaveCentre.x, WaveCentre.y * ratio)
|
||||
);
|
||||
|
||||
highp float CurrentTime = time[i];
|
||||
|
||||
if (Dist <= (CurrentTime + 0.1) && Dist >= (CurrentTime - 0.1)) {
|
||||
highp float Diff = Dist - CurrentTime;
|
||||
highp float ScaleDiff = 1.0 - pow(abs(Diff * sharpness[i]), width[i]);
|
||||
highp float DiffTime = Diff * ScaleDiff;
|
||||
highp vec2 DiffTexCoord = normalize(coord - WaveCentre);
|
||||
|
||||
totalOffset += (DiffTexCoord * DiffTime) / (CurrentTime * Dist * falloffPower[i]);
|
||||
}
|
||||
}
|
||||
|
||||
coord += totalOffset;
|
||||
|
||||
highp vec4 Color = texture(SCREEN_TEXTURE, coord);
|
||||
COLOR = Color;
|
||||
}
|
||||
BIN
Resources/Textures/_Sunrise/Effects/explosion_smoke.rsi/dust.png
Normal file
BIN
Resources/Textures/_Sunrise/Effects/explosion_smoke.rsi/dust.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
Resources/Textures/_Sunrise/Effects/explosion_smoke.rsi/fire.png
Normal file
BIN
Resources/Textures/_Sunrise/Effects/explosion_smoke.rsi/fire.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
BIN
Resources/Textures/_Sunrise/Effects/explosion_smoke.rsi/gas.png
Normal file
BIN
Resources/Textures/_Sunrise/Effects/explosion_smoke.rsi/gas.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"version": 1,
|
||||
"license": "CLA",
|
||||
"copyright": "SUNRISE",
|
||||
"size":
|
||||
{
|
||||
"x": 128,
|
||||
"y": 128
|
||||
},
|
||||
"states":
|
||||
[
|
||||
{
|
||||
"name": "smoke"
|
||||
},
|
||||
{
|
||||
"name": "dust"
|
||||
},
|
||||
{
|
||||
"name": "fire"
|
||||
},
|
||||
{
|
||||
"name": "gas"
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Loading…
Add table
Reference in a new issue