diff --git a/Content.Server/Zombies/ZombieSystem.Transform.cs b/Content.Server/Zombies/ZombieSystem.Transform.cs
index b393850497..47d94984c0 100644
--- a/Content.Server/Zombies/ZombieSystem.Transform.cs
+++ b/Content.Server/Zombies/ZombieSystem.Transform.cs
@@ -132,6 +132,16 @@ public sealed partial class ZombieSystem
melee.Angle = 0.0f;
melee.HitSound = zombiecomp.BiteSound;
+ DirtyFields(target, melee, null, fields:
+ [
+ nameof(MeleeWeaponComponent.Animation),
+ nameof(MeleeWeaponComponent.WideAnimation),
+ nameof(MeleeWeaponComponent.AltDisarm),
+ nameof(MeleeWeaponComponent.Range),
+ nameof(MeleeWeaponComponent.Angle),
+ nameof(MeleeWeaponComponent.HitSound),
+ ]);
+
if (mobState.CurrentState == MobState.Alive)
{
// Groaning when damaged
diff --git a/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs b/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs
index 212c03475c..84e88156ad 100644
--- a/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs
+++ b/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs
@@ -10,7 +10,7 @@ namespace Content.Shared.Weapons.Melee;
///
/// When given to a mob lets them do unarmed attacks, or when given to an item lets someone wield it to do attacks.
///
-[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, AutoGenerateComponentPause]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(fieldDeltas: true), AutoGenerateComponentPause]
public sealed partial class MeleeWeaponComponent : Component
{
// TODO: This is becoming bloated as shit.
@@ -18,28 +18,26 @@ public sealed partial class MeleeWeaponComponent : Component
///
/// Does this entity do a disarm on alt attack.
///
- [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
+ [DataField, AutoNetworkedField]
public bool AltDisarm = true;
///
/// Should the melee weapon's damage stats be examinable.
///
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField]
+ [DataField, AutoNetworkedField]
public bool Hidden;
///
/// Next time this component is allowed to light attack. Heavy attacks are wound up and never have a cooldown.
///
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField]
- [ViewVariables(VVAccess.ReadWrite)]
[AutoPausedField]
public TimeSpan NextAttack;
///
/// Starts attack cooldown when equipped if true.
///
- [ViewVariables(VVAccess.ReadWrite), DataField]
+ [DataField, AutoNetworkedField]
public bool ResetOnHandSelected = true;
/*
@@ -51,72 +49,70 @@ public sealed partial class MeleeWeaponComponent : Component
///
/// How many times we can attack per second.
///
- [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
+ [DataField, AutoNetworkedField]
public float AttackRate = 1f;
///
/// Are we currently holding down the mouse for an attack.
/// Used so we can't just hold the mouse button and attack constantly.
///
- [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
+ [AutoNetworkedField]
public bool Attacking = false;
///
/// If true, attacks will be repeated automatically without requiring the mouse button to be lifted.
///
- [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
+ [DataField, AutoNetworkedField]
public bool AutoAttack;
///
/// If true, attacks will bypass armor resistances.
///
- [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
+ [DataField, AutoNetworkedField]
public bool ResistanceBypass = false;
-
+
///
/// Base damage for this weapon. Can be modified via heavy damage or other means.
///
- [DataField(required: true)]
- [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
+ [DataField(required: true), AutoNetworkedField]
public DamageSpecifier Damage = default!;
- [DataField]
- [ViewVariables(VVAccess.ReadWrite)]
+ [DataField, AutoNetworkedField]
public FixedPoint2 BluntStaminaDamageFactor = FixedPoint2.New(0.5f);
///
/// Multiplies damage by this amount for single-target attacks.
///
- [ViewVariables(VVAccess.ReadWrite), DataField]
+ [DataField, AutoNetworkedField]
public FixedPoint2 ClickDamageModifier = FixedPoint2.New(1);
// TODO: Temporarily 1.5 until interactionoutline is adjusted to use melee, then probably drop to 1.2
///
/// Nearest edge range to hit an entity.
///
- [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
+ [DataField, AutoNetworkedField]
public float Range = 1.5f;
///
/// Total width of the angle for wide attacks.
///
- [ViewVariables(VVAccess.ReadWrite), DataField]
+ [DataField, AutoNetworkedField]
public Angle Angle = Angle.FromDegrees(60);
- [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
+ [DataField, AutoNetworkedField]
public EntProtoId Animation = "WeaponArcPunch";
- [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
+ [DataField, AutoNetworkedField]
public EntProtoId WideAnimation = "WeaponArcSlash";
///
/// Rotation of the animation.
/// 0 degrees means the top faces the attacker.
///
- [ViewVariables(VVAccess.ReadWrite), DataField]
+ [DataField, AutoNetworkedField]
public Angle WideAnimationRotation = Angle.Zero;
- [ViewVariables(VVAccess.ReadWrite), DataField]
+ [DataField, AutoNetworkedField]
public bool SwingLeft;
diff --git a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs
index 43be9a5b14..947c969a3e 100644
--- a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs
+++ b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs
@@ -104,7 +104,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
if (gun.NextFire > component.NextAttack)
{
component.NextAttack = gun.NextFire;
- Dirty(uid, component);
+ DirtyField(uid, component, nameof(MeleeWeaponComponent.NextAttack));
}
}
@@ -128,7 +128,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
return;
component.NextAttack = minimum;
- Dirty(uid, component);
+ DirtyField(uid, component, nameof(MeleeWeaponComponent.NextAttack));
}
private void OnGetBonusMeleeDamage(EntityUid uid, BonusMeleeDamageComponent component, ref GetMeleeDamageEvent args)
@@ -168,7 +168,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
return;
weapon.Attacking = false;
- Dirty(weaponUid, weapon);
+ DirtyField(weaponUid, weapon, nameof(MeleeWeaponComponent.Attacking));
}
private void OnLightAttack(LightAttackEvent msg, EntitySessionEventArgs args)
@@ -392,7 +392,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
swings++;
}
- Dirty(weaponUid, weapon);
+ DirtyField(weaponUid, weapon, nameof(MeleeWeaponComponent.NextAttack));
// Do this AFTER attack so it doesn't spam every tick
var ev = new AttemptMeleeEvent();
@@ -442,6 +442,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
RaiseLocalEvent(user, ref attackEv);
weapon.Attacking = true;
+ DirtyField(weaponUid, weapon, nameof(MeleeWeaponComponent.Attacking));
return true;
}
@@ -838,15 +839,21 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
//Setting deactivated damage to the weapon's regular value before changing it.
itemToggleMelee.DeactivatedDamage ??= meleeWeapon.Damage;
meleeWeapon.Damage = itemToggleMelee.ActivatedDamage;
+ DirtyField(uid, meleeWeapon, nameof(MeleeWeaponComponent.Damage));
}
- meleeWeapon.HitSound = itemToggleMelee.ActivatedSoundOnHit;
+ if (meleeWeapon.HitSound?.Equals(itemToggleMelee.ActivatedSoundOnHit) != true)
+ {
+ meleeWeapon.HitSound = itemToggleMelee.ActivatedSoundOnHit;
+ DirtyField(uid, meleeWeapon, nameof(MeleeWeaponComponent.HitSound));
+ }
if (itemToggleMelee.ActivatedSoundOnHitNoDamage != null)
{
//Setting the deactivated sound on no damage hit to the weapon's regular value before changing it.
itemToggleMelee.DeactivatedSoundOnHitNoDamage ??= meleeWeapon.NoDamageSound;
meleeWeapon.NoDamageSound = itemToggleMelee.ActivatedSoundOnHitNoDamage;
+ DirtyField(uid, meleeWeapon, nameof(MeleeWeaponComponent.NoDamageSound));
}
if (itemToggleMelee.ActivatedSoundOnSwing != null)
@@ -854,28 +861,41 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
//Setting the deactivated sound on no damage hit to the weapon's regular value before changing it.
itemToggleMelee.DeactivatedSoundOnSwing ??= meleeWeapon.SwingSound;
meleeWeapon.SwingSound = itemToggleMelee.ActivatedSoundOnSwing;
+ DirtyField(uid, meleeWeapon, nameof(MeleeWeaponComponent.SwingSound));
}
if (itemToggleMelee.DeactivatedSecret)
+ {
meleeWeapon.Hidden = false;
+ }
}
else
{
if (itemToggleMelee.DeactivatedDamage != null)
+ {
meleeWeapon.Damage = itemToggleMelee.DeactivatedDamage;
+ DirtyField(uid, meleeWeapon, nameof(MeleeWeaponComponent.Damage));
+ }
meleeWeapon.HitSound = itemToggleMelee.DeactivatedSoundOnHit;
+ DirtyField(uid, meleeWeapon, nameof(MeleeWeaponComponent.HitSound));
if (itemToggleMelee.DeactivatedSoundOnHitNoDamage != null)
+ {
meleeWeapon.NoDamageSound = itemToggleMelee.DeactivatedSoundOnHitNoDamage;
+ DirtyField(uid, meleeWeapon, nameof(MeleeWeaponComponent.NoDamageSound));
+ }
if (itemToggleMelee.DeactivatedSoundOnSwing != null)
+ {
meleeWeapon.SwingSound = itemToggleMelee.DeactivatedSoundOnSwing;
+ DirtyField(uid, meleeWeapon, nameof(MeleeWeaponComponent.SwingSound));
+ }
if (itemToggleMelee.DeactivatedSecret)
+ {
meleeWeapon.Hidden = true;
+ }
}
-
- Dirty(uid, meleeWeapon);
}
}