private void OnHandSelected(EntityUid uid, MeleeWeaponComponent comp, HandSelectedEvent args) { var curTime = _gameTiming.CurTime; var cool = TimeSpan.FromSeconds(comp.CooldownTime * 0.5f); if (curTime < comp.CooldownEnd) { if (comp.CooldownEnd - curTime < cool) { comp.LastAttackTime = curTime; comp.CooldownEnd += cool; } else { return; } } else { comp.LastAttackTime = curTime; comp.CooldownEnd = curTime + cool; } RaiseLocalEvent(uid, new RefreshItemCooldownEvent(comp.LastAttackTime, comp.CooldownEnd), false); }
private void OnClickAttack(EntityUid owner, MeleeWeaponComponent comp, ClickAttackEvent args) { args.Handled = true; var curTime = _gameTiming.CurTime; if (curTime < comp.CooldownEnd || args.Target == null) { return; } var location = EntityManager.GetComponent <TransformComponent>(args.User).Coordinates; var diff = args.ClickLocation.ToMapPos(EntityManager) - location.ToMapPos(EntityManager); var angle = Angle.FromWorldVec(diff); if (args.Target is { Valid : true } target) { // Raise event before doing damage so we can cancel damage if the event is handled var hitEvent = new MeleeHitEvent(new List <EntityUid>() { target }, args.User); RaiseLocalEvent(owner, hitEvent, false); if (!hitEvent.Handled) { var targets = new[] { target }; SendAnimation(comp.ClickArc, angle, args.User, owner, targets, comp.ClickAttackEffect, false); RaiseLocalEvent(target, new AttackedEvent(args.Used, args.User, args.ClickLocation)); var modifiedDamage = DamageSpecifier.ApplyModifierSets(comp.Damage + hitEvent.BonusDamage, hitEvent.ModifiersList); var damageResult = _damageableSystem.TryChangeDamage(target, modifiedDamage); if (damageResult != null) { if (args.Used == args.User) { _logSystem.Add(LogType.MeleeHit, $"{ToPrettyString(args.User):user} melee attacked {ToPrettyString(args.Target.Value):target} using their hands and dealt {damageResult.Total:damage} damage"); } else { _logSystem.Add(LogType.MeleeHit, $"{ToPrettyString(args.User):user} melee attacked {ToPrettyString(args.Target.Value):target} using {ToPrettyString(args.Used):used} and dealt {damageResult.Total:damage} damage"); } } if (hitEvent.HitSoundOverride != null) { SoundSystem.Play(Filter.Pvs(owner), hitEvent.HitSoundOverride.GetSound(), target, AudioHelpers.WithVariation(0.25f)); } else { SoundSystem.Play(Filter.Pvs(owner), comp.HitSound.GetSound(), target); } } }
private void OnClickAttack(EntityUid uid, MeleeWeaponComponent comp, ClickAttackEvent args) { args.Handled = true; var curTime = _gameTiming.CurTime; if (curTime < comp.CooldownEnd || !args.Target.IsValid()) { return; } var owner = EntityManager.GetEntity(uid); var target = args.TargetEntity; var location = args.User.Transform.Coordinates; var diff = args.ClickLocation.ToMapPos(owner.EntityManager) - location.ToMapPos(owner.EntityManager); var angle = Angle.FromWorldVec(diff); if (target != null) { // Raise event before doing damage so we can cancel damage if the event is handled var hitEvent = new MeleeHitEvent(new List <IEntity>() { target }, args.User); RaiseLocalEvent(uid, hitEvent, false); if (!hitEvent.Handled) { var targets = new[] { target }; SendAnimation(comp.ClickArc, angle, args.User, owner, targets, comp.ClickAttackEffect, false); if (target.TryGetComponent(out IDamageableComponent? damageableComponent)) { damageableComponent.TryChangeDamage(comp.DamageType, comp.Damage); } SoundSystem.Play(Filter.Pvs(owner), comp.HitSound.GetSound(), target); } } else { SoundSystem.Play(Filter.Pvs(owner), comp.MissSound.GetSound(), args.User); return; } comp.LastAttackTime = curTime; comp.CooldownEnd = comp.LastAttackTime + TimeSpan.FromSeconds(comp.CooldownTime); RaiseLocalEvent(uid, new RefreshItemCooldownEvent(comp.LastAttackTime, comp.CooldownEnd), false); }
/// <summary> /// Used for melee weapons that want some behavior on AfterInteract, /// but also want the cooldown (stun batons, flashes) /// </summary> private void OnAfterInteract(EntityUid uid, MeleeWeaponComponent comp, AfterInteractEvent args) { if (!args.CanReach) { return; } var curTime = _gameTiming.CurTime; if (curTime < comp.CooldownEnd) { return; } var owner = EntityManager.GetEntity(uid); if (args.Target == null) { return; } var location = args.User.Transform.Coordinates; var diff = args.ClickLocation.ToMapPos(owner.EntityManager) - location.ToMapPos(owner.EntityManager); var angle = Angle.FromWorldVec(diff); var hitEvent = new MeleeInteractEvent(args.Target, args.User); RaiseLocalEvent(uid, hitEvent, false); if (!hitEvent.CanInteract) { return; } SendAnimation(comp.ClickArc, angle, args.User, owner, new List <IEntity>() { args.Target }, comp.ClickAttackEffect, false); comp.LastAttackTime = curTime; comp.CooldownEnd = comp.LastAttackTime + TimeSpan.FromSeconds(comp.CooldownTime); RaiseLocalEvent(uid, new RefreshItemCooldownEvent(comp.LastAttackTime, comp.CooldownEnd), false); }
private void OnWideAttack(EntityUid uid, MeleeWeaponComponent comp, WideAttackEvent args) { args.Handled = true; var curTime = _gameTiming.CurTime; if (curTime < comp.CooldownEnd) { return; } var owner = EntityManager.GetEntity(uid); var location = args.User.Transform.Coordinates; var diff = args.ClickLocation.ToMapPos(owner.EntityManager) - location.ToMapPos(owner.EntityManager); var angle = Angle.FromWorldVec(diff); // This should really be improved. GetEntitiesInArc uses pos instead of bounding boxes. var entities = ArcRayCast(args.User.Transform.WorldPosition, angle, comp.ArcWidth, comp.Range, owner.Transform.MapID, args.User); var hitEntities = new List <IEntity>(); foreach (var entity in entities) { if (!entity.Transform.IsMapTransform || entity == args.User) { continue; } if (ComponentManager.HasComponent <IDamageableComponent>(entity.Uid)) { hitEntities.Add(entity); } } // Raise event before doing damage so we can cancel damage if handled var hitEvent = new MeleeHitEvent(hitEntities, args.User); RaiseLocalEvent(uid, hitEvent, false); SendAnimation(comp.Arc, angle, args.User, owner, hitEntities); if (!hitEvent.Handled) { if (entities.Count != 0) { SoundSystem.Play(Filter.Pvs(owner), comp.HitSound.GetSound(), entities.First().Transform.Coordinates); } else { SoundSystem.Play(Filter.Pvs(owner), comp.MissSound.GetSound(), args.User.Transform.Coordinates); } foreach (var entity in hitEntities) { if (entity.TryGetComponent <IDamageableComponent>(out var damageComponent)) { damageComponent.TryChangeDamage(comp.DamageType, comp.Damage); } } } comp.LastAttackTime = curTime; comp.CooldownEnd = comp.LastAttackTime + TimeSpan.FromSeconds(comp.ArcCooldownTime); RaiseLocalEvent(uid, new RefreshItemCooldownEvent(comp.LastAttackTime, comp.CooldownEnd), false); }