Proto-kinetic crusher (#16277)
Co-authored-by: AJCM-git <60196617+AJCM-git@users.noreply.github.com>
This commit is contained in:
@@ -15,6 +15,8 @@ using Content.Shared.Physics;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Weapons.Melee.Components;
|
||||
using Content.Shared.Weapons.Melee.Events;
|
||||
using Content.Shared.Weapons.Ranged.Components;
|
||||
using Content.Shared.Weapons.Ranged.Systems;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Collections;
|
||||
using Robust.Shared.GameStates;
|
||||
@@ -70,6 +72,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
SubscribeLocalEvent<MeleeWeaponComponent, ComponentHandleState>(OnHandleState);
|
||||
SubscribeLocalEvent<MeleeWeaponComponent, HandDeselectedEvent>(OnMeleeDropped);
|
||||
SubscribeLocalEvent<MeleeWeaponComponent, HandSelectedEvent>(OnMeleeSelected);
|
||||
SubscribeLocalEvent<MeleeWeaponComponent, GunShotEvent>(OnMeleeShot);
|
||||
|
||||
SubscribeAllEvent<HeavyAttackEvent>(OnHeavyAttack);
|
||||
SubscribeAllEvent<LightAttackEvent>(OnLightAttack);
|
||||
@@ -89,6 +92,18 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
#endif
|
||||
}
|
||||
|
||||
private void OnMeleeShot(EntityUid uid, MeleeWeaponComponent component, ref GunShotEvent args)
|
||||
{
|
||||
if (!TryComp<GunComponent>(uid, out var gun))
|
||||
return;
|
||||
|
||||
if (gun.NextFire > component.NextAttack)
|
||||
{
|
||||
component.NextAttack = gun.NextFire;
|
||||
Dirty(component);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMeleeUnpaused(EntityUid uid, MeleeWeaponComponent component, ref EntityUnpausedEvent args)
|
||||
{
|
||||
component.NextAttack += args.PausedTime;
|
||||
@@ -356,38 +371,64 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
}
|
||||
|
||||
// Windup time checked elsewhere.
|
||||
var fireRate = TimeSpan.FromSeconds(1f / weapon.AttackRate);
|
||||
var swings = 0;
|
||||
|
||||
// TODO: If we get autoattacks then probably need a shotcounter like guns so we can do timing properly.
|
||||
if (weapon.NextAttack < curTime)
|
||||
weapon.NextAttack = curTime;
|
||||
|
||||
weapon.NextAttack += TimeSpan.FromSeconds(1f / weapon.AttackRate);
|
||||
|
||||
// Attack confirmed
|
||||
string animation;
|
||||
|
||||
switch (attack)
|
||||
while (weapon.NextAttack <= curTime)
|
||||
{
|
||||
case LightAttackEvent light:
|
||||
DoLightAttack(user, light, weaponUid, weapon, session);
|
||||
animation = weapon.ClickAnimation;
|
||||
break;
|
||||
case DisarmAttackEvent disarm:
|
||||
if (!DoDisarm(user, disarm, weaponUid, weapon, session))
|
||||
return;
|
||||
|
||||
animation = weapon.ClickAnimation;
|
||||
break;
|
||||
case HeavyAttackEvent heavy:
|
||||
DoHeavyAttack(user, heavy, weaponUid, weapon, session);
|
||||
animation = weapon.WideAnimation;
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
weapon.NextAttack += fireRate;
|
||||
swings++;
|
||||
}
|
||||
|
||||
DoLungeAnimation(user, weapon.Angle, attack.Coordinates.ToMap(EntityManager, TransformSystem), weapon.Range, animation);
|
||||
weapon.Attacking = true;
|
||||
Dirty(weapon);
|
||||
|
||||
// Do this AFTER attack so it doesn't spam every tick
|
||||
var ev = new AttemptMeleeEvent();
|
||||
RaiseLocalEvent(weaponUid, ref ev);
|
||||
|
||||
if (ev.Cancelled)
|
||||
{
|
||||
if (ev.Message != null)
|
||||
{
|
||||
PopupSystem.PopupClient(ev.Message, weaponUid, user);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Attack confirmed
|
||||
for (var i = 0; i < swings; i++)
|
||||
{
|
||||
string animation;
|
||||
|
||||
switch (attack)
|
||||
{
|
||||
case LightAttackEvent light:
|
||||
DoLightAttack(user, light, weaponUid, weapon, session);
|
||||
animation = weapon.ClickAnimation;
|
||||
break;
|
||||
case DisarmAttackEvent disarm:
|
||||
if (!DoDisarm(user, disarm, weaponUid, weapon, session))
|
||||
return;
|
||||
|
||||
animation = weapon.ClickAnimation;
|
||||
break;
|
||||
case HeavyAttackEvent heavy:
|
||||
DoHeavyAttack(user, heavy, weaponUid, weapon, session);
|
||||
animation = weapon.WideAnimation;
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
DoLungeAnimation(user, weapon.Angle, attack.Coordinates.ToMap(EntityManager, TransformSystem), weapon.Range, animation);
|
||||
}
|
||||
|
||||
weapon.Attacking = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -469,9 +510,10 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
Interaction.DoContactInteraction(user, ev.Target);
|
||||
|
||||
// For stuff that cares about it being attacked.
|
||||
RaiseLocalEvent(ev.Target.Value, new AttackedEvent(meleeUid, user, targetXform.Coordinates));
|
||||
var attackedEvent = new AttackedEvent(meleeUid, user, targetXform.Coordinates);
|
||||
RaiseLocalEvent(ev.Target.Value, attackedEvent);
|
||||
|
||||
var modifiedDamage = DamageSpecifier.ApplyModifierSets(damage + hitEvent.BonusDamage, hitEvent.ModifiersList);
|
||||
var modifiedDamage = DamageSpecifier.ApplyModifierSets(damage + hitEvent.BonusDamage + attackedEvent.BonusDamage, hitEvent.ModifiersList);
|
||||
var damageResult = Damageable.TryChangeDamage(ev.Target, modifiedDamage, origin:user);
|
||||
|
||||
if (damageResult != null && damageResult.Total > FixedPoint2.Zero)
|
||||
@@ -596,16 +638,15 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
// 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.
|
||||
Interaction.DoContactInteraction(user, target);
|
||||
|
||||
RaiseLocalEvent(target, new AttackedEvent(meleeUid, user, Transform(target).Coordinates));
|
||||
}
|
||||
|
||||
var modifiedDamage = DamageSpecifier.ApplyModifierSets(damage + hitEvent.BonusDamage, hitEvent.ModifiersList);
|
||||
var appliedDamage = new DamageSpecifier();
|
||||
|
||||
foreach (var entity in targets)
|
||||
{
|
||||
RaiseLocalEvent(entity, new AttackedEvent(meleeUid, user, ev.Coordinates));
|
||||
var attackedEvent = new AttackedEvent(meleeUid, user, ev.Coordinates);
|
||||
RaiseLocalEvent(entity, attackedEvent);
|
||||
var modifiedDamage = DamageSpecifier.ApplyModifierSets(damage + hitEvent.BonusDamage + attackedEvent.BonusDamage, hitEvent.ModifiersList);
|
||||
|
||||
var damageResult = Damageable.TryChangeDamage(entity, modifiedDamage, origin:user);
|
||||
|
||||
@@ -631,7 +672,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
if (appliedDamage.Total > FixedPoint2.Zero)
|
||||
{
|
||||
var target = entities.First();
|
||||
PlayHitSound(target, user, GetHighestDamageSound(modifiedDamage, _protoManager), hitEvent.HitSoundOverride, component.HitSound);
|
||||
PlayHitSound(target, user, GetHighestDamageSound(appliedDamage, _protoManager), hitEvent.HitSoundOverride, component.HitSound);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user