private void PlayWeaponArc(PlayMeleeWeaponAnimationMessage msg) { if (!_prototypeManager.TryIndex(msg.ArcPrototype, out MeleeWeaponAnimationPrototype? weaponArc)) { Logger.Error("Tried to play unknown weapon arc prototype '{0}'", msg.ArcPrototype); return; } var attacker = msg.Attacker; if (!EntityManager.EntityExists(msg.Attacker)) { // FIXME: This should never happen. Logger.Error($"Tried to play a weapon arc {msg.ArcPrototype}, but the attacker does not exist. attacker={msg.Attacker}, source={msg.Source}"); return; } if (!Deleted(attacker)) { var lunge = attacker.EnsureComponent <MeleeLungeComponent>(); lunge.SetData(msg.Angle); var entity = EntityManager.SpawnEntity(weaponArc.Prototype, EntityManager.GetComponent <TransformComponent>(attacker).Coordinates); EntityManager.GetComponent <TransformComponent>(entity).LocalRotation = msg.Angle; var weaponArcAnimation = EntityManager.GetComponent <MeleeWeaponArcAnimationComponent>(entity); weaponArcAnimation.SetData(weaponArc, msg.Angle, attacker, msg.ArcFollowAttacker); // Due to ISpriteComponent limitations, weapons that don't use an RSI won't have this effect. if (EntityManager.EntityExists(msg.Source) && msg.TextureEffect && EntityManager.TryGetComponent(msg.Source, out ISpriteComponent? sourceSprite) && sourceSprite.BaseRSI?.Path is { } path) { var curTime = _gameTiming.CurTime; var effect = new EffectSystemMessage { EffectSprite = path.ToString(), RsiState = sourceSprite.LayerGetState(0).Name, Coordinates = EntityManager.GetComponent <TransformComponent>(attacker).Coordinates, Color = Vector4.Multiply(new Vector4(255, 255, 255, 125), 1.0f), ColorDelta = Vector4.Multiply(new Vector4(0, 0, 0, -10), 1.0f), Velocity = msg.Angle.ToWorldVec(), Acceleration = msg.Angle.ToWorldVec() * 5f, Born = curTime, DeathTime = curTime.Add(TimeSpan.FromMilliseconds(300f)), }; _effectSystem.CreateEffect(effect); } } foreach (var hit in msg.Hits) { if (!EntityManager.EntityExists(hit)) { continue; } if (!EntityManager.TryGetComponent(hit, out ISpriteComponent? sprite)) { continue; } var originalColor = sprite.Color; var newColor = Color.Red * originalColor; sprite.Color = newColor; hit.SpawnTimer(100, () => { // Only reset back to the original color if something else didn't change the color in the mean time. if (sprite.Color == newColor) { sprite.Color = originalColor; } }); } }