* Start adding flashy flash * Change slop Might give a smoother decline * flashy flash * Add flashbang and flash projectiles Bang bang bang pull my flash trigger * Add collision check to area flash * Flash cleanupo * flash.ogg mixed to mono * Adjusted flash curve again * Enhancing flashes with unshaded and lights and shit Still a WIP * Add the other ballistic gun types Re-organised some of the gun stuff so the powercell guns share the shooting code with the ballistic guns. * Re-merging branch with master Also fixed some visualizer bugs * Last cleanup Fixed some crashes Fixed Deckard sprite Fixed Hitscan effects Re-applied master changes Re-factor to using soundsystem Add some more audio effects * Cleanup flashes for merge Can put flashbangs in lockers so you don't get blinded Fix some bugs * Fix shotties Also removed some redundant code * Bulldoze some legacycode brrrrrrrrt * Fix clientignore warnings * Add the other Stunnable types to StunnableProjectile * Some gun refactoring * Removed extra visualizers * All casing ejections use the same code * Speed loaders can have their ammo pulled out * Bolt sound less loud * Stop ThrowController from throwing * Fix speed loader visuals * Update hitscan collision mask and fix typo * Cleanup * Fit hitscan and flashbang collisions * Use the new flags support * Update taser placeholder description * Update protonames per style guide * Add yaml flag support for gun firerates * Cleanup crew * Fix Audio up (components, audio file, + remove global sounds) * Add server-side recoil back-in (forgot that I was testing this client-side) * Add Flag support for fire-rate selectors * Wrong int you dolt * Fix AI conflicts Haha ranged bulldozer go BRR (I'll rewrite it after the other AI systems are done). * Mix bang.ogg from stereo to mono * Make sure serializer's reading for guns Fixes integration test * Change EntitySystem calls to use the static function Also removed the Pumpbarrel commented-out code * Change StunnableProjectile defaults to 0 * Fix taser paralyse Apparently removing defaults means you have to specify the values, whodathunkit * Add slowdown to stunnableprojectiles and fix tasers * Remove FlagsFor from gun components Co-authored-by: Metal Gear Sloth <metalgearsloth@gmail.com> Co-authored-by: Víctor Aguilera Puerto <6766154+Zumorica@users.noreply.github.com>
283 lines
10 KiB
C#
283 lines
10 KiB
C#
using System;
|
|
using Content.Client.Animations;
|
|
using Content.Client.UserInterface.Stylesheets;
|
|
using Content.Client.Utility;
|
|
using Content.Shared.GameObjects;
|
|
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
|
|
using Robust.Client.Animations;
|
|
using Robust.Client.Graphics;
|
|
using Robust.Client.UserInterface;
|
|
using Robust.Client.UserInterface.Controls;
|
|
using Robust.Shared.Animations;
|
|
using Robust.Shared.GameObjects;
|
|
using Robust.Shared.Interfaces.Network;
|
|
using Robust.Shared.Maths;
|
|
using Robust.Shared.Players;
|
|
using Robust.Shared.Serialization;
|
|
using Robust.Shared.ViewVariables;
|
|
|
|
namespace Content.Client.GameObjects.Components.Weapons.Ranged.Barrels
|
|
{
|
|
[RegisterComponent]
|
|
public class ClientMagazineBarrelComponent : Component, IItemStatus
|
|
{
|
|
private static readonly Animation AlarmAnimationSmg = new Animation
|
|
{
|
|
Length = TimeSpan.FromSeconds(1.4),
|
|
AnimationTracks =
|
|
{
|
|
new AnimationTrackControlProperty
|
|
{
|
|
// These timings match the SMG audio file.
|
|
Property = nameof(Label.FontColorOverride),
|
|
InterpolationMode = AnimationInterpolationMode.Previous,
|
|
KeyFrames =
|
|
{
|
|
new AnimationTrackProperty.KeyFrame(Color.Red, 0.1f),
|
|
new AnimationTrackProperty.KeyFrame(null, 0.3f),
|
|
new AnimationTrackProperty.KeyFrame(Color.Red, 0.2f),
|
|
new AnimationTrackProperty.KeyFrame(null, 0.3f),
|
|
new AnimationTrackProperty.KeyFrame(Color.Red, 0.2f),
|
|
new AnimationTrackProperty.KeyFrame(null, 0.3f),
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
private static readonly Animation AlarmAnimationLmg = new Animation
|
|
{
|
|
Length = TimeSpan.FromSeconds(0.75),
|
|
AnimationTracks =
|
|
{
|
|
new AnimationTrackControlProperty
|
|
{
|
|
// These timings match the SMG audio file.
|
|
Property = nameof(Label.FontColorOverride),
|
|
InterpolationMode = AnimationInterpolationMode.Previous,
|
|
KeyFrames =
|
|
{
|
|
new AnimationTrackProperty.KeyFrame(Color.Red, 0.0f),
|
|
new AnimationTrackProperty.KeyFrame(null, 0.15f),
|
|
new AnimationTrackProperty.KeyFrame(Color.Red, 0.15f),
|
|
new AnimationTrackProperty.KeyFrame(null, 0.15f),
|
|
new AnimationTrackProperty.KeyFrame(Color.Red, 0.15f),
|
|
new AnimationTrackProperty.KeyFrame(null, 0.15f),
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
public override string Name => "MagazineBarrel";
|
|
public override uint? NetID => ContentNetIDs.MAGAZINE_BARREL;
|
|
|
|
private StatusControl _statusControl;
|
|
|
|
/// <summary>
|
|
/// True if a bullet is chambered.
|
|
/// </summary>
|
|
[ViewVariables]
|
|
public bool Chambered { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Count of bullets in the magazine.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Null if no magazine is inserted.
|
|
/// </remarks>
|
|
[ViewVariables]
|
|
public (int count, int max)? MagazineCount { get; private set; }
|
|
|
|
[ViewVariables(VVAccess.ReadWrite)] private bool _isLmgAlarmAnimation;
|
|
|
|
public override void ExposeData(ObjectSerializer serializer)
|
|
{
|
|
base.ExposeData(serializer);
|
|
|
|
serializer.DataField(ref _isLmgAlarmAnimation, "lmg_alarm_animation", false);
|
|
}
|
|
|
|
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
|
|
{
|
|
if (!(curState is MagazineBarrelComponentState cast))
|
|
return;
|
|
|
|
Chambered = cast.Chambered;
|
|
MagazineCount = cast.Magazine;
|
|
_statusControl?.Update();
|
|
}
|
|
|
|
public override void HandleNetworkMessage(ComponentMessage message, INetChannel channel, ICommonSession session = null)
|
|
{
|
|
base.HandleNetworkMessage(message, channel, session);
|
|
|
|
switch (message)
|
|
{
|
|
/*
|
|
case BmwComponentAutoEjectedMessage _:
|
|
_statusControl?.PlayAlarmAnimation();
|
|
return;*/
|
|
}
|
|
}
|
|
|
|
public Control MakeControl()
|
|
{
|
|
_statusControl = new StatusControl(this);
|
|
_statusControl.Update();
|
|
return _statusControl;
|
|
}
|
|
|
|
public void DestroyControl(Control control)
|
|
{
|
|
if (_statusControl == control)
|
|
{
|
|
_statusControl = null;
|
|
}
|
|
}
|
|
|
|
private sealed class StatusControl : Control
|
|
{
|
|
private readonly ClientMagazineBarrelComponent _parent;
|
|
private readonly HBoxContainer _bulletsListTop;
|
|
private readonly HBoxContainer _bulletsListBottom;
|
|
private readonly TextureRect _chamberedBullet;
|
|
private readonly Label _noMagazineLabel;
|
|
|
|
public StatusControl(ClientMagazineBarrelComponent parent)
|
|
{
|
|
_parent = parent;
|
|
SizeFlagsHorizontal = SizeFlags.FillExpand;
|
|
SizeFlagsVertical = SizeFlags.ShrinkCenter;
|
|
AddChild(new VBoxContainer
|
|
{
|
|
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
|
SizeFlagsVertical = SizeFlags.ShrinkCenter,
|
|
SeparationOverride = 0,
|
|
Children =
|
|
{
|
|
(_bulletsListTop = new HBoxContainer {SeparationOverride = 0}),
|
|
new HBoxContainer
|
|
{
|
|
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
|
Children =
|
|
{
|
|
new Control
|
|
{
|
|
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
|
Children =
|
|
{
|
|
(_bulletsListBottom = new HBoxContainer
|
|
{
|
|
SizeFlagsVertical = SizeFlags.ShrinkCenter,
|
|
SeparationOverride = 0
|
|
}),
|
|
(_noMagazineLabel = new Label
|
|
{
|
|
Text = "No Magazine!",
|
|
StyleClasses = {StyleNano.StyleClassItemStatus}
|
|
})
|
|
}
|
|
},
|
|
(_chamberedBullet = new TextureRect
|
|
{
|
|
Texture = StaticIoC.ResC.GetTexture("/Textures/UserInterface/status/bullets/chambered.png"),
|
|
SizeFlagsVertical = SizeFlags.ShrinkCenter,
|
|
SizeFlagsHorizontal = SizeFlags.ShrinkEnd | SizeFlags.Fill,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
_chamberedBullet.ModulateSelfOverride =
|
|
_parent.Chambered ? Color.FromHex("#d7df60") : Color.Black;
|
|
|
|
_bulletsListTop.RemoveAllChildren();
|
|
_bulletsListBottom.RemoveAllChildren();
|
|
|
|
if (_parent.MagazineCount == null)
|
|
{
|
|
_noMagazineLabel.Visible = true;
|
|
return;
|
|
}
|
|
|
|
var (count, capacity) = _parent.MagazineCount.Value;
|
|
|
|
_noMagazineLabel.Visible = false;
|
|
|
|
string texturePath;
|
|
if (capacity <= 20)
|
|
{
|
|
texturePath = "/Textures/UserInterface/status/bullets/normal.png";
|
|
}
|
|
else if (capacity <= 30)
|
|
{
|
|
texturePath = "/Textures/UserInterface/status/bullets/small.png";
|
|
}
|
|
else
|
|
{
|
|
texturePath = "/Textures/UserInterface/status/bullets/tiny.png";
|
|
}
|
|
|
|
var texture = StaticIoC.ResC.GetTexture(texturePath);
|
|
|
|
const int tinyMaxRow = 60;
|
|
|
|
if (capacity > tinyMaxRow)
|
|
{
|
|
FillBulletRow(_bulletsListBottom, Math.Min(tinyMaxRow, count), tinyMaxRow, texture);
|
|
FillBulletRow(_bulletsListTop, Math.Max(0, count - tinyMaxRow), capacity - tinyMaxRow, texture);
|
|
}
|
|
else
|
|
{
|
|
FillBulletRow(_bulletsListBottom, count, capacity, texture);
|
|
}
|
|
}
|
|
|
|
private static void FillBulletRow(Control container, int count, int capacity, Texture texture)
|
|
{
|
|
var colorA = Color.FromHex("#b68f0e");
|
|
var colorB = Color.FromHex("#d7df60");
|
|
var colorGoneA = Color.FromHex("#000000");
|
|
var colorGoneB = Color.FromHex("#222222");
|
|
|
|
var altColor = false;
|
|
|
|
for (var i = count; i < capacity; i++)
|
|
{
|
|
container.AddChild(new TextureRect
|
|
{
|
|
Texture = texture,
|
|
ModulateSelfOverride = altColor ? colorGoneA : colorGoneB
|
|
});
|
|
|
|
altColor ^= true;
|
|
}
|
|
|
|
for (var i = 0; i < count; i++)
|
|
{
|
|
container.AddChild(new TextureRect
|
|
{
|
|
Texture = texture,
|
|
ModulateSelfOverride = altColor ? colorA : colorB
|
|
});
|
|
|
|
altColor ^= true;
|
|
}
|
|
}
|
|
|
|
protected override Vector2 CalculateMinimumSize()
|
|
{
|
|
return Vector2.ComponentMax((0, 15), base.CalculateMinimumSize());
|
|
}
|
|
|
|
public void PlayAlarmAnimation()
|
|
{
|
|
var animation = _parent._isLmgAlarmAnimation ? AlarmAnimationLmg : AlarmAnimationSmg;
|
|
_noMagazineLabel.PlayAnimation(animation, "alarm");
|
|
}
|
|
}
|
|
}
|
|
} |