* serv3 in shared pt 1 * beginning of deepclone api * progress in implementing ideepclone & serv3 in content * adds target * its cant hurt you it cant hurt you * more changes to content.server * adds dataclasses * almost there * renamed & edited entry * finishes refactoring content to use serv3 * gasmixture runtimes, next: reagentunit * fucin hell that was an annoying one * adds flags * fixes some yaml errors * removes comment * fixes generic components for now * removes todo actually clones values my god paul fixes bug involving resolving custom data classes from other proj renames dataclass fixes spritecomp adds WithFormat.Constants support * adds deepclone to ResistanceSet * adds a bunch of deepclone implementations adds a deepclone analyzer (TODO) adds a deep clone fallback for classes & structs * fixes a bunch of runtimes * adds deepclone to entityuid * adds generator to sln * gets rid of warnings * fixes * argh * componentdata refactors * more deepclone impl * heck me i reworked all of content deepclone * renames custom dataclasstarget * misc * reworks prototypes * deepclone nuke * renamed customdataclass attribute * fixes everything * misc fixed * the killcommit * getting there * changed yamlfieldattribute namespace * adds back iselfserialize * renames everything to data(field/definition) * ouch * Fix most errors on content * Fix more errors in content * Fix some components * work on tests * fixes some customdataclasses * fuggin shit * yes * yeas * Remove data classes * Data field naming fixes * arg * Git resetti RobustToolbox * Merge fixes * General fixes * Fix startup serialization errors * Fix DamageContainerPrototype when supported classes or types are null * Implement construction graph step type serializer * Fix up construction serialization * Fix up construction serialization part 2 * Fix null list in technology database component * Fix body serialization * Fix entity storage serialization * Fix actions serialization * Fix AI serialization * Fix reaction serialization * Fix body serialization * Fix grid atmosphere serialization * Rename IServ3Manager to ISerializationManager * Convert every non generic serializer to the new format, general fixes * Serialization and body system fix * pushinheritance fix * Update all prototypes to have a parent and have consistent id/parent properties * Merge fixes * smh my head * cuddling slaps * Content commit for engine PR * stuff * more fixes * argh * yes even you are fixed * changelog fixes * fixes seeds * argh * Test fixes * Add writing for alert order prototype * Fix alert order writing * FIX * its been alot ok * Fix the rest of the visualizers * Fix server alerts component tests * Fix alert prototype tests not using the read value * Fix alert prototype tests initializing serialization multiple times * THIS IS AN AMERICAN CODEBASE GOD BLESS THE USA * Add ImplicitDataDefinitionForInheritors to IMechanismBehavior Fixes the behaviors not being found * Fix NRE in strap component Good night to the 1 buckle optimization * Fix clothing component slot flags serialization tag * Fix body component in all components test * Merge fixes * ffs * Make construction graph prototype use serialization hooks * human yaml linted * a * Do the thing for construction * stuff * a * monke see yaml linter * LINT HARDER * Remove redundant todo * yes * Add skip hook argument to readers and copiers * we gamin * test/datafield fixes * adds more verbose validation * moves linter to action * Improve construction graph step type serializer error message * Fix ammo box component NRE * gamin * some updates to the linter * yes * removes that test * misc fixes * array fix priority fix misc fixes * adds proper info the validation * adds alwaysrelevant usa * Make yaml linter take half as long to run (~50% less) * Make yaml linter 5 times faster (~80% less execution time) * based vera being based * fixes mapsaving * warning cleanup & moves surpressor * removes old msbuild targets * Revert "Make yaml linter 5 times faster (~80% less execution time)" This reverts commit 3e6091359a26252c3e98828199553de668031c63. * Add -nowarn to yaml linter run configuration * Improve yaml linter message feedback * Make dependencies an argument instead of a property on the serialization manager * yamllinting slaps * Clean up type serializers * Move yaml linter code to its own method * Fix yaml errors * Change yaml linter action name and remove -nowarn * yaml linter please shut * Git resetti robust toolbox Co-authored-by: Paul <ritter.paul1+git@googlemail.com> Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
260 lines
9.6 KiB
C#
260 lines
9.6 KiB
C#
using System;
|
|
using Content.Client.UserInterface.Stylesheets;
|
|
using Content.Client.Utility;
|
|
using Content.Shared.GameObjects;
|
|
using Content.Shared.GameObjects.Components.Weapons.Ranged;
|
|
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.Maths;
|
|
using Robust.Shared.Network;
|
|
using Robust.Shared.Players;
|
|
using Robust.Shared.Prototypes;
|
|
using Robust.Shared.Serialization;
|
|
using Robust.Shared.Serialization.Manager.Attributes;
|
|
using Robust.Shared.ViewVariables;
|
|
|
|
namespace Content.Client.GameObjects.Components.Weapons.Ranged.Barrels
|
|
{
|
|
[RegisterComponent]
|
|
public class ClientMagazineBarrelComponent : Component, IItemStatus
|
|
{
|
|
private static readonly Animation AlarmAnimationSmg = new()
|
|
{
|
|
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()
|
|
{
|
|
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)] [DataField("lmg_alarm_animation")] private bool _isLmgAlarmAnimation = default;
|
|
|
|
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
|
|
{
|
|
base.HandleComponentState(curState, nextState);
|
|
|
|
if (curState is not 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 MagazineAutoEjectMessage _:
|
|
_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 _bulletsList;
|
|
private readonly TextureRect _chamberedBullet;
|
|
private readonly Label _noMagazineLabel;
|
|
private readonly Label _ammoCount;
|
|
|
|
public StatusControl(ClientMagazineBarrelComponent parent)
|
|
{
|
|
MinHeight = 15;
|
|
_parent = parent;
|
|
HorizontalExpand = true;
|
|
VerticalAlignment = VAlignment.Center;
|
|
|
|
AddChild(new HBoxContainer
|
|
{
|
|
HorizontalExpand = true,
|
|
Children =
|
|
{
|
|
(_chamberedBullet = new TextureRect
|
|
{
|
|
Texture = StaticIoC.ResC.GetTexture("/Textures/Interface/ItemStatus/Bullets/chambered_rotated.png"),
|
|
VerticalAlignment = VAlignment.Center,
|
|
HorizontalAlignment = HAlignment.Right,
|
|
}),
|
|
new Control() { MinSize = (5,0) },
|
|
new Control
|
|
{
|
|
HorizontalExpand = true,
|
|
Children =
|
|
{
|
|
(_bulletsList = new HBoxContainer
|
|
{
|
|
VerticalAlignment = VAlignment.Center,
|
|
SeparationOverride = 0
|
|
}),
|
|
(_noMagazineLabel = new Label
|
|
{
|
|
Text = "No Magazine!",
|
|
StyleClasses = {StyleNano.StyleClassItemStatus}
|
|
})
|
|
}
|
|
},
|
|
new Control() { MinSize = (5,0) },
|
|
(_ammoCount = new Label
|
|
{
|
|
StyleClasses = {StyleNano.StyleClassItemStatus},
|
|
HorizontalAlignment = HAlignment.Right,
|
|
}),
|
|
}
|
|
});
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
_chamberedBullet.ModulateSelfOverride =
|
|
_parent.Chambered ? Color.FromHex("#d7df60") : Color.Black;
|
|
|
|
_bulletsList.RemoveAllChildren();
|
|
|
|
if (_parent.MagazineCount == null)
|
|
{
|
|
_noMagazineLabel.Visible = true;
|
|
_ammoCount.Visible = false;
|
|
return;
|
|
}
|
|
|
|
var (count, capacity) = _parent.MagazineCount.Value;
|
|
|
|
_noMagazineLabel.Visible = false;
|
|
_ammoCount.Visible = true;
|
|
|
|
var texturePath = "/Textures/Interface/ItemStatus/Bullets/normal.png";
|
|
var texture = StaticIoC.ResC.GetTexture(texturePath);
|
|
|
|
_ammoCount.Text = $"x{count:00}";
|
|
capacity = Math.Min(capacity, 20);
|
|
FillBulletRow(_bulletsList, 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;
|
|
|
|
// Draw the empty ones
|
|
for (var i = count; i < capacity; i++)
|
|
{
|
|
container.AddChild(new TextureRect
|
|
{
|
|
Texture = texture,
|
|
ModulateSelfOverride = altColor ? colorGoneA : colorGoneB,
|
|
Stretch = TextureRect.StretchMode.KeepCentered
|
|
});
|
|
|
|
altColor ^= true;
|
|
}
|
|
|
|
// Draw the full ones, but limit the count to the capacity
|
|
count = Math.Min(count, capacity);
|
|
for (var i = 0; i < count; i++)
|
|
{
|
|
container.AddChild(new TextureRect
|
|
{
|
|
Texture = texture,
|
|
ModulateSelfOverride = altColor ? colorA : colorB,
|
|
Stretch = TextureRect.StretchMode.KeepCentered
|
|
});
|
|
|
|
altColor ^= true;
|
|
}
|
|
}
|
|
|
|
public void PlayAlarmAnimation()
|
|
{
|
|
var animation = _parent._isLmgAlarmAnimation ? AlarmAnimationLmg : AlarmAnimationSmg;
|
|
_noMagazineLabel.PlayAnimation(animation, "alarm");
|
|
}
|
|
}
|
|
}
|
|
}
|