public void CreateEffect(EffectSystemMessage message) { if (message.AttachedEntityUid != null && message.Coordinates != default) { Logger.Warning("Set both an AttachedEntityUid and EntityCoordinates on an EffectSystemMessage for sprite {0} which is not supported!", message.EffectSprite); } var gameTime = gameTiming.CurTime; if (gameTime > message.DeathTime) //Did we already die in transit? That's pretty troubling isn't it { Logger.Warning("Effect using sprite {0} died in transit to the client", message.EffectSprite); return; } //Create effect from creation message var effect = new Effect(message, resourceCache, _mapManager, _entityManager); if (effect.AttachedEntityUid != null) { effect.AttachedEntity = _entityManager.GetEntity(effect.AttachedEntityUid.Value); } //Age the effect through a single update to the previous update tick of the effect system //effect.Update((float)((lasttimeprocessed - effect.Age).TotalSeconds)); _Effects.Add(effect); }
protected void MuzzleFlash(EntityUid gun, AmmoComponent component, EntityUid?user = null) { var sprite = component.MuzzleFlash?.ToString(); // TODO: AAAAA THIS MUZZLE FLASH CODE IS BAD // NEEDS EFFECTS TO NOT BE BAD! if (sprite == null) { return; } var time = Timing.CurTime; var deathTime = time + TimeSpan.FromSeconds(MuzzleFlashLifetime); // Offset the sprite so it actually looks like it's coming from the gun var offset = new Vector2(0.0f, -0.5f); var message = new EffectSystemMessage { EffectSprite = sprite, Born = time, DeathTime = deathTime, AttachedEntityUid = gun, AttachedOffset = offset, //Rotated from east facing Rotation = -MathF.PI / 2f, Color = Vector4.Multiply(new Vector4(255, 255, 255, 255), 1.0f), ColorDelta = new Vector4(0, 0, 0, -1500f), Shaded = false }; CreateEffect(message, user); }
public void MuzzleFlash(EntityUid entity, Angle angle) { if (_muzzleFlashSprite == null) { return; } var time = _gameTiming.CurTime; var deathTime = time + TimeSpan.FromMilliseconds(200); // Offset the sprite so it actually looks like it's coming from the gun var offset = angle.ToVec().Normalized / 2; var message = new EffectSystemMessage { EffectSprite = _muzzleFlashSprite, Born = time, DeathTime = deathTime, AttachedEntityUid = entity, AttachedOffset = offset, //Rotated from east facing Rotation = (float)angle.Theta, Color = Vector4.Multiply(new Vector4(255, 255, 255, 255), 1.0f), ColorDelta = new Vector4(0, 0, 0, -1500f), Shaded = false }; EntitySystem.Get <EffectSystem>().CreateParticle(message); }
public void CreateEffect(EffectSystemMessage message) { var gametime = gameTiming.CurTime; /* * // TODO: Fix this, it doesn't work. Probably because CurTime isn't synchronized with the server. * if (gametime > message.DeathTime) //Did we already die in transit? That's pretty troubling isn't it * { * Logger.Warning(string.Format("Effect using sprite {0} died in transit to the client", message.EffectSprite), message); * return; * } */ //Create effect from creation message var effect = new Effect(message, resourceCache); //Remove this effect.Age = gametime; effect.Deathtime = effect.Age + TimeSpan.FromSeconds(4); //Age the effect through a single update to the previous update tick of the effect system //effect.Update((float)((lasttimeprocessed - effect.Age).TotalSeconds)); _Effects.Add(effect); }
public void CreateParticle(EffectSystemMessage effect) { _CurrentEffects.Add(effect); //For now we will use this which sends to ALL clients //TODO: Client bubbling RaiseNetworkEvent(effect); }
protected override void CreateEffect(EffectSystemMessage message, EntityUid?user = null) { // TODO: F*****g bad if (TryComp <ActorComponent>(user, out var actor)) { _effects.CreateParticle(message, actor.PlayerSession); } else { _effects.CreateParticle(message); } }
public void MuzzleFlash(EntityUid entity, AmmoComponent component, Angle angle) { if (component.MuzzleFlashSprite == null) { return; } var time = _gameTiming.CurTime; var deathTime = time + TimeSpan.FromMilliseconds(200); // Offset the sprite so it actually looks like it's coming from the gun var offset = new Vector2(0.0f, -0.5f); var message = new EffectSystemMessage { EffectSprite = component.MuzzleFlashSprite.ToString(), Born = time, DeathTime = deathTime, AttachedEntityUid = entity, AttachedOffset = offset, //Rotated from east facing Rotation = -MathF.PI / 2f, Color = Vector4.Multiply(new Vector4(255, 255, 255, 255), 1.0f), ColorDelta = new Vector4(0, 0, 0, -1500f), Shaded = false }; /* TODO: Fix rotation when shooting sideways. This was the closest I got but still had issues. * var time = _gameTiming.CurTime; * var deathTime = time + TimeSpan.FromMilliseconds(200); * var entityRotation = EntityManager.GetComponent<TransformComponent>(entity).WorldRotation; * var localAngle = entityRotation - (angle + MathF.PI / 2f); * // Offset the sprite so it actually looks like it's coming from the gun * var offset = localAngle.RotateVec(new Vector2(0.0f, -0.5f)); * * var message = new EffectSystemMessage * { * EffectSprite = component.MuzzleFlashSprite.ToString(), * Born = time, * DeathTime = deathTime, * AttachedEntityUid = entity, * AttachedOffset = offset, * //Rotated from east facing * Rotation = (float) (localAngle - MathF.PI / 2), * Color = Vector4.Multiply(new Vector4(255, 255, 255, 255), 1.0f), * ColorDelta = new Vector4(0, 0, 0, -1500f), * Shaded = false * }; */ _effects.CreateParticle(message); }
/// <summary> /// Creates a particle effect and sends it to clients. /// </summary> /// <param name="effect"></param> /// <param name="excludedSession">Session to be excluded for prediction</param> public void CreateParticle(EffectSystemMessage effect, IPlayerSession?excludedSession = null) { _CurrentEffects.Add(effect); //For now we will use this which sends to ALL clients //TODO: Client bubbling foreach (var player in _playerManager.GetAllPlayers()) { if (player.Status != SessionStatus.InGame || player == excludedSession) { continue; } RaiseNetworkEvent(effect, player.ConnectedClient); } }
public void CreateEffect(EffectSystemMessage message) { var gameTime = gameTiming.CurTime; if (gameTime > message.DeathTime) //Did we already die in transit? That's pretty troubling isn't it { Logger.Warning("Effect using sprite {0} died in transit to the client", message.EffectSprite); return; } //Create effect from creation message var effect = new Effect(message, resourceCache, _mapManager); //Age the effect through a single update to the previous update tick of the effect system //effect.Update((float)((lasttimeprocessed - effect.Age).TotalSeconds)); _Effects.Add(effect); }
private EffectSystemMessage AfterEffects(EntityCoordinates origin, Angle angle, float distance, float offset = 0.0f) { var midPointOffset = angle.ToVec() * distance / 2; var message = new EffectSystemMessage { EffectSprite = _spriteName, Born = _startTime, DeathTime = _deathTime, Size = new Vector2(distance - offset, 1f), Coordinates = origin.Offset(midPointOffset), //Rotated from east facing Rotation = (float)angle.Theta, Color = Vector4.Multiply(new Vector4(255, 255, 255, 750), ColorModifier), ColorDelta = new Vector4(0, 0, 0, -1500f), Shaded = false }; return(message); }
protected virtual void AfterEffects(IEntity user, RayCastResults ray, Angle angle) { var time = IoCManager.Resolve <IGameTiming>().CurTime; var offset = angle.ToVec() * ray.Distance / 2; EffectSystemMessage message = new EffectSystemMessage { EffectSprite = spritename, Born = time, DeathTime = time + TimeSpan.FromSeconds(1), Size = new Vector2(ray.Distance, 1f), Coordinates = user.GetComponent <TransformComponent>().LocalPosition.Translated(offset), //Rotated from east facing Rotation = (float)angle.Theta, ColorDelta = new Vector4(0, 0, 0, -1500f), Color = new Vector4(255, 255, 255, 750), Shaded = false }; IoCManager.Resolve <IEntitySystemManager>().GetEntitySystem <EffectSystem>().CreateParticle(message); }
public Effect(EffectSystemMessage effectcreation, IResourceCache resourceCache) { EffectSprite = resourceCache.GetResource <TextureResource>(new ResourcePath("/Textures/") / effectcreation.EffectSprite).Texture; Coordinates = effectcreation.Coordinates; EmitterCoordinates = effectcreation.EmitterCoordinates; Velocity = effectcreation.Velocity; Acceleration = effectcreation.Acceleration; RadialVelocity = effectcreation.RadialVelocity; RadialAcceleration = effectcreation.RadialAcceleration; TangentialVelocity = effectcreation.TangentialVelocity; TangentialAcceleration = effectcreation.TangentialAcceleration; Age = effectcreation.Born; Deathtime = effectcreation.DeathTime; Rotation = effectcreation.Rotation; RotationRate = effectcreation.RotationRate; Size = effectcreation.Size; SizeDelta = effectcreation.SizeDelta; Color = effectcreation.Color; ColorDelta = effectcreation.ColorDelta; Shaded = effectcreation.Shaded; }
public Effect(EffectSystemMessage effectcreation, IResourceCache resourceCache, IMapManager mapManager, IEntityManager entityManager) { if (effectcreation.RsiState != null) { var rsi = resourceCache .GetResource <RSIResource>(new ResourcePath("/Textures/") / effectcreation.EffectSprite) .RSI; RsiState = rsi[effectcreation.RsiState]; EffectSprite = RsiState.Frame0; } else { EffectSprite = resourceCache .GetResource <TextureResource>(new ResourcePath("/Textures/") / effectcreation.EffectSprite) .Texture; } AnimationLoops = effectcreation.AnimationLoops; AttachedEntityUid = effectcreation.AttachedEntityUid; AttachedOffset = effectcreation.AttachedOffset; Coordinates = effectcreation.Coordinates; EmitterCoordinates = effectcreation.EmitterCoordinates; Velocity = effectcreation.Velocity; Acceleration = effectcreation.Acceleration; RadialVelocity = effectcreation.RadialVelocity; RadialAcceleration = effectcreation.RadialAcceleration; TangentialVelocity = effectcreation.TangentialVelocity; TangentialAcceleration = effectcreation.TangentialAcceleration; Age = effectcreation.Born; Deathtime = effectcreation.DeathTime; Rotation = effectcreation.Rotation; RotationRate = effectcreation.RotationRate; Size = effectcreation.Size; SizeDelta = effectcreation.SizeDelta; Color = effectcreation.Color; ColorDelta = effectcreation.ColorDelta; Shaded = effectcreation.Shaded; _mapManager = mapManager; _entityManager = entityManager; }
private EffectSystemMessage?ImpactFlash(float distance, Angle angle) { if (_impactFlash == null) { return(null); } var message = new EffectSystemMessage { EffectSprite = _impactFlash, Born = _startTime, DeathTime = _deathTime, Coordinates = Owner.Transform.Coordinates.Offset(angle.ToVec() * distance), //Rotated from east facing Rotation = (float)angle.FlipPositive(), Color = Vector4.Multiply(new Vector4(255, 255, 255, 750), ColorModifier), ColorDelta = new Vector4(0, 0, 0, -1500f), Shaded = false }; return(message); }
protected virtual void AfterEffects(IEntity user, float distance, Angle angle, float energyModifier) { var time = IoCManager.Resolve <IGameTiming>().CurTime; var offset = angle.ToVec() * distance / 2; var message = new EffectSystemMessage { EffectSprite = _spritename, Born = time, DeathTime = time + TimeSpan.FromSeconds(1), Size = new Vector2(distance, 1f), Coordinates = user.Transform.GridPosition.Translated(offset), //Rotated from east facing Rotation = (float)angle.Theta, ColorDelta = new Vector4(0, 0, 0, -1500f), Color = Vector4.Multiply(new Vector4(255, 255, 255, 750), energyModifier), Shaded = false }; EntitySystem.Get <EffectSystem>().CreateParticle(message); EntitySystem.Get <AudioSystem>().PlayFromEntity(_fireSound, Owner, AudioParams.Default.WithVolume(-5)); }
protected virtual void AfterEffects(IEntity user, RayCastResults ray, Angle angle) { var time = IoCManager.Resolve <IGameTiming>().CurTime; var dist = ray.DidHitObject ? ray.Distance : MaxLength; var offset = angle.ToVec() * dist / 2; var message = new EffectSystemMessage { EffectSprite = Spritename, Born = time, DeathTime = time + TimeSpan.FromSeconds(1), Size = new Vector2(dist, 1f), Coordinates = user.Transform.GridPosition.Translated(offset), //Rotated from east facing Rotation = (float)angle.Theta, ColorDelta = new Vector4(0, 0, 0, -1500f), Color = new Vector4(255, 255, 255, 750), Shaded = false }; var mgr = IoCManager.Resolve <IEntitySystemManager>(); mgr.GetEntitySystem <EffectSystem>().CreateParticle(message); mgr.GetEntitySystem <AudioSystem>().Play("/Audio/laser.ogg", Owner, AudioParams.Default.WithVolume(-5)); }
private EffectSystemMessage?MuzzleFlash(EntityCoordinates grid, Angle angle) { if (_muzzleFlash == null) { return(null); } var offset = angle.ToVec().Normalized / 2; var message = new EffectSystemMessage { EffectSprite = _muzzleFlash, Born = _startTime, DeathTime = _deathTime, Coordinates = grid.Offset(offset), //Rotated from east facing Rotation = (float)angle.Theta, Color = Vector4.Multiply(new Vector4(255, 255, 255, 750), ColorModifier), ColorDelta = new Vector4(0, 0, 0, -1500f), Shaded = false }; return(message); }
private bool Explosion() { var maxRange = MathHelper.Max(DevastationRange, HeavyImpactRange, LightImpactRange, 0f); //Entity damage calculation var entitiesAll = _serverEntityManager.GetEntitiesInRange(Owner.Transform.GridPosition, maxRange).ToList(); foreach (var entity in entitiesAll) { Owner.Delete(); if (entity == Owner) { continue; } if (!entity.Transform.IsMapTransform) { continue; } var distanceFromEntity = (int)entity.Transform.GridPosition.Distance(_mapManager, Owner.Transform.GridPosition); var exAct = _entitySystemManager.GetEntitySystem <ActSystem>(); var severity = ExplosionSeverity.Destruction; if (distanceFromEntity < DevastationRange) { severity = ExplosionSeverity.Destruction; } else if (distanceFromEntity < HeavyImpactRange) { severity = ExplosionSeverity.Heavy; } else if (distanceFromEntity < LightImpactRange) { severity = ExplosionSeverity.Light; } else { continue; } exAct.HandleExplosion(Owner, entity, severity); } //Tile damage calculation mockup //TODO: make it into some sort of actual damage component or whatever the boys think is appropriate var mapGrid = _mapManager.GetGrid(Owner.Transform.GridPosition.GridID); var circle = new Circle(Owner.Transform.GridPosition.Position, maxRange); var tiles = mapGrid.GetTilesIntersecting(circle); foreach (var tile in tiles) { var tileLoc = mapGrid.GridTileToLocal(tile.GridIndices); var tileDef = (ContentTileDefinition)_tileDefinitionManager[tile.Tile.TypeId]; var distanceFromTile = (int)tileLoc.Distance(_mapManager, Owner.Transform.GridPosition); if (!string.IsNullOrWhiteSpace(tileDef.SubFloor)) { if (distanceFromTile < DevastationRange) { mapGrid.SetTile(tileLoc, new Tile(_tileDefinitionManager["space"].TileId)); } if (distanceFromTile < HeavyImpactRange) { if (new Random().Prob(80)) { mapGrid.SetTile(tileLoc, new Tile(_tileDefinitionManager[tileDef.SubFloor].TileId)); } else { mapGrid.SetTile(tileLoc, new Tile(_tileDefinitionManager["space"].TileId)); } } if (distanceFromTile < LightImpactRange) { if (new Random().Prob(50)) { mapGrid.SetTile(tileLoc, new Tile(_tileDefinitionManager[tileDef.SubFloor].TileId)); } } } } //Effects and sounds var time = IoCManager.Resolve <IGameTiming>().CurTime; var message = new EffectSystemMessage { EffectSprite = "Effects/explosion.rsi", RsiState = "explosionfast", Born = time, DeathTime = time + TimeSpan.FromSeconds(5), Size = new Vector2(FlashRange / 2, FlashRange / 2), Coordinates = Owner.Transform.GridPosition, //Rotated from east facing Rotation = 0f, ColorDelta = new Vector4(0, 0, 0, -1500f), Color = Vector4.Multiply(new Vector4(255, 255, 255, 750), 0.5f), Shaded = false }; _entitySystemManager.GetEntitySystem <EffectSystem>().CreateParticle(message); _entitySystemManager.GetEntitySystem <AudioSystem>().Play("/Audio/effects/explosion.ogg", Owner); // Knock back cameras of all players in the area. var playerManager = IoCManager.Resolve <IPlayerManager>(); var selfPos = Owner.Transform.WorldPosition; foreach (var player in playerManager.GetAllPlayers()) { if (player.AttachedEntity == null || player.AttachedEntity.Transform.MapID != mapGrid.ParentMapId || !player.AttachedEntity.TryGetComponent(out CameraRecoilComponent recoil)) { continue; } var playerPos = player.AttachedEntity.Transform.WorldPosition; var delta = selfPos - playerPos; var distance = delta.LengthSquared; var effect = 1 / (1 + 0.2f * distance); if (effect > 0.01f) { var kick = -delta.Normalized * effect; recoil.Kick(kick); } } return(true); }
protected abstract void CreateEffect(EffectSystemMessage message, EntityUid?user = null);
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; } }); } }
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 = EntityManager.GetEntity(msg.Attacker); if (!attacker.Deleted) { var lunge = attacker.EnsureComponent <MeleeLungeComponent>(); lunge.SetData(msg.Angle); var entity = EntityManager.SpawnEntity(weaponArc.Prototype, attacker.Transform.Coordinates); entity.Transform.LocalRotation = msg.Angle; var weaponArcAnimation = entity.GetComponent <MeleeWeaponArcAnimationComponent>(); 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.TryGetEntity(msg.Source, out var source) && msg.TextureEffect && source.TryGetComponent(out ISpriteComponent sourceSprite) && sourceSprite.BaseRSI?.Path != null) { var sys = Get <EffectSystem>(); var curTime = _gameTiming.CurTime; var effect = new EffectSystemMessage { EffectSprite = sourceSprite.BaseRSI.Path.ToString(), RsiState = sourceSprite.LayerGetState(0).Name, Coordinates = attacker.Transform.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.ToVec(), Acceleration = msg.Angle.ToVec() * 5f, Born = curTime, DeathTime = curTime.Add(TimeSpan.FromMilliseconds(300f)), }; sys.CreateEffect(effect); } } foreach (var uid in msg.Hits) { if (!EntityManager.TryGetEntity(uid, out var hitEntity) || hitEntity.Deleted) { continue; } if (!hitEntity.TryGetComponent(out ISpriteComponent sprite)) { continue; } var originalColor = sprite.Color; var newColor = Color.Red * originalColor; sprite.Color = newColor; hitEntity.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; } }); } }