using System.Collections.Generic; using Content.Server.GameObjects.Components.Mobs; using Content.Shared.GameObjects; using Robust.Server.GameObjects; using Robust.Shared.GameObjects; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.GameObjects.Components; using Content.Server.GameObjects.Components.Mobs; using Content.Shared.GameObjects; using Robust.Shared.Log; using Robust.Shared.Serialization; using Robust.Shared.Interfaces.Physics; namespace Content.Server.GameObjects.Components.Projectiles { [RegisterComponent] public class ProjectileComponent : Component, ICollideSpecial, ICollideBehavior { public override string Name => "Projectile"; public bool IgnoreShooter = true; private EntityUid Shooter = EntityUid.Invalid; private Dictionary _damages; [ViewVariables] public Dictionary Damages => _damages; private float _velocity; public float Velocity { get => _velocity; set => _velocity = value; } public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); // If not specified 0 damage serializer.DataField(ref _damages, "damages", new Dictionary()); serializer.DataField(ref _velocity, "velocity", 20f); } public float TimeLeft { get; set; } = 10; /// /// Function that makes the collision of this object ignore a specific entity so we don't collide with ourselves /// /// public void IgnoreEntity(IEntity shooter) { Shooter = shooter.Uid; } /// /// Special collision override, can be used to give custom behaviors deciding when to collide /// /// /// bool ICollideSpecial.PreventCollide(ICollidable collidedwith) { if (IgnoreShooter && collidedwith.Owner.Uid == Shooter) return true; return false; } /// /// Applys the damage when our projectile collides with its victim /// /// void ICollideBehavior.CollideWith(List collidedwith) { foreach (var entity in collidedwith) { if (entity.TryGetComponent(out DamageableComponent damage)) { foreach (var damageType in _damages) { damage.TakeDamage(damageType.Key, damageType.Value); } } if (entity.TryGetComponent(out CameraRecoilComponent recoilComponent) && Owner.TryGetComponent(out PhysicsComponent physicsComponent)) { var direction = physicsComponent.LinearVelocity.Normalized; recoilComponent.Kick(direction); } } if (collidedwith.Count > 0) { Owner.Delete(); } } } }