Content update for NetEntities (#18935)
This commit is contained in:
@@ -10,9 +10,9 @@ namespace Content.Shared.Weapons.Melee.Events
|
||||
/// <summary>
|
||||
/// Coordinates being attacked.
|
||||
/// </summary>
|
||||
public readonly EntityCoordinates Coordinates;
|
||||
public readonly NetCoordinates Coordinates;
|
||||
|
||||
protected AttackEvent(EntityCoordinates coordinates)
|
||||
protected AttackEvent(NetCoordinates coordinates)
|
||||
{
|
||||
Coordinates = coordinates;
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ namespace Content.Shared.Weapons.Melee.Events;
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class DisarmAttackEvent : AttackEvent
|
||||
{
|
||||
public EntityUid? Target;
|
||||
public NetEntity? Target;
|
||||
|
||||
public DisarmAttackEvent(EntityUid? target, EntityCoordinates coordinates) : base(coordinates)
|
||||
public DisarmAttackEvent(NetEntity? target, NetCoordinates coordinates) : base(coordinates)
|
||||
{
|
||||
Target = target;
|
||||
}
|
||||
|
||||
@@ -9,14 +9,14 @@ namespace Content.Shared.Weapons.Melee.Events;
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class HeavyAttackEvent : AttackEvent
|
||||
{
|
||||
public readonly EntityUid Weapon;
|
||||
public readonly NetEntity Weapon;
|
||||
|
||||
/// <summary>
|
||||
/// As what the client swung at will not match server we'll have them tell us what they hit so we can verify.
|
||||
/// </summary>
|
||||
public List<EntityUid> Entities;
|
||||
public List<NetEntity> Entities;
|
||||
|
||||
public HeavyAttackEvent(EntityUid weapon, List<EntityUid> entities, EntityCoordinates coordinates) : base(coordinates)
|
||||
public HeavyAttackEvent(NetEntity weapon, List<NetEntity> entities, NetCoordinates coordinates) : base(coordinates)
|
||||
{
|
||||
Weapon = weapon;
|
||||
Entities = entities;
|
||||
|
||||
@@ -9,10 +9,10 @@ namespace Content.Shared.Weapons.Melee.Events;
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class LightAttackEvent : AttackEvent
|
||||
{
|
||||
public readonly EntityUid? Target;
|
||||
public readonly EntityUid Weapon;
|
||||
public readonly NetEntity? Target;
|
||||
public readonly NetEntity Weapon;
|
||||
|
||||
public LightAttackEvent(EntityUid? target, EntityUid weapon, EntityCoordinates coordinates) : base(coordinates)
|
||||
public LightAttackEvent(NetEntity? target, NetEntity weapon, NetCoordinates coordinates) : base(coordinates)
|
||||
{
|
||||
Target = target;
|
||||
Weapon = weapon;
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Content.Shared.Weapons.Melee.Events;
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class MeleeLungeEvent : EntityEventArgs
|
||||
{
|
||||
public EntityUid Entity;
|
||||
public NetEntity Entity;
|
||||
|
||||
/// <summary>
|
||||
/// Width of the attack angle.
|
||||
@@ -26,9 +26,9 @@ public sealed class MeleeLungeEvent : EntityEventArgs
|
||||
/// </summary>
|
||||
public string? Animation;
|
||||
|
||||
public MeleeLungeEvent(EntityUid uid, Angle angle, Vector2 localPos, string? animation)
|
||||
public MeleeLungeEvent(NetEntity entity, Angle angle, Vector2 localPos, string? animation)
|
||||
{
|
||||
Entity = uid;
|
||||
Entity = entity;
|
||||
Angle = angle;
|
||||
LocalPos = localPos;
|
||||
Animation = animation;
|
||||
|
||||
@@ -5,9 +5,9 @@ namespace Content.Shared.Weapons.Melee.Events;
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class StopAttackEvent : EntityEventArgs
|
||||
{
|
||||
public readonly EntityUid Weapon;
|
||||
public readonly NetEntity Weapon;
|
||||
|
||||
public StopAttackEvent(EntityUid weapon)
|
||||
public StopAttackEvent(NetEntity weapon)
|
||||
{
|
||||
Weapon = weapon;
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
return;
|
||||
|
||||
if (!TryGetWeapon(user.Value, out var weaponUid, out var weapon) ||
|
||||
weaponUid != msg.Weapon)
|
||||
weaponUid != GetEntity(msg.Weapon))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -184,12 +184,12 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
return;
|
||||
|
||||
if (!TryGetWeapon(user.Value, out var weaponUid, out var weapon) ||
|
||||
weaponUid != msg.Weapon)
|
||||
weaponUid != GetEntity(msg.Weapon))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AttemptAttack(args.SenderSession.AttachedEntity!.Value, msg.Weapon, weapon, msg, args.SenderSession);
|
||||
AttemptAttack(args.SenderSession.AttachedEntity!.Value, weaponUid, weapon, msg, args.SenderSession);
|
||||
}
|
||||
|
||||
private void OnHeavyAttack(HeavyAttackEvent msg, EntitySessionEventArgs args)
|
||||
@@ -200,12 +200,12 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
}
|
||||
|
||||
if (!TryGetWeapon(args.SenderSession.AttachedEntity.Value, out var weaponUid, out var weapon) ||
|
||||
weaponUid != msg.Weapon)
|
||||
weaponUid != GetEntity(msg.Weapon))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AttemptAttack(args.SenderSession.AttachedEntity.Value, msg.Weapon, weapon, msg, args.SenderSession);
|
||||
AttemptAttack(args.SenderSession.AttachedEntity.Value, weaponUid, weapon, msg, args.SenderSession);
|
||||
}
|
||||
|
||||
private void OnDisarmAttack(DisarmAttackEvent msg, EntitySessionEventArgs args)
|
||||
@@ -330,7 +330,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
|
||||
public void AttemptLightAttackMiss(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, EntityCoordinates coordinates)
|
||||
{
|
||||
AttemptAttack(user, weaponUid, weapon, new LightAttackEvent(null, weaponUid, coordinates), null);
|
||||
AttemptAttack(user, weaponUid, weapon, new LightAttackEvent(null, GetNetEntity(weaponUid), GetNetCoordinates(coordinates)), null);
|
||||
}
|
||||
|
||||
public bool AttemptLightAttack(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, EntityUid target)
|
||||
@@ -338,7 +338,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
if (!TryComp<TransformComponent>(target, out var targetXform))
|
||||
return false;
|
||||
|
||||
return AttemptAttack(user, weaponUid, weapon, new LightAttackEvent(target, weaponUid, targetXform.Coordinates), null);
|
||||
return AttemptAttack(user, weaponUid, weapon, new LightAttackEvent(GetNetEntity(target), GetNetEntity(weaponUid), GetNetCoordinates(targetXform.Coordinates)), null);
|
||||
}
|
||||
|
||||
public bool AttemptDisarmAttack(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, EntityUid target)
|
||||
@@ -346,7 +346,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
if (!TryComp<TransformComponent>(target, out var targetXform))
|
||||
return false;
|
||||
|
||||
return AttemptAttack(user, weaponUid, weapon, new DisarmAttackEvent(target, targetXform.Coordinates), null);
|
||||
return AttemptAttack(user, weaponUid, weapon, new DisarmAttackEvent(GetNetEntity(target), GetNetCoordinates(targetXform.Coordinates)), null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -366,16 +366,20 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
switch (attack)
|
||||
{
|
||||
case LightAttackEvent light:
|
||||
if (!Blocker.CanAttack(user, light.Target))
|
||||
var lightTarget = GetEntity(light.Target);
|
||||
|
||||
if (!Blocker.CanAttack(user, lightTarget))
|
||||
return false;
|
||||
|
||||
// Can't self-attack if you're the weapon
|
||||
if (weaponUid == light.Target)
|
||||
if (weaponUid == lightTarget)
|
||||
return false;
|
||||
|
||||
break;
|
||||
case DisarmAttackEvent disarm:
|
||||
if (!Blocker.CanAttack(user, disarm.Target))
|
||||
var disarmTarget = GetEntity(disarm.Target);
|
||||
|
||||
if (!Blocker.CanAttack(user, disarmTarget))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
@@ -441,7 +445,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
DoLungeAnimation(user, weapon.Angle, attack.Coordinates.ToMap(EntityManager, TransformSystem), weapon.Range, animation);
|
||||
DoLungeAnimation(user, weapon.Angle, GetCoordinates(attack.Coordinates).ToMap(EntityManager, TransformSystem), weapon.Range, animation);
|
||||
}
|
||||
|
||||
weapon.Attacking = true;
|
||||
@@ -454,13 +458,14 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
{
|
||||
// If I do not come back later to fix Light Attacks being Heavy Attacks you can throw me in the spider pit -Errant
|
||||
var damage = GetDamage(meleeUid, user, component) * GetHeavyDamageModifier(meleeUid, user, component);
|
||||
var target = GetEntity(ev.Target);
|
||||
|
||||
// For consistency with wide attacks stuff needs damageable.
|
||||
if (Deleted(ev.Target) ||
|
||||
!HasComp<DamageableComponent>(ev.Target) ||
|
||||
!TryComp<TransformComponent>(ev.Target, out var targetXform) ||
|
||||
if (Deleted(target) ||
|
||||
!HasComp<DamageableComponent>(target) ||
|
||||
!TryComp<TransformComponent>(target, out var targetXform) ||
|
||||
// Not in LOS.
|
||||
!InRange(user, ev.Target.Value, component.Range, session))
|
||||
!InRange(user, target.Value, component.Range, session))
|
||||
{
|
||||
// Leave IsHit set to true, because the only time it's set to false
|
||||
// is when a melee weapon is examined. Misses are inferred from an
|
||||
@@ -485,7 +490,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
// Sawmill.Debug($"Melee damage is {damage.Total} out of {component.Damage.Total}");
|
||||
|
||||
// Raise event before doing damage so we can cancel damage if the event is handled
|
||||
var hitEvent = new MeleeHitEvent(new List<EntityUid> { ev.Target.Value }, user, meleeUid, damage);
|
||||
var hitEvent = new MeleeHitEvent(new List<EntityUid> { target.Value }, user, meleeUid, damage);
|
||||
RaiseLocalEvent(meleeUid, hitEvent);
|
||||
|
||||
if (hitEvent.Handled)
|
||||
@@ -493,43 +498,45 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
|
||||
var targets = new List<EntityUid>(1)
|
||||
{
|
||||
ev.Target.Value
|
||||
target.Value
|
||||
};
|
||||
|
||||
Interaction.DoContactInteraction(ev.Weapon, ev.Target);
|
||||
Interaction.DoContactInteraction(user, ev.Weapon);
|
||||
var weapon = GetEntity(ev.Weapon);
|
||||
|
||||
Interaction.DoContactInteraction(weapon, target);
|
||||
Interaction.DoContactInteraction(user, weapon);
|
||||
|
||||
// If the user is using a long-range weapon, this probably shouldn't be happening? But I'll interpret melee as a
|
||||
// somewhat messy scuffle. See also, heavy attacks.
|
||||
Interaction.DoContactInteraction(user, ev.Target);
|
||||
Interaction.DoContactInteraction(user, target);
|
||||
|
||||
// For stuff that cares about it being attacked.
|
||||
var attackedEvent = new AttackedEvent(meleeUid, user, targetXform.Coordinates);
|
||||
RaiseLocalEvent(ev.Target.Value, attackedEvent);
|
||||
RaiseLocalEvent(target.Value, attackedEvent);
|
||||
|
||||
var modifiedDamage = DamageSpecifier.ApplyModifierSets(damage + hitEvent.BonusDamage + attackedEvent.BonusDamage, hitEvent.ModifiersList);
|
||||
var damageResult = Damageable.TryChangeDamage(ev.Target, modifiedDamage, origin:user);
|
||||
var damageResult = Damageable.TryChangeDamage(target, modifiedDamage, origin:user);
|
||||
|
||||
if (damageResult != null && damageResult.Total > FixedPoint2.Zero)
|
||||
{
|
||||
// If the target has stamina and is taking blunt damage, they should also take stamina damage based on their blunt to stamina factor
|
||||
if (damageResult.DamageDict.TryGetValue("Blunt", out var bluntDamage))
|
||||
{
|
||||
_stamina.TakeStaminaDamage(ev.Target.Value, (bluntDamage * component.BluntStaminaDamageFactor).Float(), visual: false, source: user, with: meleeUid == user ? null : meleeUid);
|
||||
_stamina.TakeStaminaDamage(target.Value, (bluntDamage * component.BluntStaminaDamageFactor).Float(), visual: false, source: user, with: meleeUid == user ? null : meleeUid);
|
||||
}
|
||||
|
||||
if (meleeUid == user)
|
||||
{
|
||||
AdminLogger.Add(LogType.MeleeHit, LogImpact.Medium,
|
||||
$"{ToPrettyString(user):actor} melee attacked (light) {ToPrettyString(ev.Target.Value):subject} using their hands and dealt {damageResult.Total:damage} damage");
|
||||
$"{ToPrettyString(user):actor} melee attacked (light) {ToPrettyString(target.Value):subject} using their hands and dealt {damageResult.Total:damage} damage");
|
||||
}
|
||||
else
|
||||
{
|
||||
AdminLogger.Add(LogType.MeleeHit, LogImpact.Medium,
|
||||
$"{ToPrettyString(user):actor} melee attacked (light) {ToPrettyString(ev.Target.Value):subject} using {ToPrettyString(meleeUid):tool} and dealt {damageResult.Total:damage} damage");
|
||||
$"{ToPrettyString(user):actor} melee attacked (light) {ToPrettyString(target.Value):subject} using {ToPrettyString(meleeUid):tool} and dealt {damageResult.Total:damage} damage");
|
||||
}
|
||||
|
||||
PlayHitSound(ev.Target.Value, user, GetHighestDamageSound(modifiedDamage, _protoManager), hitEvent.HitSoundOverride, component.HitSound);
|
||||
PlayHitSound(target.Value, user, GetHighestDamageSound(modifiedDamage, _protoManager), hitEvent.HitSoundOverride, component.HitSound);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -561,7 +568,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
if (!TryComp<TransformComponent>(user, out var userXform))
|
||||
return false;
|
||||
|
||||
var targetMap = ev.Coordinates.ToMap(EntityManager, TransformSystem);
|
||||
var targetMap = GetCoordinates(ev.Coordinates).ToMap(EntityManager, TransformSystem);
|
||||
|
||||
if (targetMap.MapId != userXform.MapID)
|
||||
return false;
|
||||
@@ -571,7 +578,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
var distance = Math.Min(component.Range, direction.Length());
|
||||
|
||||
var damage = GetDamage(meleeUid, user, component);
|
||||
var entities = ev.Entities;
|
||||
var entities = GetEntityList(ev.Entities);
|
||||
|
||||
if (entities.Count == 0)
|
||||
{
|
||||
@@ -632,12 +639,14 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
if (hitEvent.Handled)
|
||||
return true;
|
||||
|
||||
Interaction.DoContactInteraction(user, ev.Weapon);
|
||||
var weapon = GetEntity(ev.Weapon);
|
||||
|
||||
Interaction.DoContactInteraction(user, weapon);
|
||||
|
||||
// For stuff that cares about it being attacked.
|
||||
foreach (var target in targets)
|
||||
{
|
||||
Interaction.DoContactInteraction(ev.Weapon, target);
|
||||
Interaction.DoContactInteraction(weapon, target);
|
||||
|
||||
// If the user is using a long-range weapon, this probably shouldn't be happening? But I'll interpret melee as a
|
||||
// somewhat messy scuffle. See also, light attacks.
|
||||
@@ -648,7 +657,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
|
||||
foreach (var entity in targets)
|
||||
{
|
||||
var attackedEvent = new AttackedEvent(meleeUid, user, ev.Coordinates);
|
||||
var attackedEvent = new AttackedEvent(meleeUid, user, GetCoordinates(ev.Coordinates));
|
||||
RaiseLocalEvent(entity, attackedEvent);
|
||||
var modifiedDamage = DamageSpecifier.ApplyModifierSets(damage + hitEvent.BonusDamage + attackedEvent.BonusDamage, hitEvent.ModifiersList);
|
||||
|
||||
@@ -820,9 +829,13 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
|
||||
protected virtual bool DoDisarm(EntityUid user, DisarmAttackEvent ev, EntityUid meleeUid, MeleeWeaponComponent component, ICommonSession? session)
|
||||
{
|
||||
if (Deleted(ev.Target) ||
|
||||
user == ev.Target)
|
||||
var target = GetEntity(ev.Target);
|
||||
|
||||
if (Deleted(target) ||
|
||||
user == target)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Play a sound to give instant feedback; same with playing the animations
|
||||
Audio.PlayPredicted(component.SwingSound, meleeUid, user);
|
||||
|
||||
@@ -112,14 +112,16 @@ public abstract partial class SharedTetherGunSystem : EntitySystem
|
||||
return;
|
||||
}
|
||||
|
||||
if (!msg.Coordinates.TryDistance(EntityManager, TransformSystem, Transform(gunUid.Value).Coordinates,
|
||||
var coords = GetCoordinates(msg.Coordinates);
|
||||
|
||||
if (!coords.TryDistance(EntityManager, TransformSystem, Transform(gunUid.Value).Coordinates,
|
||||
out var distance) ||
|
||||
distance > gun.MaxDistance)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TransformSystem.SetCoordinates(gun.TetherEntity.Value, msg.Coordinates);
|
||||
TransformSystem.SetCoordinates(gun.TetherEntity.Value, coords);
|
||||
}
|
||||
|
||||
private void OnTetherRanged(EntityUid uid, TetherGunComponent component, AfterInteractEvent args)
|
||||
@@ -283,7 +285,7 @@ public abstract partial class SharedTetherGunSystem : EntitySystem
|
||||
[Serializable, NetSerializable]
|
||||
protected sealed class RequestTetherMoveEvent : EntityEventArgs
|
||||
{
|
||||
public EntityCoordinates Coordinates;
|
||||
public NetCoordinates Coordinates;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
|
||||
@@ -7,7 +7,7 @@ using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototy
|
||||
|
||||
namespace Content.Shared.Weapons.Ranged.Components;
|
||||
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class BallisticAmmoProviderComponent : Component
|
||||
{
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField("soundRack")]
|
||||
@@ -25,7 +25,6 @@ public sealed partial class BallisticAmmoProviderComponent : Component
|
||||
public int Count => UnspawnedCount + Container.ContainedEntities.Count;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField("unspawnedCount")]
|
||||
[AutoNetworkedField]
|
||||
public int UnspawnedCount;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField("whitelist")]
|
||||
@@ -35,7 +34,6 @@ public sealed partial class BallisticAmmoProviderComponent : Component
|
||||
|
||||
// TODO: Make this use stacks when the typeserializer is done.
|
||||
[DataField("entities")]
|
||||
[AutoNetworkedField(true)]
|
||||
public List<EntityUid> Entities = new();
|
||||
|
||||
/// <summary>
|
||||
@@ -45,7 +43,6 @@ public sealed partial class BallisticAmmoProviderComponent : Component
|
||||
/// Set to false for entities like turrets to avoid users being able to cycle them.
|
||||
/// </remarks>
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField("cycleable")]
|
||||
[AutoNetworkedField]
|
||||
public bool Cycleable = true;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Content.Shared.Weapons.Ranged.Events;
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class MuzzleFlashEvent : EntityEventArgs
|
||||
{
|
||||
public EntityUid Uid;
|
||||
public NetEntity Uid;
|
||||
public string Prototype;
|
||||
|
||||
/// <summary>
|
||||
@@ -16,7 +16,7 @@ public sealed class MuzzleFlashEvent : EntityEventArgs
|
||||
/// </summary>
|
||||
public bool MatchRotation;
|
||||
|
||||
public MuzzleFlashEvent(EntityUid uid, string prototype, bool matchRotation = false)
|
||||
public MuzzleFlashEvent(NetEntity uid, string prototype, bool matchRotation = false)
|
||||
{
|
||||
Uid = uid;
|
||||
Prototype = prototype;
|
||||
|
||||
@@ -9,6 +9,6 @@ namespace Content.Shared.Weapons.Ranged.Events;
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class RequestShootEvent : EntityEventArgs
|
||||
{
|
||||
public EntityUid Gun;
|
||||
public EntityCoordinates Coordinates;
|
||||
}
|
||||
public NetEntity Gun;
|
||||
public NetCoordinates Coordinates;
|
||||
}
|
||||
|
||||
@@ -8,5 +8,5 @@ namespace Content.Shared.Weapons.Ranged.Events;
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class RequestStopShootEvent : EntityEventArgs
|
||||
{
|
||||
public EntityUid Gun;
|
||||
}
|
||||
public NetEntity Gun;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,29 @@ public abstract partial class SharedGunSystem
|
||||
SubscribeLocalEvent<BallisticAmmoProviderComponent, AfterInteractEvent>(OnBallisticAfterInteract);
|
||||
SubscribeLocalEvent<BallisticAmmoProviderComponent, AmmoFillDoAfterEvent>(OnBallisticAmmoFillDoAfter);
|
||||
SubscribeLocalEvent<BallisticAmmoProviderComponent, UseInHandEvent>(OnBallisticUse);
|
||||
|
||||
SubscribeLocalEvent<BallisticAmmoProviderComponent, ComponentGetState>(OnBallisticGetState);
|
||||
SubscribeLocalEvent<BallisticAmmoProviderComponent, ComponentHandleState>(OnBallisticHandleState);
|
||||
}
|
||||
|
||||
private void OnBallisticGetState(EntityUid uid, BallisticAmmoProviderComponent component, ref ComponentGetState args)
|
||||
{
|
||||
args.State = new BallisticAmmoProviderComponentState()
|
||||
{
|
||||
UnspawnedCount = component.UnspawnedCount,
|
||||
Cycleable = component.Cycleable,
|
||||
Entities = GetNetEntityList(component.Entities),
|
||||
};
|
||||
}
|
||||
|
||||
private void OnBallisticHandleState(EntityUid uid, BallisticAmmoProviderComponent component, ref ComponentHandleState args)
|
||||
{
|
||||
if (args.Current is not BallisticAmmoProviderComponentState state)
|
||||
return;
|
||||
|
||||
component.UnspawnedCount = state.UnspawnedCount;
|
||||
component.Cycleable = state.Cycleable;
|
||||
component.Entities = EnsureEntityList<BallisticAmmoProviderComponent>(state.Entities, uid);
|
||||
}
|
||||
|
||||
private void OnBallisticUse(EntityUid uid, BallisticAmmoProviderComponent component, UseInHandEvent args)
|
||||
@@ -73,7 +96,7 @@ public abstract partial class SharedGunSystem
|
||||
|
||||
args.Handled = true;
|
||||
|
||||
_doAfter.TryStartDoAfter(new DoAfterArgs(args.User, component.FillDelay, new AmmoFillDoAfterEvent(), used: uid, target: args.Target, eventTarget: uid)
|
||||
_doAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, component.FillDelay, new AmmoFillDoAfterEvent(), used: uid, target: args.Target, eventTarget: uid)
|
||||
{
|
||||
BreakOnTargetMove = true,
|
||||
BreakOnUserMove = true,
|
||||
@@ -141,7 +164,7 @@ public abstract partial class SharedGunSystem
|
||||
SimulateInsertAmmo(ent.Value, args.Target.Value, Transform(args.Target.Value).Coordinates);
|
||||
}
|
||||
|
||||
if (ent.Value.IsClientSide())
|
||||
if (IsClientSide(ent.Value))
|
||||
Del(ent.Value);
|
||||
}
|
||||
|
||||
@@ -269,6 +292,14 @@ public abstract partial class SharedGunSystem
|
||||
Appearance.SetData(uid, AmmoVisuals.AmmoCount, GetBallisticShots(component), appearance);
|
||||
Appearance.SetData(uid, AmmoVisuals.AmmoMax, component.Capacity, appearance);
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
private sealed class BallisticAmmoProviderComponentState : ComponentState
|
||||
{
|
||||
public int UnspawnedCount;
|
||||
public List<NetEntity> Entities = new();
|
||||
public bool Cycleable = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -47,7 +47,7 @@ public partial class SharedGunSystem
|
||||
args.State = new RevolverAmmoProviderComponentState
|
||||
{
|
||||
CurrentIndex = component.CurrentIndex,
|
||||
AmmoSlots = component.AmmoSlots,
|
||||
AmmoSlots = GetNetEntityList(component.AmmoSlots),
|
||||
Chambers = component.Chambers,
|
||||
};
|
||||
}
|
||||
@@ -64,7 +64,7 @@ public partial class SharedGunSystem
|
||||
// Need to copy across the state rather than the ref.
|
||||
for (var i = 0; i < component.AmmoSlots.Count; i++)
|
||||
{
|
||||
component.AmmoSlots[i] = state.AmmoSlots[i];
|
||||
component.AmmoSlots[i] = EnsureEntity<RevolverAmmoProviderComponent>(state.AmmoSlots[i], uid);
|
||||
component.Chambers[i] = state.Chambers[i];
|
||||
}
|
||||
|
||||
@@ -416,7 +416,7 @@ public partial class SharedGunSystem
|
||||
protected sealed class RevolverAmmoProviderComponentState : ComponentState
|
||||
{
|
||||
public int CurrentIndex;
|
||||
public List<EntityUid?> AmmoSlots = default!;
|
||||
public List<NetEntity?> AmmoSlots = default!;
|
||||
public bool?[] Chambers = default!;
|
||||
}
|
||||
|
||||
|
||||
@@ -131,18 +131,20 @@ public abstract partial class SharedGunSystem : EntitySystem
|
||||
return;
|
||||
}
|
||||
|
||||
if (ent != msg.Gun)
|
||||
if (ent != GetEntity(msg.Gun))
|
||||
return;
|
||||
|
||||
gun.ShootCoordinates = msg.Coordinates;
|
||||
gun.ShootCoordinates = GetCoordinates(msg.Coordinates);
|
||||
Log.Debug($"Set shoot coordinates to {gun.ShootCoordinates}");
|
||||
AttemptShoot(user.Value, ent, gun);
|
||||
}
|
||||
|
||||
private void OnStopShootRequest(RequestStopShootEvent ev, EntitySessionEventArgs args)
|
||||
{
|
||||
var gunUid = GetEntity(ev.Gun);
|
||||
|
||||
if (args.SenderSession.AttachedEntity == null ||
|
||||
!TryComp<GunComponent>(ev.Gun, out var gun) ||
|
||||
!TryComp<GunComponent>(gunUid, out var gun) ||
|
||||
!TryGetGun(args.SenderSession.AttachedEntity.Value, out _, out var userGun))
|
||||
{
|
||||
return;
|
||||
@@ -151,7 +153,7 @@ public abstract partial class SharedGunSystem : EntitySystem
|
||||
if (userGun != gun)
|
||||
return;
|
||||
|
||||
StopShooting(ev.Gun, gun);
|
||||
StopShooting(gunUid, gun);
|
||||
}
|
||||
|
||||
public bool CanShoot(GunComponent component)
|
||||
@@ -432,7 +434,7 @@ public abstract partial class SharedGunSystem : EntitySystem
|
||||
if (sprite == null)
|
||||
return;
|
||||
|
||||
var ev = new MuzzleFlashEvent(gun, sprite, user == gun);
|
||||
var ev = new MuzzleFlashEvent(GetNetEntity(gun), sprite, user == gun);
|
||||
CreateEffect(gun, ev, user);
|
||||
}
|
||||
|
||||
@@ -454,7 +456,7 @@ public abstract partial class SharedGunSystem : EntitySystem
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class HitscanEvent : EntityEventArgs
|
||||
{
|
||||
public List<(EntityCoordinates coordinates, Angle angle, SpriteSpecifier Sprite, float Distance)> Sprites = new();
|
||||
public List<(NetCoordinates coordinates, Angle angle, SpriteSpecifier Sprite, float Distance)> Sprites = new();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user