Merge branch 'master' into buckle-locker-fix-1262
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.GameObjects.Components.Mobs;
|
||||
using Content.Server.GameObjects.EntitySystems.Click;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||
using Content.Shared.GameObjects.Components.Mobs;
|
||||
using Content.Shared.Interfaces;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using Timer = Robust.Shared.Timers.Timer;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Weapon.Melee
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class FlashComponent : MeleeWeaponComponent, IUse, IExamine
|
||||
{
|
||||
#pragma warning disable 649
|
||||
[Dependency] private readonly ILocalizationManager _localizationManager;
|
||||
[Dependency] private readonly IEntityManager _entityManager;
|
||||
[Dependency] private readonly ISharedNotifyManager _notifyManager;
|
||||
#pragma warning restore 649
|
||||
|
||||
public override string Name => "Flash";
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)] private int _flashDuration = 5000;
|
||||
[ViewVariables(VVAccess.ReadWrite)] private float _flashFalloffExp = 8f;
|
||||
[ViewVariables(VVAccess.ReadWrite)] private int _uses = 5;
|
||||
[ViewVariables(VVAccess.ReadWrite)] private float _range = 3f;
|
||||
[ViewVariables(VVAccess.ReadWrite)] private int _aoeFlashDuration = 5000 / 3;
|
||||
[ViewVariables(VVAccess.ReadWrite)] private float _slowTo = 0.75f;
|
||||
private bool _flashing;
|
||||
|
||||
private int Uses
|
||||
{
|
||||
get => _uses;
|
||||
set
|
||||
{
|
||||
_uses = value;
|
||||
Dirty();
|
||||
}
|
||||
}
|
||||
|
||||
private bool HasUses => _uses > 0;
|
||||
|
||||
public override void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
base.ExposeData(serializer);
|
||||
|
||||
serializer.DataField(ref _flashDuration, "duration", 5000);
|
||||
serializer.DataField(ref _flashFalloffExp, "flashFalloffExp", 8f);
|
||||
serializer.DataField(ref _uses, "uses", 5);
|
||||
serializer.DataField(ref _range, "range", 3f);
|
||||
serializer.DataField(ref _aoeFlashDuration, "aoeFlashDuration", _flashDuration / 3);
|
||||
serializer.DataField(ref _slowTo, "slowTo", 0.75f);
|
||||
}
|
||||
|
||||
protected override bool OnHitEntities(IReadOnlyList<IEntity> entities, AttackEventArgs eventArgs)
|
||||
{
|
||||
if (entities.Count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Use(eventArgs.User))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
Flash(entity, eventArgs.User);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool UseEntity(UseEntityEventArgs eventArgs)
|
||||
{
|
||||
if (!Use(eventArgs.User))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var entity in _entityManager.GetEntitiesInRange(Owner.Transform.GridPosition, _range))
|
||||
{
|
||||
Flash(entity, eventArgs.User, _aoeFlashDuration);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool Use(IEntity user)
|
||||
{
|
||||
if (HasUses)
|
||||
{
|
||||
var sprite = Owner.GetComponent<SpriteComponent>();
|
||||
if (--Uses == 0)
|
||||
{
|
||||
sprite.LayerSetState(0, "burnt");
|
||||
|
||||
_notifyManager.PopupMessage(Owner, user, "The flash burns out!");
|
||||
}
|
||||
else if (!_flashing)
|
||||
{
|
||||
int animLayer = sprite.AddLayerWithState("flashing");
|
||||
_flashing = true;
|
||||
|
||||
Timer.Spawn(400, () =>
|
||||
{
|
||||
sprite.RemoveLayer(animLayer);
|
||||
_flashing = false;
|
||||
});
|
||||
}
|
||||
|
||||
EntitySystem.Get<AudioSystem>().PlayAtCoords("/Audio/weapons/flash.ogg", Owner.Transform.GridPosition,
|
||||
AudioParams.Default);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void Flash(IEntity entity, IEntity user)
|
||||
{
|
||||
Flash(entity, user, _flashDuration);
|
||||
}
|
||||
|
||||
// TODO: Check if target can be flashed (e.g. things like sunglasses would block a flash)
|
||||
private void Flash(IEntity entity, IEntity user, int flashDuration)
|
||||
{
|
||||
if (entity.TryGetComponent(out ServerOverlayEffectsComponent overlayEffectsComponent))
|
||||
{
|
||||
var container = new TimedOverlayContainer(nameof(OverlayType.FlashOverlay), flashDuration);
|
||||
overlayEffectsComponent.AddOverlay(container);
|
||||
container.StartTimer(() => overlayEffectsComponent.RemoveOverlay(container));
|
||||
}
|
||||
|
||||
if (entity.TryGetComponent(out StunnableComponent stunnableComponent))
|
||||
{
|
||||
stunnableComponent.Slowdown(flashDuration / 1000f, _slowTo, _slowTo);
|
||||
}
|
||||
|
||||
if (entity != user)
|
||||
{
|
||||
_notifyManager.PopupMessage(user, entity, $"{user.Name} blinds you with the {Owner.Name}");
|
||||
}
|
||||
}
|
||||
|
||||
public void Examine(FormattedMessage message, bool inDetailsRange)
|
||||
{
|
||||
if (!HasUses)
|
||||
{
|
||||
message.AddText("It's burnt out.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (inDetailsRange)
|
||||
{
|
||||
message.AddMarkup(_localizationManager.GetString(
|
||||
$"The flash has [color=green]{Uses}[/color] uses remaining."));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||
using Content.Shared.GameObjects;
|
||||
using Content.Shared.GameObjects.Components.Items;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
@@ -81,9 +81,9 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee
|
||||
serializer.DataField(ref _cooldownTime, "cooldownTime", 1f);
|
||||
}
|
||||
|
||||
public virtual bool OnHitEntities(IReadOnlyList<IEntity> entities)
|
||||
protected virtual bool OnHitEntities(IReadOnlyList<IEntity> entities, AttackEventArgs eventArgs)
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void IAttack.Attack(AttackEventArgs eventArgs)
|
||||
@@ -112,7 +112,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee
|
||||
}
|
||||
}
|
||||
|
||||
if(OnHitEntities(hitEntities)) return;
|
||||
if(!OnHitEntities(hitEntities, eventArgs)) return;
|
||||
|
||||
var audioSystem = EntitySystem.Get<AudioSystem>();
|
||||
var emitter = hitEntities.Count == 0 ? eventArgs.User : hitEntities[0];
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
using Content.Server.GameObjects.Components.Items.Storage;
|
||||
using Content.Server.GameObjects.Components.Mobs;
|
||||
using Content.Server.GameObjects.Components.Power;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.GameObjects.EntitySystems.Click;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||
using Content.Server.Interfaces.GameObjects;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.GameObjects;
|
||||
@@ -86,7 +87,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee
|
||||
serializer.DataField(ref _slowdownTime, "slowdownTime", 5f);
|
||||
}
|
||||
|
||||
public override bool OnHitEntities(IReadOnlyList<IEntity> entities)
|
||||
protected override bool OnHitEntities(IReadOnlyList<IEntity> entities, AttackEventArgs eventArgs)
|
||||
{
|
||||
var cell = Cell;
|
||||
if (!Activated || entities.Count == 0 || cell == null)
|
||||
@@ -118,7 +119,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee
|
||||
TurnOff();
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ToggleStatus(IEntity user)
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using Content.Server.GameObjects.Components.Items.Storage;
|
||||
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.GameObjects;
|
||||
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using Content.Server.GameObjects.Components.Items.Storage;
|
||||
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
|
||||
using Content.Shared.Interfaces;
|
||||
@@ -33,7 +34,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition
|
||||
public int ShotsLeft => _spawnedAmmo.Count + _unspawnedCount;
|
||||
public int Capacity => _capacity;
|
||||
private int _capacity;
|
||||
|
||||
|
||||
public MagazineType MagazineType => _magazineType;
|
||||
private MagazineType _magazineType;
|
||||
public BallisticCaliber Caliber => _caliber;
|
||||
@@ -88,7 +89,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition
|
||||
{
|
||||
_appearanceComponent = appearanceComponent;
|
||||
}
|
||||
|
||||
|
||||
_appearanceComponent?.SetData(MagazineBarrelVisuals.MagLoaded, true);
|
||||
}
|
||||
|
||||
@@ -97,7 +98,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition
|
||||
_appearanceComponent?.SetData(AmmoVisuals.AmmoCount, ShotsLeft);
|
||||
_appearanceComponent?.SetData(AmmoVisuals.AmmoMax, Capacity);
|
||||
}
|
||||
|
||||
|
||||
public bool TryInsertAmmo(IEntity user, IEntity ammo)
|
||||
{
|
||||
if (!ammo.TryGetComponent(out AmmoComponent ammoComponent))
|
||||
@@ -137,7 +138,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition
|
||||
_unspawnedCount--;
|
||||
ammo = Owner.EntityManager.SpawnEntity(_fillPrototype, Owner.Transform.GridPosition);
|
||||
}
|
||||
|
||||
|
||||
UpdateAppearance();
|
||||
return ammo;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Collections.Generic;
|
||||
using Content.Server.GameObjects.Components.Items.Storage;
|
||||
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
|
||||
using Content.Shared.Interfaces;
|
||||
using Robust.Server.GameObjects;
|
||||
@@ -39,7 +40,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition
|
||||
serializer.DataField(ref _caliber, "caliber", BallisticCaliber.Unspecified);
|
||||
serializer.DataField(ref _capacity, "capacity", 6);
|
||||
serializer.DataField(ref _fillPrototype, "fillPrototype", null);
|
||||
|
||||
|
||||
_spawnedAmmo = new Stack<IEntity>(_capacity);
|
||||
}
|
||||
|
||||
@@ -57,7 +58,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IMapInit.MapInit()
|
||||
{
|
||||
_unspawnedCount += _capacity;
|
||||
@@ -92,7 +93,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition
|
||||
Owner.PopupMessage(user, Loc.GetString("No room"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
_spawnedAmmo.Push(entity);
|
||||
_ammoContainer.Insert(entity);
|
||||
UpdateAppearance();
|
||||
@@ -150,10 +151,10 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// This area is dirty but not sure of an easier way to do it besides add an interface or somethin
|
||||
bool changed = false;
|
||||
|
||||
|
||||
if (eventArgs.Target.TryGetComponent(out RevolverBarrelComponent revolverBarrel))
|
||||
{
|
||||
for (var i = 0; i < Capacity; i++)
|
||||
@@ -194,9 +195,9 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition
|
||||
TryInsertAmmo(eventArgs.User, ammo);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (changed)
|
||||
{
|
||||
UpdateAppearance();
|
||||
@@ -213,4 +214,4 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition
|
||||
return UseEntity(eventArgs.User);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Collections.Generic;
|
||||
using Content.Server.GameObjects.Components.Sound;
|
||||
using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||
using Content.Shared.GameObjects;
|
||||
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Collections.Generic;
|
||||
using Content.Server.GameObjects.Components.Sound;
|
||||
using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
|
||||
using Content.Shared.Interfaces;
|
||||
using Robust.Server.GameObjects;
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using Content.Server.GameObjects.Components.Sound;
|
||||
using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||
using Content.Shared.GameObjects;
|
||||
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
|
||||
@@ -5,6 +5,7 @@ using Content.Server.GameObjects.Components.Power;
|
||||
using Content.Server.GameObjects.Components.Projectiles;
|
||||
using Content.Server.GameObjects.Components.Sound;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||
using Content.Shared.GameObjects;
|
||||
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
|
||||
using Robust.Server.GameObjects;
|
||||
@@ -69,9 +70,9 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
|
||||
return (int) Math.Ceiling((float) (powerCell.GetComponent<BatteryComponent>().MaxCharge / _baseFireCost));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private AppearanceComponent _appearanceComponent;
|
||||
|
||||
|
||||
// Sounds
|
||||
private string _soundPowerCellInsert;
|
||||
private string _soundPowerCellEject;
|
||||
@@ -111,10 +112,10 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
|
||||
{
|
||||
_appearanceComponent = appearanceComponent;
|
||||
}
|
||||
|
||||
|
||||
UpdateAppearance();
|
||||
}
|
||||
|
||||
|
||||
public void UpdateAppearance()
|
||||
{
|
||||
_appearanceComponent?.SetData(MagazineBarrelVisuals.MagLoaded, _powerCellContainer.ContainedEntity != null);
|
||||
@@ -224,14 +225,14 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
var entity = _powerCellContainer.ContainedEntity;
|
||||
_powerCellContainer.Remove(entity);
|
||||
if (_soundPowerCellEject != null)
|
||||
{
|
||||
EntitySystem.Get<AudioSystem>().PlayAtCoords(_soundPowerCellEject, Owner.Transform.GridPosition, AudioParams.Default.WithVolume(-2));
|
||||
}
|
||||
|
||||
|
||||
UpdateAppearance();
|
||||
//Dirty();
|
||||
return entity;
|
||||
@@ -243,8 +244,8 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!eventArgs.User.TryGetComponent(out HandsComponent handsComponent) ||
|
||||
|
||||
if (!eventArgs.User.TryGetComponent(out HandsComponent handsComponent) ||
|
||||
PowerCellEntity == null)
|
||||
{
|
||||
return false;
|
||||
@@ -255,7 +256,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
var powerCell = RemovePowerCell();
|
||||
handsComponent.PutInHand(itemComponent);
|
||||
powerCell.Transform.GridPosition = eventArgs.User.Transform.GridPosition;
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using Content.Server.GameObjects.Components.Items.Storage;
|
||||
using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||
using Content.Shared.GameObjects;
|
||||
using Content.Shared.GameObjects.Components.Weapons.Ranged;
|
||||
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
|
||||
|
||||
@@ -5,6 +5,7 @@ using Content.Server.GameObjects.Components.Mobs;
|
||||
using Content.Server.GameObjects.Components.Projectiles;
|
||||
using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.GameObjects.Components.Weapons.Ranged;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using Content.Server.GameObjects.Components.Mobs;
|
||||
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Interaction;
|
||||
using Content.Shared.GameObjects.Components.Weapons.Ranged;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
Reference in New Issue
Block a user