mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-06-09 10:06:34 +02:00
Fuck yeah, particles! (Try the esword, press f to turn on. its great :) )
This commit is contained in:
@@ -66,6 +66,9 @@
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\References\Release\Gorgon.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GorgonFramework">
|
||||
<HintPath>..\References\Release\GorgonFramework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="NetSerializer, Version=1.5.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
@@ -105,6 +108,8 @@
|
||||
<Compile Include="Component\Mover\SlaveMoverComponent.cs" />
|
||||
<Compile Include="Component\Physics\PhysicsComponent.cs" />
|
||||
<Compile Include="Component\PlayerActionComp\PlayerActionCompC.cs" />
|
||||
<Compile Include="Component\Renderable\ParticleSystem.cs" />
|
||||
<Compile Include="Component\Renderable\ParticleSystemComponent.cs" />
|
||||
<Compile Include="Component\Renderable\Speechbubble.cs" />
|
||||
<Compile Include="Component\Renderable\WearableSpriteComponent.cs" />
|
||||
<Compile Include="Component\Renderable\ItemSpriteComponent.cs" />
|
||||
|
||||
@@ -175,11 +175,14 @@ namespace CGO
|
||||
|
||||
public void LoadSprites(string name)
|
||||
{
|
||||
AddSprite(name);
|
||||
AddSprite(name + "_inhand");
|
||||
AddSprite(name + "_inhand_side");
|
||||
if (IoCManager.Resolve<IResourceManager>().SpriteExists(name + "_inhand_back"))
|
||||
AddSprite(name + "_inhand_back");
|
||||
if (!HasSprite(name))
|
||||
{
|
||||
AddSprite(name);
|
||||
AddSprite(name + "_inhand");
|
||||
AddSprite(name + "_inhand_side");
|
||||
if (IoCManager.Resolve<IResourceManager>().SpriteExists(name + "_inhand_back"))
|
||||
AddSprite(name + "_inhand_back");
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool WasClicked(PointF worldPos)
|
||||
|
||||
@@ -0,0 +1,777 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using GorgonLibrary;
|
||||
using GorgonLibrary.Graphics;
|
||||
|
||||
namespace CGO
|
||||
{
|
||||
public class ParticleSystem
|
||||
{
|
||||
#region Classes
|
||||
private class Particle
|
||||
{
|
||||
/// <summary>
|
||||
/// Particle position relative to the emit position
|
||||
/// </summary>
|
||||
public Vector2D Position;
|
||||
|
||||
/// <summary>
|
||||
/// Where the emitter was when the particle was first emitted
|
||||
/// </summary>
|
||||
public Vector2D EmitterPosition;
|
||||
|
||||
/// <summary>
|
||||
/// Particle's x/y velocity
|
||||
/// </summary>
|
||||
public Vector2D Velocity;
|
||||
|
||||
/// <summary>
|
||||
/// Particle's x/y acceleration
|
||||
/// </summary>
|
||||
public Vector2D Acceleration;
|
||||
|
||||
/// <summary>
|
||||
/// Particle's radial velocity - relative to EmitterPosition
|
||||
/// </summary>
|
||||
public float RadialVelocity;
|
||||
|
||||
/// <summary>
|
||||
/// Particle's radial acceleration
|
||||
/// </summary>
|
||||
public float RadialAcceleration;
|
||||
|
||||
/// <summary>
|
||||
/// Particle's tangential velocity - relative to EmitterPosition
|
||||
/// </summary>
|
||||
public float TangentialVelocity;
|
||||
|
||||
/// <summary>
|
||||
/// Particle's tangential acceleration
|
||||
/// </summary>
|
||||
public float TangentialAcceleration;
|
||||
|
||||
/// <summary>
|
||||
/// Particle's age -- from 0f
|
||||
/// </summary>
|
||||
public float Age;
|
||||
|
||||
/// <summary>
|
||||
/// Time after which the particle will "die"
|
||||
/// </summary>
|
||||
public float Lifetime;
|
||||
|
||||
/// <summary>
|
||||
/// Particle's spin about its center in radians
|
||||
/// </summary>
|
||||
public float Spin;
|
||||
|
||||
/// <summary>
|
||||
/// Rate of change of particle's spin
|
||||
/// </summary>
|
||||
public float SpinVelocity;
|
||||
|
||||
/// <summary>
|
||||
/// Particle's current size
|
||||
/// </summary>
|
||||
public float Size;
|
||||
|
||||
/// <summary>
|
||||
/// Rate of change of particle's size change
|
||||
/// </summary>
|
||||
public float SizeDelta;
|
||||
|
||||
/// <summary>
|
||||
/// Particle's current color
|
||||
/// </summary>
|
||||
public Vector4D Color;
|
||||
|
||||
/// <summary>
|
||||
/// Rate of change of particle's color
|
||||
/// </summary>
|
||||
public Vector4D ColorDelta;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the particle is currently being drawn
|
||||
/// </summary>
|
||||
public bool Alive;
|
||||
|
||||
public Particle()
|
||||
{
|
||||
Position = ParticleDefaults.Position;
|
||||
EmitterPosition = ParticleDefaults.EmitterPosition;
|
||||
Velocity = ParticleDefaults.Velocity;
|
||||
Acceleration = ParticleDefaults.Acceleration;
|
||||
RadialVelocity = ParticleDefaults.RadialVelocity;
|
||||
RadialAcceleration = ParticleDefaults.RadialAcceleration;
|
||||
TangentialVelocity = ParticleDefaults.TangentialVelocity;
|
||||
TangentialAcceleration = ParticleDefaults.TangentialAcceleration;
|
||||
Age = ParticleDefaults.Age;
|
||||
Lifetime = ParticleDefaults.Lifetime;
|
||||
Spin = ParticleDefaults.Spin;
|
||||
SpinVelocity = ParticleDefaults.SpinVelocity;
|
||||
Size = ParticleDefaults.Size;
|
||||
SizeDelta = ParticleDefaults.SizeDelta;
|
||||
Color = ParticleDefaults.Color;
|
||||
ColorDelta = ParticleDefaults.ColorDelta;
|
||||
Alive = ParticleDefaults.Alive;
|
||||
}
|
||||
|
||||
public void Update(float frameTime)
|
||||
{
|
||||
Age += frameTime;
|
||||
if (Age >= Lifetime)
|
||||
Alive = false;
|
||||
Velocity += Acceleration*frameTime;
|
||||
RadialVelocity += RadialAcceleration*frameTime;
|
||||
TangentialVelocity += TangentialAcceleration*frameTime;
|
||||
|
||||
//Calculate delta p due to radial velocity
|
||||
var positionRelativeToEmitter = Position - EmitterPosition;
|
||||
var deltaRadial = RadialVelocity * frameTime;
|
||||
var deltaPosition = positionRelativeToEmitter*(deltaRadial/positionRelativeToEmitter.Length);
|
||||
|
||||
//Calculate delta p due to tangential velocity
|
||||
var radius = positionRelativeToEmitter.Length;
|
||||
if (radius > 0)
|
||||
{
|
||||
var theta = MathUtility.ASin(positionRelativeToEmitter.X/radius);
|
||||
theta += TangentialVelocity*frameTime;
|
||||
deltaPosition += new Vector2D(radius*MathUtility.Sin(theta), radius*MathUtility.Cos(theta))
|
||||
- positionRelativeToEmitter;
|
||||
}
|
||||
//Calculate delta p due to Velocity
|
||||
deltaPosition += Velocity*frameTime;
|
||||
Position += deltaPosition;
|
||||
Spin += SpinVelocity*frameTime;
|
||||
Size += SizeDelta*frameTime;
|
||||
Color += ColorDelta*frameTime;
|
||||
}
|
||||
}
|
||||
|
||||
private struct ParticleDefaults
|
||||
{
|
||||
/// <summary>
|
||||
/// Particle position relative to the emit position
|
||||
/// </summary>
|
||||
public static Vector2D Position = new Vector2D(0,0);
|
||||
|
||||
/// <summary>
|
||||
/// Where the emitter was when the particle was first emitted
|
||||
/// </summary>
|
||||
public static Vector2D EmitterPosition = new Vector2D(0,0);
|
||||
|
||||
/// <summary>
|
||||
/// Particle's x/y velocity
|
||||
/// </summary>
|
||||
public static Vector2D Velocity = new Vector2D(0,0);
|
||||
|
||||
/// <summary>
|
||||
/// Particle's x/y acceleration
|
||||
/// </summary>
|
||||
public static Vector2D Acceleration = new Vector2D(0,0);
|
||||
|
||||
/// <summary>
|
||||
/// Particle's radial velocity - relative to EmitterPosition
|
||||
/// </summary>
|
||||
public static float RadialVelocity = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Particle's radial acceleration
|
||||
/// </summary>
|
||||
public static float RadialAcceleration = 0f;
|
||||
|
||||
/// <summary>
|
||||
/// Particle's tangential velocity - relative to EmitterPosition
|
||||
/// </summary>
|
||||
public static float TangentialVelocity = 0f;
|
||||
|
||||
/// <summary>
|
||||
/// Particle's tangential acceleration
|
||||
/// </summary>
|
||||
public static float TangentialAcceleration = 0f;
|
||||
|
||||
/// <summary>
|
||||
/// Particle's age -- from 0f
|
||||
/// </summary>
|
||||
public static float Age = 0f;
|
||||
|
||||
/// <summary>
|
||||
/// Time after which the particle will "die"
|
||||
/// </summary>
|
||||
public static float Lifetime = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Particle's spin about its center in radians
|
||||
/// </summary>
|
||||
public static float Spin = 0f;
|
||||
|
||||
/// <summary>
|
||||
/// Rate of change of particle's spin
|
||||
/// </summary>
|
||||
public static float SpinVelocity = 0f;
|
||||
|
||||
/// <summary>
|
||||
/// Particle's current size
|
||||
/// </summary>
|
||||
public static float Size = 0f;
|
||||
|
||||
/// <summary>
|
||||
/// Rate of change of particle's size change
|
||||
/// </summary>
|
||||
public static float SizeDelta = 0f;
|
||||
|
||||
/// <summary>
|
||||
/// Particle's current color
|
||||
/// </summary>
|
||||
public static Vector4D Color = new Vector4D(1,0,0,0);
|
||||
|
||||
/// <summary>
|
||||
/// Rate of change of particle's color
|
||||
/// </summary>
|
||||
public static Vector4D ColorDelta = new Vector4D(-1, 0, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the particle is currently being drawn
|
||||
/// </summary>
|
||||
public static bool Alive = false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Variables
|
||||
|
||||
private Particle[] _particles;
|
||||
private Batch _batch;
|
||||
private Random _rnd = new Random();
|
||||
private float _particlesToEmit;
|
||||
private List<Particle> _newParticles = new List<Particle>();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Emitter Position;
|
||||
/// This is the logical position of the emitter object
|
||||
/// </summary>
|
||||
public Vector2D EmitterPosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Emission Offset;
|
||||
/// This is where the particles should be emitted relative to the emitter position.
|
||||
/// </summary>
|
||||
public Vector2D EmissionOffset { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Emit Position
|
||||
/// This is where the particles will be emitted.
|
||||
/// </summary>
|
||||
public Vector2D EmitPosition { get { return EmitterPosition + EmissionOffset; } }
|
||||
|
||||
/// <summary>
|
||||
/// Emit
|
||||
/// This controls whether particles are being emitted or not
|
||||
/// </summary>
|
||||
public bool Emit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Emit Rate
|
||||
/// This controls the rate in particles per second at which particles are emitted.
|
||||
/// </summary>
|
||||
public int EmitRate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Maximum Particles To Display
|
||||
/// This controls how many particles will be 'alive' at once. If the number of particles generated exceeds this,
|
||||
/// the oldest particles will be culled first.
|
||||
/// </summary>
|
||||
public int MaximumParticleCount
|
||||
{
|
||||
get { return _particles.Length; }
|
||||
set
|
||||
{
|
||||
if (value < 1)
|
||||
throw new ArgumentOutOfRangeException("The number of particles cannot be less than 1.");
|
||||
|
||||
_particles = new Particle[value];
|
||||
for (var i = 0; i < value; i++)
|
||||
{
|
||||
_particles[i] = new Particle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Particle Sprite
|
||||
/// This is the sprite that will be drawn as the "particle".
|
||||
/// </summary>
|
||||
public Sprite ParticleSprite { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Emission Radius
|
||||
/// This controls the range in radius from the emission position where the particles
|
||||
/// will start. If the radius is 0, they will all be emitted at the EmitPosition.
|
||||
/// </summary>
|
||||
public Range<float> EmissionRadiusRange { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Velocity Range
|
||||
/// This controls the particle's initial velocity
|
||||
/// </summary>
|
||||
public Vector2D Velocity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Velocity Variance
|
||||
/// This controls the random variation of the particle's initial velocity
|
||||
/// </summary>
|
||||
public float VelocityVariance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Acceleration Range
|
||||
/// This controls the particle's initial acceleration
|
||||
/// </summary>
|
||||
public Vector2D Acceleration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Acceleration Variance
|
||||
/// This controls the random variation of particle's initial acceleration
|
||||
/// </summary>
|
||||
public float AccelerationVariance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Radial Velocity Range
|
||||
/// This controls the particle's initial Radial velocity
|
||||
/// </summary>
|
||||
public float RadialVelocity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Radial Velocity Variance
|
||||
/// Radial This controls the random variation of the particle's initial Radial velocity
|
||||
/// </summary>
|
||||
public float RadialVelocityVariance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Radial Acceleration Range
|
||||
/// This controls the particle's initial Radial acceleration
|
||||
/// </summary>
|
||||
public float RadialAcceleration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Radial Acceleration Variance
|
||||
/// This controls the random variation of particle's initial Radial acceleration
|
||||
/// </summary>
|
||||
public float RadialAccelerationVariance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tangential Velocity Range
|
||||
/// This controls the particle's initial tangential velocity
|
||||
/// </summary>
|
||||
public float TangentialVelocity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tangential Velocity Variance
|
||||
/// This controls the random variation of the particle's initial tangential velocity
|
||||
/// </summary>
|
||||
public float TangentialVelocityVariance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tangential Acceleration Range
|
||||
/// This controls the particle's initial tangential acceleration
|
||||
/// </summary>
|
||||
public float TangentialAcceleration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tangential Acceleration Variance
|
||||
/// This controls the random variation of particle's initial tangential acceleration
|
||||
/// </summary>
|
||||
public float TangentialAccelerationVariance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Lifetime
|
||||
/// This controls the particle's lifetime
|
||||
/// </summary>
|
||||
public float Lifetime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Lifetime Variance
|
||||
/// This controls the variation in the particle's lifetime
|
||||
/// </summary>
|
||||
public float LifetimeVariance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Spin Velocity
|
||||
/// This controls the initial spin velocity over the life of the particle
|
||||
/// </summary>
|
||||
public Range<float> SpinVelocity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Spin Velocity Variance
|
||||
/// This controls the random variation of the initial spin velocity of the particle
|
||||
/// </summary>
|
||||
public float SpinVelocityVariance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Size Range
|
||||
/// This controls the range in size of the particle over the course of its lifetime
|
||||
/// </summary>
|
||||
public Range<float> SizeRange { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This controls how much particle size will vary between particles
|
||||
/// </summary>
|
||||
public float SizeVariance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This controls the color range of the particle over the course of its lifetime
|
||||
/// </summary>
|
||||
public Range<Vector4D> ColorRange { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This controls how much particle color will vary between particles
|
||||
/// </summary>
|
||||
public float ColorVariance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the set of live particles, ordered by oldest (nearest to death) first
|
||||
/// </summary>
|
||||
private IEnumerable<Particle> LiveParticles
|
||||
{
|
||||
get { return _particles.Where(p => p.Alive).OrderByDescending(p => 1-(p.Lifetime-p.Age)/p.Lifetime); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the set of dead particles
|
||||
/// </summary>
|
||||
private IEnumerable<Particle> DeadParticles
|
||||
{
|
||||
get { return _particles.Where(p => !p.Alive); }
|
||||
}
|
||||
|
||||
private int DeadParticleCount
|
||||
{
|
||||
get { return DeadParticles.Count(); }
|
||||
}
|
||||
|
||||
private int LiveParticleCount
|
||||
{
|
||||
get { return LiveParticles.Count(); }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
private float RandomFloat()
|
||||
{
|
||||
return (float) _rnd.NextDouble();
|
||||
}
|
||||
|
||||
private float RandomSignedFloat()
|
||||
{
|
||||
return (float) (_rnd.NextDouble() - 0.5f)*2;
|
||||
}
|
||||
|
||||
private float RandomRangeFloat(Range<float> randomRange)
|
||||
{
|
||||
return (RandomFloat() * (randomRange.End - randomRange.Start)) + randomRange.Start;
|
||||
}
|
||||
|
||||
private float RandomRangeFloat(float start, float end)
|
||||
{
|
||||
return (RandomFloat()*(end - start)) + start;
|
||||
}
|
||||
|
||||
private Vector2D RandomRangeVector2D(Range<Vector2D> randomRange)
|
||||
{
|
||||
return new Vector2D(
|
||||
RandomRangeFloat(randomRange.Start.X, randomRange.End.X),
|
||||
RandomRangeFloat(randomRange.Start.Y, randomRange.End.Y)
|
||||
);
|
||||
}
|
||||
|
||||
private Vector3D RandomRangeVector3D(Range<Vector3D> randomRange)
|
||||
{
|
||||
return new Vector3D(
|
||||
RandomRangeFloat(randomRange.Start.X, randomRange.End.X),
|
||||
RandomRangeFloat(randomRange.Start.Y, randomRange.End.Y),
|
||||
RandomRangeFloat(randomRange.Start.Z, randomRange.End.Z)
|
||||
);
|
||||
}
|
||||
|
||||
private Vector4D RandomRangeVector4D(Range<Vector4D> randomRange)
|
||||
{
|
||||
return new Vector4D(
|
||||
RandomRangeFloat(randomRange.Start.X, randomRange.End.X),
|
||||
RandomRangeFloat(randomRange.Start.Y, randomRange.End.Y),
|
||||
RandomRangeFloat(randomRange.Start.Z, randomRange.End.Z),
|
||||
RandomRangeFloat(randomRange.Start.W, randomRange.End.W)
|
||||
);
|
||||
}
|
||||
|
||||
private float VariedFloat(float value, float variance)
|
||||
{
|
||||
return value + RandomSignedFloat() * variance;
|
||||
}
|
||||
|
||||
private float VariedPositiveFloat(float value, float variance)
|
||||
{
|
||||
return value + RandomFloat() * variance;
|
||||
}
|
||||
|
||||
private Vector2D VariedVector2D(Vector2D value, float variance)
|
||||
{
|
||||
return new Vector2D(
|
||||
VariedFloat(value.X, variance),
|
||||
VariedFloat(value.Y, variance)
|
||||
);
|
||||
}
|
||||
|
||||
private Vector2D VariedPositiveVector2D(Vector2D value, float variance)
|
||||
{
|
||||
return new Vector2D(
|
||||
VariedPositiveFloat(value.X, variance),
|
||||
VariedPositiveFloat(value.Y, variance)
|
||||
);
|
||||
}
|
||||
|
||||
private Vector3D VariedVector3D(Vector3D value, float variance)
|
||||
{
|
||||
return new Vector3D(
|
||||
VariedFloat(value.X, variance),
|
||||
VariedFloat(value.Y, variance),
|
||||
VariedFloat(value.Z, variance)
|
||||
);
|
||||
}
|
||||
|
||||
private Vector3D VariedPositiveVector3D(Vector3D value, float variance)
|
||||
{
|
||||
return new Vector3D(
|
||||
VariedPositiveFloat(value.X, variance),
|
||||
VariedPositiveFloat(value.Y, variance),
|
||||
VariedPositiveFloat(value.Z, variance)
|
||||
);
|
||||
}
|
||||
|
||||
private Vector4D VariedVector4D(Vector4D value, float variance)
|
||||
{
|
||||
return new Vector4D(
|
||||
VariedFloat(value.X, variance),
|
||||
VariedFloat(value.Y, variance),
|
||||
VariedFloat(value.Z, variance),
|
||||
VariedFloat(value.W, variance)
|
||||
);
|
||||
}
|
||||
|
||||
private Vector4D VariedPositiveVector4D(Vector4D value, float variance)
|
||||
{
|
||||
return new Vector4D(
|
||||
VariedPositiveFloat(value.X, variance),
|
||||
VariedPositiveFloat(value.Y, variance),
|
||||
VariedPositiveFloat(value.Z, variance),
|
||||
VariedPositiveFloat(value.W, variance)
|
||||
);
|
||||
}
|
||||
|
||||
private Vector4D Limit(Vector4D color)
|
||||
{
|
||||
if (Math.Max(color.X, Math.Max(color.Y, Math.Max(color.Z, color.W))) <= 255)
|
||||
return color;
|
||||
float x, y, z, w;
|
||||
x = color.X;
|
||||
y = color.Y;
|
||||
z = color.Z;
|
||||
w = color.W;
|
||||
//RGB Max
|
||||
var max = Math.Max(y, Math.Max(z, w));
|
||||
if(max > 255)
|
||||
{
|
||||
var f = 255/max;
|
||||
y = f*y;
|
||||
z = f*z;
|
||||
w = f*w;
|
||||
}
|
||||
if (x > 255)
|
||||
x = 255;
|
||||
return new Vector4D(x, y, z, w);
|
||||
}
|
||||
|
||||
private Color ToColor(Vector4D color)
|
||||
{
|
||||
color = Limit(color);
|
||||
return Color.FromArgb((int) color.X, (int)color.Y, (int)color.Z, (int)color.W);
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
Emit = true;
|
||||
}
|
||||
|
||||
private void EmitParticle(Particle p)
|
||||
{
|
||||
p.Acceleration = VariedVector2D(Acceleration, AccelerationVariance);
|
||||
p.Lifetime = VariedPositiveFloat(Lifetime, LifetimeVariance);
|
||||
p.Age = 0;
|
||||
if (p.Lifetime == 0)
|
||||
return;
|
||||
p.Alive = true;
|
||||
p.Color = Limit(VariedPositiveVector4D(ColorRange.Start, ColorVariance));
|
||||
var endColor = Limit(VariedPositiveVector4D(ColorRange.End, ColorVariance));
|
||||
p.ColorDelta = (endColor - p.Color)/Lifetime;
|
||||
p.EmitterPosition = EmitPosition;
|
||||
var emitRadius = RandomRangeFloat(EmissionRadiusRange);
|
||||
emitRadius = emitRadius > 0.01f ? emitRadius : 0.1f;
|
||||
var emitAngle = RandomFloat()*2*MathUtility.PI;
|
||||
p.Position = EmitPosition + new Vector2D(
|
||||
emitRadius*MathUtility.Sin(emitAngle),
|
||||
emitRadius*MathUtility.Cos(emitAngle)
|
||||
);
|
||||
p.RadialAcceleration = VariedFloat(RadialAcceleration, RadialAccelerationVariance);
|
||||
p.RadialVelocity = VariedFloat(RadialVelocity, RadialVelocityVariance);
|
||||
p.Size = VariedPositiveFloat(SizeRange.Start, SizeVariance);
|
||||
var endSize = VariedPositiveFloat(SizeRange.End, SizeVariance);
|
||||
p.SizeDelta = (endSize - p.Size)/Lifetime;
|
||||
//TODO Add initial spin?
|
||||
p.SpinVelocity = VariedFloat(SpinVelocity.Start, SpinVelocityVariance);
|
||||
//TODO add spin velocity delta?
|
||||
p.TangentialAcceleration = VariedFloat(TangentialAcceleration, TangentialAccelerationVariance);
|
||||
p.TangentialVelocity = VariedFloat(TangentialVelocity, TangentialVelocityVariance);
|
||||
p.Velocity = VariedVector2D(Velocity, VelocityVariance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Move JUST the emitter
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This moves the emitter's position
|
||||
/// </remarks>
|
||||
/// <param name="toPosition"></param>
|
||||
public void MoveEmitter(Vector2D toPosition)
|
||||
{
|
||||
EmitterPosition = toPosition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Move JUST the particles, moving the emitter to offset
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This moves the particles, but not the emitter. This changes the particles positions relative to the emitter.
|
||||
/// </remarks>
|
||||
/// <param name="toPosition"></param>
|
||||
public void MoveParticles(Vector2D toPosition)
|
||||
{
|
||||
var offset = toPosition - EmitterPosition;
|
||||
MoveParticlesOffset(offset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Move JUST the particles, moving the emitter to offset
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This moves the particles, but not the emitter. This changes the particles positions relative to the emitter.
|
||||
/// </remarks>
|
||||
/// <param name="offset"></param>
|
||||
public void MoveParticlesOffset(Vector2D offset)
|
||||
{
|
||||
Parallel.ForEach(LiveParticles, particle =>
|
||||
{
|
||||
particle.Position += offset;
|
||||
particle.EmitterPosition += offset;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Move the whole system, both emitter and particles
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Practically, this simply changes the emitter logical position. Since the particles are positioned relative to the
|
||||
/// emitter, they "move" as well.
|
||||
/// </remarks>
|
||||
/// <param name="toPosition"></param>
|
||||
public void Move(Vector2D toPosition)
|
||||
{
|
||||
MoveParticles(toPosition);
|
||||
EmitterPosition = toPosition;
|
||||
}
|
||||
|
||||
public void Update(float frameTime)
|
||||
{
|
||||
Parallel.ForEach(LiveParticles, particle => particle.Update(frameTime));
|
||||
|
||||
if (!Emit)
|
||||
return;
|
||||
_particlesToEmit += frameTime*EmitRate;
|
||||
var newParticleCount = (int)Math.Floor(_particlesToEmit);
|
||||
//This should go down to zero.
|
||||
_particlesToEmit -= newParticleCount;
|
||||
|
||||
//Clear out last update
|
||||
_newParticles.Clear();
|
||||
|
||||
//Take some dead particles
|
||||
_newParticles.AddRange(DeadParticles.Take(newParticleCount));
|
||||
|
||||
newParticleCount -= _newParticles.Count();
|
||||
|
||||
//If there aren't enough dead ones, take the remainder from the live ones, oldest first.
|
||||
if(newParticleCount > 0)
|
||||
_newParticles.AddRange(LiveParticles.Take(newParticleCount));
|
||||
|
||||
for (var i = 0; i < _newParticles.Count(); i++)
|
||||
{
|
||||
EmitParticle(_newParticles[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void Render()
|
||||
{
|
||||
//_batch.Clear();
|
||||
foreach (var particle in LiveParticles)
|
||||
{
|
||||
ParticleSprite.Color = ToColor(particle.Color);
|
||||
ParticleSprite.Position = particle.Position;
|
||||
ParticleSprite.Rotation = MathUtility.Degrees(particle.Spin);
|
||||
ParticleSprite.UniformScale = particle.Size;
|
||||
//_batch.AddClone(ParticleSprite);
|
||||
ParticleSprite.Draw();
|
||||
}
|
||||
//_batch.Draw();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructor/Destructors
|
||||
public ParticleSystem(Sprite particleSprite, Vector2D position)
|
||||
{
|
||||
MaximumParticleCount = 200;
|
||||
//TODO start with sane defaults
|
||||
Acceleration = Vector2D.Zero;
|
||||
AccelerationVariance = 0f;
|
||||
ColorRange = new Range<Vector4D>(Vector4D.UnitX * 255, Vector4D.Zero);
|
||||
ColorVariance = 0f;
|
||||
EmissionOffset = Vector2D.Zero;
|
||||
EmissionRadiusRange = new Range<float>(0f,0f);
|
||||
Emit = false;
|
||||
EmitRate = 1;
|
||||
EmitterPosition = position;
|
||||
Lifetime = 1.0f;
|
||||
LifetimeVariance = 0f;
|
||||
ParticleSprite = particleSprite;
|
||||
RadialAcceleration = 0f;
|
||||
RadialAccelerationVariance = 0f;
|
||||
RadialVelocity = 0f;
|
||||
RadialVelocityVariance = 0f;
|
||||
SizeRange = new Range<float>(10,0);
|
||||
SizeVariance = 1.0f;
|
||||
SpinVelocity = new Range<float>(0f, 0f);
|
||||
SpinVelocityVariance = 0f;
|
||||
TangentialAcceleration = 0;
|
||||
TangentialAccelerationVariance = 0;
|
||||
TangentialVelocity = 0;
|
||||
TangentialVelocityVariance = 0;
|
||||
Velocity = Vector2D.Zero;
|
||||
VelocityVariance = 0;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using ClientInterfaces.GOC;
|
||||
using ClientInterfaces.Resource;
|
||||
using ClientWindow;
|
||||
using GameObject;
|
||||
using GorgonLibrary;
|
||||
using GorgonLibrary.Graphics;
|
||||
using GorgonLibrary.Graphics.Utilities;
|
||||
using SS13.IoC;
|
||||
using SS13_Shared;
|
||||
using SS13_Shared.GO;
|
||||
using SS13_Shared.GO.Component.Particles;
|
||||
|
||||
namespace CGO
|
||||
{
|
||||
public class ParticleSystemComponent : Component, IRenderableComponent
|
||||
{
|
||||
#region Variables.
|
||||
private Random _rnd = new Random(); // Random number generator.
|
||||
private ParticleSystem _emitter; // List of particle emitters.
|
||||
private RenderImage _particleImage; // Particle image.
|
||||
private Sprite _particleSprite; // Particle sprite.
|
||||
private PreciseTimer _timer = new PreciseTimer(); // Timer object.
|
||||
private Vector4D _particlesColorStart = Vector4D.UnitX;
|
||||
private Vector4D _particlesColorEnd = Vector4D.Zero;
|
||||
private bool _active = false;
|
||||
private int _particleRate = 1;
|
||||
|
||||
public DrawDepth DrawDepth { get; set; }
|
||||
#endregion
|
||||
public ParticleSystemComponent()
|
||||
{
|
||||
Family = ComponentFamily.Particles;
|
||||
DrawDepth = DrawDepth.ItemsOnTables;
|
||||
_particleSprite = IoCManager.Resolve<IResourceManager>().GetSprite("");
|
||||
CreateEmitter(new Vector2D(0,0));
|
||||
}
|
||||
|
||||
public override Type StateType
|
||||
{
|
||||
get { return typeof(ParticleSystemComponentState); }
|
||||
}
|
||||
|
||||
public void OnMove(object sender, VectorEventArgs args)
|
||||
{
|
||||
var offset = new Vector2D(args.VectorTo.X, args.VectorTo.Y) -
|
||||
new Vector2D(args.VectorFrom.X, args.VectorFrom.Y);
|
||||
_emitter.MoveEmitter(_emitter.EmitterPosition + offset);
|
||||
}
|
||||
|
||||
public override void OnAdd(Entity owner)
|
||||
{
|
||||
base.OnAdd(owner);
|
||||
var transform = Owner.GetComponent<TransformComponent>(ComponentFamily.Transform);
|
||||
transform.OnMove += OnMove;
|
||||
/*
|
||||
_particleImage = new RenderImage("ParticleImage" + Owner.Uid, 64, 64, ImageBufferFormats.BufferRGB888A8);
|
||||
CreateParticle();
|
||||
|
||||
_particleSprite = new Sprite("ParticleSprite" + Owner.Uid, _particleImage);
|
||||
_particleSprite.Axis = new Vector2D(32, 32);
|
||||
*/
|
||||
_particleSprite = IoCManager.Resolve<IResourceManager>().GetSprite("star1");
|
||||
_emitter.ParticleSprite = _particleSprite;
|
||||
}
|
||||
|
||||
public override void OnRemove()
|
||||
{
|
||||
var transform = Owner.GetComponent<TransformComponent>(ComponentFamily.Transform);
|
||||
transform.OnMove -= OnMove;
|
||||
_particleSprite.Image = null;
|
||||
_particleSprite = null;
|
||||
_particleImage.Dispose();
|
||||
_particleImage = null;
|
||||
_emitter = null;
|
||||
base.OnRemove();
|
||||
}
|
||||
|
||||
public override void SetParameter(ComponentParameter parameter)
|
||||
{
|
||||
base.SetParameter(parameter);
|
||||
dynamic parameterValue;
|
||||
switch (parameter.MemberName)
|
||||
{
|
||||
case "drawdepth":
|
||||
DrawDepth = ((DrawDepth)Enum.Parse(typeof(DrawDepth), parameter.GetValue<string>(), true));
|
||||
break;
|
||||
case "colorStart":
|
||||
parameterValue = parameter.GetValue<Vector4>();
|
||||
_particlesColorStart = new Vector4D(parameterValue.X, parameterValue.Y, parameterValue.Z, parameterValue.W);
|
||||
UpdateParticleColor();
|
||||
break;
|
||||
case "colorEnd":
|
||||
parameterValue = parameter.GetValue<Vector4>();
|
||||
_particlesColorEnd = new Vector4D(parameterValue.X, parameterValue.Y, parameterValue.Z, parameterValue.W);
|
||||
UpdateParticleColor();
|
||||
break;
|
||||
case "particlesPerSecond":
|
||||
_particleRate = parameter.GetValue<int>();
|
||||
UpdateParticleRate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override ComponentReplyMessage RecieveMessage(object sender, ComponentMessageType type,
|
||||
params object[] list)
|
||||
{
|
||||
ComponentReplyMessage reply = base.RecieveMessage(sender, type, list);
|
||||
|
||||
if (sender == this) //Don't listen to our own messages!
|
||||
return ComponentReplyMessage.Empty;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ComponentMessageType.SetDrawDepth:
|
||||
DrawDepth = (DrawDepth)list[0];
|
||||
break;
|
||||
}
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
_emitter.Update(frameTime);
|
||||
}
|
||||
|
||||
public virtual void Render(Vector2D topLeft, Vector2D bottomRight)
|
||||
{
|
||||
var blend = Gorgon.CurrentRenderTarget.BlendingMode;
|
||||
Gorgon.CurrentRenderTarget.BlendingMode = BlendingModes.Additive;
|
||||
|
||||
Vector2D renderPos =
|
||||
ClientWindowData.WorldToScreen(
|
||||
Owner.GetComponent<TransformComponent>(ComponentFamily.Transform).Position);
|
||||
|
||||
_emitter.Move(renderPos);
|
||||
_emitter.Render();
|
||||
Gorgon.CurrentRenderTarget.BlendingMode = blend;
|
||||
}
|
||||
|
||||
private void UpdateParticleColor()
|
||||
{
|
||||
_emitter.ColorRange = new Range<Vector4D>(_particlesColorStart, _particlesColorEnd);
|
||||
}
|
||||
|
||||
private void UpdateParticleRate()
|
||||
{
|
||||
_emitter.EmitRate = _particleRate;
|
||||
}
|
||||
|
||||
private void UpdateActive()
|
||||
{
|
||||
_emitter.Emit = _active;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Function to create a particle.
|
||||
/// </summary>
|
||||
private void CreateParticle()
|
||||
{
|
||||
Color particleColor;
|
||||
|
||||
_particleImage.Clear(Color.Transparent);
|
||||
_particleImage.BeginDrawing();
|
||||
for (int x = 64; x > 0; x--)
|
||||
{
|
||||
particleColor = Color.FromArgb(255 - ((x * 4) - 1), 255, 255, 255);
|
||||
_particleImage.FilledCircle(32.0f, 32.0f, x / 2, particleColor);
|
||||
}
|
||||
_particleImage.EndDrawing();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Function to create a particle emitter.
|
||||
/// </summary>
|
||||
/// <param name="position">The position of the emitter.</param>
|
||||
/// <returns>A new emitter.</returns>
|
||||
private void CreateEmitter(Vector2D position)
|
||||
{
|
||||
_emitter = null;
|
||||
|
||||
_emitter = new ParticleSystem(_particleSprite, position);
|
||||
_emitter.ColorRange = new Range<Vector4D>(_particlesColorStart, _particlesColorEnd);
|
||||
_emitter.Emit = _active;
|
||||
_emitter.Lifetime = 10f;
|
||||
_emitter.LifetimeVariance = 2f;
|
||||
_emitter.SizeRange = new Range<float>(0.1f, 0.05f);
|
||||
_emitter.SizeVariance = 0.05f;
|
||||
_emitter.Acceleration = new Vector2D(0, 1.5f);
|
||||
_emitter.RadialVelocity = 10f;
|
||||
_emitter.RadialAcceleration = -1 * _emitter.RadialVelocity/(_emitter.Lifetime-2);
|
||||
_emitter.EmissionRadiusRange = new Range<float>(5, 20);
|
||||
}
|
||||
|
||||
public float Bottom
|
||||
{
|
||||
get
|
||||
{
|
||||
return Owner.GetComponent<TransformComponent>(ComponentFamily.Transform).Position.Y +
|
||||
(_particleSprite.Height / 2);
|
||||
}
|
||||
}
|
||||
|
||||
public override void HandleComponentState(dynamic __state)
|
||||
{
|
||||
var state = (ParticleSystemComponentState) __state;
|
||||
if(state.Active != _active)
|
||||
{
|
||||
_active = state.Active;
|
||||
UpdateActive();
|
||||
}
|
||||
if (state.StartColor.X != _particlesColorStart.X
|
||||
|| state.StartColor.Y != _particlesColorStart.Y
|
||||
|| state.StartColor.Z != _particlesColorStart.Z
|
||||
|| state.StartColor.W != _particlesColorStart.W)
|
||||
{
|
||||
_particlesColorStart = new Vector4D(state.StartColor.X, state.StartColor.Y,
|
||||
state.StartColor.Z, state.StartColor.W);
|
||||
UpdateParticleColor();
|
||||
}
|
||||
if (state.EndColor.X != _particlesColorEnd.X
|
||||
|| state.EndColor.Y != _particlesColorEnd.Y
|
||||
|| state.EndColor.Z != _particlesColorEnd.Z
|
||||
|| state.EndColor.W != _particlesColorEnd.W)
|
||||
{
|
||||
_particlesColorEnd = new Vector4D(state.EndColor.X, state.EndColor.Y,
|
||||
state.EndColor.Z, state.EndColor.W);
|
||||
UpdateParticleColor();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -112,6 +112,11 @@ namespace CGO
|
||||
BuildDirectionalSprites();
|
||||
}
|
||||
|
||||
public bool HasSprite(string key)
|
||||
{
|
||||
return sprites.ContainsKey(key);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void BuildDirectionalSprites()
|
||||
|
||||
@@ -247,7 +247,9 @@
|
||||
</None>
|
||||
<None Include="MessageLogging\messageLoggerService.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<Folder Include="Graphics\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
@@ -216,9 +216,9 @@ namespace ClientServices.Placement
|
||||
|
||||
ComponentParameter spriteParam = template.GetBaseSpriteParamaters().FirstOrDefault();
|
||||
//Will break if states not ordered correctly.
|
||||
if (spriteParam == null) return;
|
||||
//if (spriteParam == null) return;
|
||||
|
||||
var spriteName = spriteParam.GetValue<string>();
|
||||
var spriteName = spriteParam == null?"":spriteParam.GetValue<string>();
|
||||
Sprite sprite = ResourceManager.GetSprite(spriteName);
|
||||
|
||||
CurrentBaseSprite = sprite;
|
||||
|
||||
@@ -1021,7 +1021,8 @@ namespace ClientServices.State.States
|
||||
/// <param name="frametime">time since the last frame was rendered.</param>
|
||||
private void RenderComponents(float frameTime, RectangleF viewPort)
|
||||
{
|
||||
List<Component> components = _entityManager.ComponentManager.GetComponents(ComponentFamily.Renderable);
|
||||
IEnumerable<Component> components = _entityManager.ComponentManager.GetComponents(ComponentFamily.Renderable)
|
||||
.Union(_entityManager.ComponentManager.GetComponents(ComponentFamily.Particles));
|
||||
|
||||
IEnumerable<IRenderableComponent> floorRenderables = from IRenderableComponent c in components
|
||||
orderby c.Bottom ascending , c.DrawDepth ascending
|
||||
@@ -1029,7 +1030,7 @@ namespace ClientServices.State.States
|
||||
select c;
|
||||
|
||||
RenderList(new Vector2D(viewPort.Left, viewPort.Top), new Vector2D(viewPort.Right, viewPort.Bottom),
|
||||
floorRenderables.ToList());
|
||||
floorRenderables);
|
||||
|
||||
IEnumerable<IRenderableComponent> largeRenderables = from IRenderableComponent c in components
|
||||
orderby c.Bottom ascending
|
||||
@@ -1038,7 +1039,7 @@ namespace ClientServices.State.States
|
||||
select c;
|
||||
|
||||
RenderList(new Vector2D(viewPort.Left, viewPort.Top), new Vector2D(viewPort.Right, viewPort.Bottom),
|
||||
largeRenderables.ToList());
|
||||
largeRenderables);
|
||||
|
||||
IEnumerable<IRenderableComponent> ceilingRenderables = from IRenderableComponent c in components
|
||||
orderby c.Bottom ascending , c.DrawDepth ascending
|
||||
@@ -1046,10 +1047,10 @@ namespace ClientServices.State.States
|
||||
select c;
|
||||
|
||||
RenderList(new Vector2D(viewPort.Left, viewPort.Top), new Vector2D(viewPort.Right, viewPort.Bottom),
|
||||
ceilingRenderables.ToList());
|
||||
ceilingRenderables);
|
||||
}
|
||||
|
||||
private void RenderList(Vector2D topleft, Vector2D bottomright, List<IRenderableComponent> renderables)
|
||||
private void RenderList(Vector2D topleft, Vector2D bottomright, IEnumerable<IRenderableComponent> renderables)
|
||||
{
|
||||
foreach (IRenderableComponent component in renderables)
|
||||
{
|
||||
|
||||
@@ -35,7 +35,12 @@ namespace ClientServices.UserInterface.Components
|
||||
{
|
||||
_resourceManager = resourceManager;
|
||||
|
||||
var SpriteName = entityTemplate.GetBaseSpriteParamaters().FirstOrDefault().GetValue<string>();
|
||||
var spriteNameParam = entityTemplate.GetBaseSpriteParamaters().FirstOrDefault();
|
||||
string SpriteName = "";
|
||||
if (spriteNameParam != null)
|
||||
{
|
||||
SpriteName = spriteNameParam.GetValue<string>();
|
||||
}
|
||||
string ObjectName = entityTemplate.Name;
|
||||
|
||||
associatedTemplate = entityTemplate;
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace GameObject
|
||||
|
||||
public List<Component> GetComponents(ComponentFamily family)
|
||||
{
|
||||
return components[ComponentFamily.Renderable].Cast<Component>().ToList();
|
||||
return components[family].Cast<Component>().ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -56,8 +56,8 @@ namespace GameObject
|
||||
foreach (ComponentFamily family in Enum.GetValues(typeof (ComponentFamily)))
|
||||
{
|
||||
// Hack the update loop to allow us to render somewhere in the GameScreen render loop
|
||||
if (family == ComponentFamily.Renderable)
|
||||
continue;
|
||||
/*if (family == ComponentFamily.Renderable)
|
||||
continue;*/
|
||||
foreach (Component component in components[family])
|
||||
{
|
||||
component.Update(frameTime);
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using SS13_Shared;
|
||||
using SS13_Shared.GO;
|
||||
|
||||
namespace GameObject
|
||||
@@ -93,6 +94,12 @@ namespace GameObject
|
||||
case "boolean":
|
||||
case "bool":
|
||||
return typeof (bool);
|
||||
case "vector2":
|
||||
return typeof(Vector2);
|
||||
case "vector3":
|
||||
return typeof(Vector3);
|
||||
case "vector4":
|
||||
return typeof(Vector4);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -161,6 +168,30 @@ namespace GameObject
|
||||
{
|
||||
paramValue = paramRawValue;
|
||||
}
|
||||
else if (paramType == typeof (Vector2))
|
||||
{
|
||||
var args = paramRawValue.Split(',');
|
||||
if (args.Length != 2)
|
||||
throw new ArgumentException("Could not parse parameter " + paramName +
|
||||
" as Vector2. Value: " + paramRawValue);
|
||||
paramValue = new Vector2(float.Parse(args[0]), float.Parse(args[1]));
|
||||
}
|
||||
else if (paramType == typeof(Vector3))
|
||||
{
|
||||
var args = paramRawValue.Split(',');
|
||||
if (args.Length != 3)
|
||||
throw new ArgumentException("Could not parse parameter " + paramName +
|
||||
" as Vector3. Value: " + paramRawValue);
|
||||
paramValue = new Vector3(float.Parse(args[0]), float.Parse(args[1]), float.Parse(args[2]));
|
||||
}
|
||||
else if (paramType == typeof(Vector4))
|
||||
{
|
||||
var args = paramRawValue.Split(',');
|
||||
if (args.Length != 4)
|
||||
throw new ArgumentException("Could not parse parameter " + paramName +
|
||||
" as Vector4. Value: " + paramRawValue);
|
||||
paramValue = new Vector4(float.Parse(args[0]), float.Parse(args[1]), float.Parse(args[2]), float.Parse(args[3]));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("Could not parse parameter " + paramName +
|
||||
|
||||
@@ -84,13 +84,8 @@ namespace SGO
|
||||
private void SetState(LightState state)
|
||||
{
|
||||
_state = state;
|
||||
SendState();
|
||||
}
|
||||
|
||||
private void SendState()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public override ComponentState GetComponentState()
|
||||
{
|
||||
return new LightComponentState(_state, _colorR, _colorG, _colorB, _mode);
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using GameObject;
|
||||
using SS13.IoC;
|
||||
using SS13_Shared;
|
||||
using SS13_Shared.GO;
|
||||
using SS13_Shared.GO.Component.Light;
|
||||
using SS13_Shared.GO.Component.Particles;
|
||||
using ServerInterfaces.Chat;
|
||||
|
||||
namespace SGO
|
||||
{
|
||||
public class ParticleSystemComponent : Component
|
||||
{
|
||||
private Vector4 _startColor = new Vector4(255, 0, 0, 0);
|
||||
private Vector4 _endColor = new Vector4(0, 0, 0, 0);
|
||||
private bool _active = false;
|
||||
|
||||
public ParticleSystemComponent()
|
||||
{
|
||||
Family = ComponentFamily.Particles;
|
||||
}
|
||||
|
||||
public override void SetParameter(ComponentParameter parameter)
|
||||
{
|
||||
base.SetParameter(parameter);
|
||||
switch (parameter.MemberName)
|
||||
{
|
||||
case "colorStart":
|
||||
_startColor = parameter.GetValue<Vector4>();
|
||||
break;
|
||||
case "colorEnd":
|
||||
_endColor = parameter.GetValue<Vector4>();
|
||||
break;
|
||||
case "startActive":
|
||||
_active = parameter.GetValue<bool>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override ComponentReplyMessage RecieveMessage(object sender, ComponentMessageType type,
|
||||
params object[] list)
|
||||
{
|
||||
ComponentReplyMessage reply = base.RecieveMessage(sender, type, list);
|
||||
|
||||
if (sender == this)
|
||||
return reply;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ComponentMessageType.Activate:
|
||||
HandleClickedInHand();
|
||||
break;
|
||||
}
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
private void HandleClickedInHand()
|
||||
{
|
||||
_active = !_active;
|
||||
}
|
||||
|
||||
public override ComponentState GetComponentState()
|
||||
{
|
||||
return new ParticleSystemComponentState(_active, _startColor, _endColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,6 +83,7 @@
|
||||
<Compile Include="Component\Item\ItemCapability\BreatherCapability.cs" />
|
||||
<Compile Include="Component\Item\ItemCapability\HealthScanCapability.cs" />
|
||||
<Compile Include="Component\Light\LightComponent.cs" />
|
||||
<Compile Include="Component\Particles\ParticleSystemComponent.cs" />
|
||||
<Compile Include="Component\Physics\PhysicsComponent.cs" />
|
||||
<Compile Include="Component\Objectives\ObjectivesComponent.cs" />
|
||||
<Compile Include="Component\PlayerActionComp\PlayerActionCompS.cs" />
|
||||
|
||||
@@ -34,4 +34,12 @@
|
||||
<Component name="ClickableComponent"></Component>
|
||||
</Components>
|
||||
</EntityTemplate>
|
||||
<EntityTemplate name="Particles">
|
||||
<Components>
|
||||
<Component name="TransformComponent"></Component>
|
||||
<Component name="VelocityComponent"></Component>
|
||||
<Component name="NetworkMoverComponent"></Component>
|
||||
<Component name="ParticleSystemComponent"></Component>
|
||||
</Components>
|
||||
</EntityTemplate>
|
||||
</EntityTemplates>
|
||||
@@ -13,6 +13,11 @@
|
||||
<Parameter name="addsprite" type="string" value="sword_on" />
|
||||
</Parameters>
|
||||
</Component>
|
||||
<Component name="ParticleSystemComponent">
|
||||
<Parameters>
|
||||
<Parameter name="particlesPerSecond" type="int" value="30" />
|
||||
</Parameters>
|
||||
</Component>
|
||||
<Component name="PhysicsComponent"></Component>
|
||||
<Component name="ClickableComponent"></Component>
|
||||
<Component name="BasicItemComponent"></Component>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
|
||||
namespace SS13_Shared.GO.Component.Particles
|
||||
{
|
||||
[Serializable]
|
||||
public class ParticleSystemComponentState : ComponentState
|
||||
{
|
||||
public bool Active;
|
||||
public Vector4 StartColor;
|
||||
public Vector4 EndColor;
|
||||
|
||||
public ParticleSystemComponentState(bool active, Vector4 startColor, Vector4 endColor)
|
||||
: base(ComponentFamily.Particles)
|
||||
{
|
||||
Active = active;
|
||||
StartColor = startColor;
|
||||
EndColor = endColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,8 @@
|
||||
Transform,
|
||||
Velocity,
|
||||
Direction,
|
||||
SVars
|
||||
SVars,
|
||||
Particles
|
||||
}
|
||||
|
||||
public enum ItemComponentNetMessage
|
||||
|
||||
@@ -130,6 +130,7 @@
|
||||
<Compile Include="GO\Component\EntityStats\EntityStatsComponentState.cs" />
|
||||
<Compile Include="GO\Component\Light\LightComponentState.cs" />
|
||||
<Compile Include="GO\Component\Mover\MoverComponentState.cs" />
|
||||
<Compile Include="GO\Component\Particles\ParticleSystemComponentState.cs" />
|
||||
<Compile Include="GO\Component\Physics\PhysicsComponentState.cs" />
|
||||
<Compile Include="GO\Component\Renderable\RenderableComponentState.cs" />
|
||||
<Compile Include="GO\Component\Renderable\SpriteComponentState.cs" />
|
||||
@@ -180,6 +181,8 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ChatConfig.cs" />
|
||||
<Compile Include="UIComponents.cs" />
|
||||
<Compile Include="Vector3.cs" />
|
||||
<Compile Include="Vector4.cs" />
|
||||
<Compile Include="VectorEventArgs.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SS13_Shared.Serialization;
|
||||
|
||||
namespace SS13_Shared
|
||||
{
|
||||
[Serializable]
|
||||
public class Vector4
|
||||
: INetSerializableType
|
||||
{
|
||||
#region Class Variables
|
||||
|
||||
/// <summary>
|
||||
/// The X component of the vector
|
||||
/// </summary>
|
||||
private float x;
|
||||
|
||||
/// <summary>
|
||||
/// The Y component of the vector
|
||||
/// </summary>
|
||||
private float y;
|
||||
|
||||
/// <summary>
|
||||
/// The Z component of the vector
|
||||
/// </summary>
|
||||
private float z;
|
||||
|
||||
/// <summary>
|
||||
/// The W component of the vector
|
||||
/// </summary>
|
||||
private float w;
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for the Vector3 class accepting three floats
|
||||
/// </summary>
|
||||
/// <param name="x">The new x value for the Vector3</param>
|
||||
/// <param name="y">The new y value for the Vector3</param>
|
||||
/// <param name="z">The new z value for the Vector3</param>
|
||||
/// <param name="w">The new w value for the Vector3</param>
|
||||
/// <implementation>
|
||||
/// Uses the mutator properties for the Vector3 components to allow verification of input (if implemented)
|
||||
/// This results in the need for pre-initialisation initialisation of the Vector3 components to 0
|
||||
/// Due to the necessity for struct's variables to be set in the constructor before moving control
|
||||
/// </implementation>
|
||||
public Vector4(float x, float y, float z, float w)
|
||||
{
|
||||
// Pre-initialisation initialisation
|
||||
// Implemented because a struct's variables always have to be set in the constructor before moving control
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.z = 0;
|
||||
this.w = 0;
|
||||
|
||||
// Initialisation
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
W = w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for the Vector3 class from another Vector3 object
|
||||
/// </summary>
|
||||
/// <param name="v1">Vector3 representing the new values for the Vector3</param>
|
||||
/// <implementation>
|
||||
/// Copies values from Vector3 v1 to this vector, does not hold a reference to object v1
|
||||
/// </implementation>
|
||||
public Vector4(Vector4 v1)
|
||||
{
|
||||
// Pre-initialisation initialisation
|
||||
// Implemented because a struct's variables always have to be set in the constructor before moving control
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.z = 0;
|
||||
this.w = 0;
|
||||
|
||||
// Initialisation
|
||||
X = v1.X;
|
||||
Y = v1.Y;
|
||||
Z = v1.Z;
|
||||
W = v1.W;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Accessors & Mutators
|
||||
|
||||
/// <summary>
|
||||
/// Property for the x component of the Vector3
|
||||
/// </summary>
|
||||
public float X
|
||||
{
|
||||
get { return x; }
|
||||
set { x = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Property for the y component of the Vector3
|
||||
/// </summary>
|
||||
public float Y
|
||||
{
|
||||
get { return y; }
|
||||
set { y = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Property for the z component of the Vector3
|
||||
/// </summary>
|
||||
public float Z
|
||||
{
|
||||
get { return z; }
|
||||
set { z = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Property for the w component of the Vector3
|
||||
/// </summary>
|
||||
public float W
|
||||
{
|
||||
get { return w; }
|
||||
set { w = value; }
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -27,4 +27,11 @@
|
||||
<Component name="BasicInteractableComponent"></Component>
|
||||
</Components>
|
||||
</EntityTemplate>
|
||||
<EntityTemplate name="Particles">
|
||||
<Components>
|
||||
<Component name="TransformComponent"></Component>
|
||||
<Component name="VelocityComponent"></Component>
|
||||
<Component name="BasicMoverComponent"></Component>
|
||||
</Components>
|
||||
</EntityTemplate>
|
||||
</EntityTemplates>
|
||||
@@ -34,6 +34,13 @@
|
||||
<Parameter name="startState" type="string" value="Off" />
|
||||
</Parameters>
|
||||
</Component>
|
||||
<Component name="ParticleSystemComponent">
|
||||
<Parameters>
|
||||
<Parameter name="colorStart" type="Vector4" value="255,128,200,255" />
|
||||
<Parameter name="colorEnd" type="Vector4" value="80,104,180,255" />
|
||||
<Parameter name="startActive" type="bool" value="false" />
|
||||
</Parameters>
|
||||
</Component>
|
||||
</Components>
|
||||
</EntityTemplate>
|
||||
</EntityTemplates>
|
||||
@@ -113,7 +113,8 @@ namespace ServerServices.Placement
|
||||
{
|
||||
created.GetComponent<ITransformComponent>(ComponentFamily.Transform).TranslateTo(
|
||||
new Vector2(xRcv, yRcv));
|
||||
created.GetComponent<IDirectionComponent>(ComponentFamily.Direction).Direction = dirRcv;
|
||||
if(created.HasComponent(ComponentFamily.Direction))
|
||||
created.GetComponent<IDirectionComponent>(ComponentFamily.Direction).Direction = dirRcv;
|
||||
created.SendMessage(this, ComponentMessageType.WallMountTile, new Vector2(tileX, tileY));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
call runclient.bat
|
||||
call runclient.bat
|
||||
Reference in New Issue
Block a user