Files
crystall-punk-14/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs
Red 963bdc022f Rethinking equipment (#1711)
* delete all modular content

* clean up

* Update guard.yml

* spear first pass

* Add imperial two-handed sword and update spear

Introduces the imperial two-handed sword with new sprites, prototype, and animations. Refines spear configuration: adjusts damage, animation, and offsets, and updates its sprites and prototype to use a new resource path. Improves melee weapon animation logic for both thrust and slash attacks.

* neck displacement

* Update neck.png

* Update migration.yml

* dagger

* Add sword prototype and refactor melee weapon swing logic

Introduces a new sword entity and associated textures. Refactors melee weapon swing logic by renaming SwingLeft to CPSwingLeft and updating related code. Adjusts animation offsets and rotation values for daggers, spears, and two-handed swords. Moves and updates dagger texture assets to a new directory structure.

* hatchet

* sickle

* Add skimitar sword entity and sprites

Introduced a new 'skimitar' sword entity with description and associated sprite assets, including icon, in-hand, and equipped states. Also updated the imperial sword's name and description for clarity.

* Add rapier weapon and adjust melee weapon balance

Introduced the imperial rapier weapon with associated prototype and textures. Increased the default single-target melee damage modifier to 1.3 and removed per-weapon clickDamageModifier overrides from dagger, spear, sword, and two-handed sword. Also increased sword base damage to 10 for better balance.

* Add iron tool/weapon variants and update wall thresholds

Introduces iron variants for pickaxe, shovel, dagger, rapier, spear, sword, and two-handed sword, including new sprites and YAML prototypes. Adjusts wall and ore vein damage thresholds for destruction and sound triggers. Updates migration.yml to map modular iron weapons to new iron variants and spawns stone blocks on stonebrick wall breakage. Also refactors dagger textures to use an 'iron' directory.

* Refactor ice dagger and adjust blacksmith skills

Replaced CP14IceDagger with CP14WeaponDaggerIce, updating its parent, stats, and components for consistency. Adjusted base dagger damage types. Blacksmith job and related melting skills are now commented out or disabled, reflecting a change in skill progression and job setup.

* Update ice_dagger.yml

* Deprecate sword mastery skills and update melee swing logic

Commented out SwordMastery, RapierMastery, and SkimitarMastery skills and removed their assignment from guard and artisan job prototypes. Renamed CPSwingLeft to SwingLeft in melee weapon code for clarity and updated related logic.

* Remove requiredSkills from anvil and furnace recipes

Eliminated the 'requiredSkills' field from all recipes in Anvil/misc.yml and furnace.yml. This simplifies recipe definitions and removes skill prerequisites for crafting these items.

* Update guard_commander.yml

* Comment out freeLearnedSkills for T1 and T2 skeletons

Disabled the freeLearnedSkills entries, including SwordMastery and SkimitarMastery, in both T1 and T2 DemiplaneAntag skeleton YAML prototypes. This change may be for balancing or testing purposes.

* Update migration.yml

* Update migration.yml

* guidebook

* r

* spear passive + hammer passive

* tool hammer + skimitar refactor

* balance tweak

* kick nerf

* TOWER DEFENCE UPDATE

* default shield refactor

* buckler (only sprites)

* Update migration.yml

* buckler parry

* some fixes

* Update T2.yml

* Update T2.yml

* Update instruments.yml

* Update migration.yml

* M O P

* war axe

* Update migration.yml

* Keen Eye skill

* arrows + bow + loadouts

* Update tools.yml

* trading

* fix

* Update misc.yml

* Update migration.yml
2025-09-06 00:59:58 +03:00

180 lines
6.0 KiB
C#

using Content.Shared.Damage;
using Content.Shared.FixedPoint;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Shared.Weapons.Melee;
/// <summary>
/// When given to a mob lets them do unarmed attacks, or when given to an item lets someone wield it to do attacks.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(fieldDeltas: true), AutoGenerateComponentPause]
public sealed partial class MeleeWeaponComponent : Component
{
// TODO: This is becoming bloated as shit.
// This should just be its own component for alt attacks.
/// <summary>
/// Does this entity do a disarm on alt attack.
/// </summary>
[DataField, AutoNetworkedField]
public bool AltDisarm = true;
/// <summary>
/// Should the melee weapon's damage stats be examinable.
/// </summary>
[DataField, AutoNetworkedField]
public bool Hidden;
/// <summary>
/// Next time this component is allowed to light attack. Heavy attacks are wound up and never have a cooldown.
/// </summary>
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField]
[AutoPausedField]
public TimeSpan NextAttack;
/// <summary>
/// Starts attack cooldown when equipped if true.
/// </summary>
[DataField, AutoNetworkedField]
public bool ResetOnHandSelected = true;
/*
* Melee combat works based around 2 types of attacks:
* 1. Click attacks with left-click. This attacks whatever is under your mnouse
* 2. Wide attacks with right-click + left-click. This attacks whatever is in the direction of your mouse.
*/
/// <summary>
/// How many times we can attack per second.
/// </summary>
[DataField, AutoNetworkedField]
public float AttackRate = 1f;
/// <summary>
/// Are we currently holding down the mouse for an attack.
/// Used so we can't just hold the mouse button and attack constantly.
/// </summary>
[AutoNetworkedField]
public bool Attacking = false;
/// <summary>
/// If true, attacks will be repeated automatically without requiring the mouse button to be lifted.
/// </summary>
[DataField, AutoNetworkedField]
public bool AutoAttack;
/// <summary>
/// If true, attacks will bypass armor resistances.
/// </summary>
[DataField, AutoNetworkedField]
public bool ResistanceBypass = false;
/// <summary>
/// Base damage for this weapon. Can be modified via heavy damage or other means.
/// </summary>
[DataField(required: true), AutoNetworkedField]
public DamageSpecifier Damage = default!;
[DataField, AutoNetworkedField]
public FixedPoint2 BluntStaminaDamageFactor = FixedPoint2.New(0.5f);
/// <summary>
/// Multiplies damage by this amount for single-target attacks.
/// </summary>
[DataField, AutoNetworkedField]
public FixedPoint2 ClickDamageModifier = FixedPoint2.New(1.3); //CP14 default bonus damage
// TODO: Temporarily 1.5 until interactionoutline is adjusted to use melee, then probably drop to 1.2
/// <summary>
/// Nearest edge range to hit an entity.
/// </summary>
[DataField, AutoNetworkedField]
public float Range = 1.5f;
/// <summary>
/// Total width of the angle for wide attacks.
/// </summary>
[DataField, AutoNetworkedField]
public Angle Angle = Angle.FromDegrees(60);
[DataField, AutoNetworkedField]
public EntProtoId Animation = "WeaponArcPunch";
[DataField, AutoNetworkedField]
public EntProtoId WideAnimation = "WeaponArcSlash";
/// <summary>
/// Rotation of the animation.
/// 0 degrees means the top faces the attacker.
/// </summary>
[DataField, AutoNetworkedField]
public Angle WideAnimationRotation = Angle.Zero;
[DataField, AutoNetworkedField]
public bool SwingLeft;
/// <summary>
/// CrystallEdge Melee upgrade. Allows each attack to take turns being either left or right
/// </summary>
[DataField]
public bool CPSwingBeverage = true;
/// <summary>
/// CrystallEdge Melee upgrade. Modifier of wide attack animation speed
/// </summary>
[DataField]
public float CPAnimationLength = 0.5f;
/// <summary>
/// CrystallEdge Melee upgrade. how far away from the player the animation should be played.
/// </summary>
[DataField]
public float CPAnimationOffset = 1f;
// Sounds
/// <summary>
/// This gets played whenever a melee attack is done. This is predicted by the client.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("soundSwing"), AutoNetworkedField]
public SoundSpecifier SwingSound { get; set; } = new SoundPathSpecifier("/Audio/Weapons/punchmiss.ogg")
{
Params = AudioParams.Default.WithVolume(-3f).WithVariation(0.025f),
};
// We do not predict the below sounds in case the client thinks but the server disagrees. If this were the case
// then a player may doubt if the target actually took damage or not.
// If overwatch and apex do this then we probably should too.
[ViewVariables(VVAccess.ReadWrite)]
[DataField("soundHit"), AutoNetworkedField]
public SoundSpecifier? HitSound;
/// <summary>
/// Plays if no damage is done to the target entity.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("soundNoDamage"), AutoNetworkedField]
public SoundSpecifier NoDamageSound { get; set; } = new SoundCollectionSpecifier("WeakHit");
/// <summary>
/// If true, the weapon must be equipped for it to be used.
/// E.g boxing gloves must be equipped to your gloves,
/// not just held in your hand to be used.
/// </summary>
[DataField, AutoNetworkedField]
public bool MustBeEquippedToUse = false;
}
/// <summary>
/// Event raised on entity in GetWeapon function to allow systems to manually
/// specify what the weapon should be.
/// </summary>
public sealed class GetMeleeWeaponEvent : HandledEntityEventArgs
{
public EntityUid? Weapon;
}