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); } }