SatelliteLaser.cs
using Sandbox.UI;
using SpriteTools;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using static Manager;
public class SatelliteLaser : Component
{
[Property] public SpriteRendererLayer Sprite { get; set; }
public float ShadowOpacity { get; set; }
public float ShadowScale { get; set; }
public SpriteRendererLayer ShadowSprite { get; set; }
private float _lifetime;
public float Damage { get; set; }
//private Vector2 _lastSpritePos;
public TimeSince TimeSinceSpawn { get; set; }
public Vector2 Position2D
{
get { return (Vector2)WorldPosition; }
set { WorldPosition = new Vector3( value.x, value.y, WorldPosition.z ); }
}
public void Init()
{
TimeSinceSpawn = 0f;
_lifetime = 1.5f;
//LocalRotation = new Angles( 0f, 0f, 0f );
var shadowObj = Manager.Instance.ShadowPrefab.Clone( WorldPosition );
shadowObj.SetParent( GameObject );
shadowObj.LocalPosition = new Vector3( 0f, 0f, Globals.SHADOW_DEPTH_OFFSET );
shadowObj.LocalRotation = new Angles( 0f, 90f, 0f );
shadowObj.NetworkMode = NetworkMode.Never;
float size = 5f;
ShadowSprite = shadowObj.Components.Get<SpriteRendererLayer>();
ShadowSprite.LocalScale = new Vector3( size * Globals.SPRITE_SCALE, size * Globals.SPRITE_SCALE, 1f );
float shadowOpacity = 0.2f;
ShadowSprite.Tint = Color.Black.WithAlpha( shadowOpacity );
Sprite.LocalScale = new Vector3( 0.5f, 0.5f, 1f ) * Globals.SPRITE_SCALE;
if ( Game.Random.Float(0f, 1f) < 0.5f )
Sprite.SpriteFlags = SpriteFlags.HorizontalFlip;
}
protected override void OnUpdate()
{
base.OnUpdate();
//Gizmo.Draw.Color = Color.Black.WithAlpha(0.2f);
//Gizmo.Draw.Text( $"{TimeSinceSpawn}", new global::Transform( (Vector3)Position2D + new Vector3( 0f, -0.2f, 0f ) ) );
//Gizmo.Draw.Color = Color.White.WithAlpha( 0.01f );
//Gizmo.Draw.LineSphere( (Vector3)Position2D, 0.5f );
//Gizmo.Draw.Color = Color.Blue.WithAlpha( 0.2f );
//Gizmo.Draw.Line( _startPos, _endPos );
float progress = Utils.Map( TimeSinceSpawn, 0f, _lifetime, 0f, 1f );
WorldPosition = new Vector3( WorldPosition.x, WorldPosition.y, Globals.GetZPos( WorldPosition.y ) );
//float stretch = Utils.MapReturn( progress, 0f, 1f, 0.2f, 0f, EasingType.QuadOut );
//Sprite.LocalScale = new Vector3( 0.5f + stretch, 0.5f - stretch, 1f ) * Globals.SPRITE_SCALE;
//_lastSpritePos = Sprite.WorldPosition;
Sprite.LocalPosition = new Vector3(0f, Utils.Map( progress, 0f, 1f, 150f, 0f, EasingType.SineOut ), 0f );
//Sprite.LocalRotation = new Angles( 0f, Utils.VectorToDegrees( ((Vector2)Sprite.WorldPosition - _lastSpritePos).Normal ), 0f );
//Sprite.Tint = Color.Lerp( new Color( 1f, 0.4f, 0f ), new Color( 1f, 0f, 0f ), 0.5f + Utils.FastSin( TimeSinceSpawn * 16f ) * 0.5f );
float shadowSize = Utils.Map( progress, 0f, 1f, 0f, 1.2f );
ShadowSprite.LocalScale = new Vector3( shadowSize * Globals.SPRITE_SCALE, shadowSize * Globals.SPRITE_SCALE, 1f );
ShadowSprite.Tint = Color.Black.WithAlpha( Utils.Map( progress, 0f, 1f, 0.2f, 1f ) );
if( TimeSinceSpawn > _lifetime )
{
Explode();
//Manager.Instance.PlaySfxNearby( "lava_puddle_01", EndPos, pitch: Game.Random.Float( 0.9f, 1.1f ), volume: 1.4f, maxDist: 6f );
Manager.Instance.RemoveSatelliteLaser( this );
GameObject.Destroy();
}
}
void Explode()
{
List<Thing> nearbyThings = new List<Thing>();
var gridPos = Manager.Instance.GetGridSquareForPos( Position2D );
for ( int dx = -2; dx <= 2; dx++ )
for ( int dy = -2; dy <= 2; dy++ )
Manager.Instance.AddThingsInGridSquare( new Manager.GridSquare( gridPos.x + dx, gridPos.y + dy ), nearbyThings );
var player = Manager.Instance.Player;
float radius = 0.425f * player.Stats[PlayerStat.RadiusMultiplier];
float damage = Damage * player.GetDamageMultiplier();
//Manager.Instance.PlaySfxNearby( "shoot", Player.Position2D, pitch: Utils.Map( xp, 1, 16, 0.85f, 1.4f ), volume: Utils.Map( xp, 1, 16, 0.6f, 1f ), maxDist: 3f );
foreach ( Thing thing in nearbyThings )
{
if ( thing is Enemy enemy && !enemy.IsDying && (!enemy.IsSpawning || enemy.TimeSinceSpawn > 0.75f) && !enemy.IgnoreCollision && !enemy.IsCharmed )
{
var dist_sqr = (thing.Position2D - Position2D).LengthSquared;
if ( dist_sqr < MathF.Pow( radius, 2f ) )
{
var addVel = (thing.Position2D - Position2D).Normal * 0.5f;
var addTempWeight = 0f;
enemy.Damage( damage, player, addVel, addTempWeight, false, DamageType.Ranged );
}
}
else if ( thing == player )
{
if ( !player.IsDead && !player.IsInvulnerable && !player.IsTimePausedForChoosing )
{
var dist_sqr = (thing.Position2D - Position2D).LengthSquared;
if ( dist_sqr < MathF.Pow( radius, 2f ) * 0.94f )
{
var dmg = player.CheckDamageAmount( damage, DamageType.Ranged );
player.Damage( Math.Max(dmg * 0.1f, 1f), PlayerDamageType.Self );
player.AddVelocity( (thing.Position2D - Position2D).Normal * 0.5f );
}
}
}
}
var explosion = Manager.Instance.SpawnExplosionEffect( Position2D, new Color( 1f, 1f, 0f ), new Color( 1f, 1f, 0.5f ), opacity: 0.05f, scaleModifier: 0.75f * radius );
explosion.Sprite.PlaybackSpeed = 5f;
explosion.Lifetime = 0.2f;
Manager.Instance.PlaySfxNearby( "laser_hit_2", Position2D, pitch: Game.Random.Float( 0.8f, 0.85f ), volume: 0.6f, maxDist: 7.5f );
}
}