Particles using display coordinates, particle growtime, character death&stun animations
This commit is contained in:
@@ -29,34 +29,53 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
public void SpawnSprites(int count)
|
||||
{
|
||||
if (activeSprites.Count < MaxSprites)
|
||||
{
|
||||
WayPoint wp = WayPoint.WayPointList[Rand.Int(WayPoint.WayPointList.Count)];
|
||||
count = Math.Min(count, MaxSprites);
|
||||
|
||||
Vector2 pos = new Vector2(wp.Rect.X, wp.Rect.Y);
|
||||
pos += Rand.Vector(200.0f);
|
||||
activeSprites.Clear();
|
||||
|
||||
for (int i = 0; i < count; i++ )
|
||||
{
|
||||
Vector2 pos = Vector2.Zero;
|
||||
|
||||
if (WayPoint.WayPointList.Count>0)
|
||||
{
|
||||
WayPoint wp = WayPoint.WayPointList[Rand.Int(WayPoint.WayPointList.Count)];
|
||||
|
||||
pos = new Vector2(wp.Rect.X, wp.Rect.Y);
|
||||
pos += Rand.Vector(200.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = Rand.Vector(2000.0f);
|
||||
}
|
||||
|
||||
var prefab = prefabs[Rand.Int(prefabs.Count)];
|
||||
|
||||
int amount = Rand.Range(prefab.SwarmMin,prefab.SwarmMax);
|
||||
int amount = Rand.Range(prefab.SwarmMin, prefab.SwarmMax);
|
||||
List<BackgroundSprite> swarmMembers = new List<BackgroundSprite>();
|
||||
|
||||
for (int i = 0; i<amount; i++)
|
||||
|
||||
for (int n = 0; n < amount; n++)
|
||||
{
|
||||
var newSprite = new BackgroundSprite(prefab, pos);
|
||||
activeSprites.Add(newSprite);
|
||||
swarmMembers.Add(newSprite);
|
||||
}
|
||||
if (amount>0)
|
||||
if (amount > 0)
|
||||
{
|
||||
Swarm swarm = new Swarm(swarmMembers, prefab.SwarmRadius);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearSprites()
|
||||
{
|
||||
activeSprites.Clear();
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
foreach (BackgroundSprite sprite in activeSprites)
|
||||
{
|
||||
sprite.Update(deltaTime);
|
||||
|
||||
@@ -940,13 +940,13 @@ namespace Subsurface
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
Particle p = Game1.ParticleManager.CreateParticle("waterblood",
|
||||
torso.SimPosition + new Vector2(Rand.Range(-0.5f, 0.5f), Rand.Range(-0.5f, 0.5f)),
|
||||
torso.Position + new Vector2(Rand.Range(-50f, 50f), Rand.Range(-50f, 50f)),
|
||||
Vector2.Zero);
|
||||
if (p!=null) p.Size *= 2.0f;
|
||||
|
||||
Game1.ParticleManager.CreateParticle("bubbles",
|
||||
torso.SimPosition,
|
||||
new Vector2(Rand.Range(-0.5f, 0.5f), Rand.Range(-1.0f,0.5f)));
|
||||
new Vector2(Rand.Range(-50f, 50f), Rand.Range(-100f,50f)));
|
||||
}
|
||||
|
||||
foreach (var joint in AnimController.limbJoints)
|
||||
@@ -956,6 +956,21 @@ namespace Subsurface
|
||||
Kill(true);
|
||||
}
|
||||
|
||||
private IEnumerable<object> DeathAnim()
|
||||
{
|
||||
float timer = 8.0f;
|
||||
|
||||
while (timer > 0.0f)
|
||||
{
|
||||
AnimController.UpdateAnim(1.0f / 60.0f);
|
||||
timer -= 1.0f / 60.0f;
|
||||
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
public void Kill(bool networkMessage = false)
|
||||
{
|
||||
if (isDead) return;
|
||||
@@ -973,6 +988,8 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
CoroutineManager.StartCoroutine(DeathAnim());
|
||||
|
||||
health = 0.0f;
|
||||
|
||||
isDead = true;
|
||||
@@ -1086,11 +1103,8 @@ namespace Subsurface
|
||||
}
|
||||
else
|
||||
{
|
||||
Limb torso = AnimController.GetLimb(LimbType.Torso);
|
||||
if (torso == null) torso = AnimController.GetLimb(LimbType.Head);
|
||||
|
||||
message.Write(torso.body.Position.X);
|
||||
message.Write(torso.body.Position.Y);
|
||||
message.Write(AnimController.RefLimb.Position.X);
|
||||
message.Write(AnimController.RefLimb.Position.Y);
|
||||
|
||||
LargeUpdateTimer = Math.Max(0, LargeUpdateTimer-1);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,11 @@ namespace Subsurface
|
||||
swimSpeed = ToolBox.GetAttributeFloat(element, "swimspeed", 1.0f);
|
||||
|
||||
float footRot = ToolBox.GetAttributeFloat(element,"footrotation", float.NaN);
|
||||
if (!float.IsNaN(footRot))
|
||||
if (float.IsNaN(footRot))
|
||||
{
|
||||
footRotation = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
footRotation = MathHelper.ToRadians(footRot);
|
||||
}
|
||||
@@ -44,6 +48,12 @@ namespace Subsurface
|
||||
|
||||
public override void UpdateAnim(float deltaTime)
|
||||
{
|
||||
if (character.IsDead)
|
||||
{
|
||||
UpdateStruggling(deltaTime);
|
||||
return;
|
||||
}
|
||||
|
||||
ResetPullJoints();
|
||||
|
||||
if (strongestImpact > 0.0f)
|
||||
@@ -54,7 +64,7 @@ namespace Subsurface
|
||||
|
||||
if (stunTimer>0.0f)
|
||||
{
|
||||
UpdateStruggling();
|
||||
UpdateStruggling(deltaTime);
|
||||
stunTimer -= deltaTime;
|
||||
return;
|
||||
}
|
||||
@@ -204,25 +214,27 @@ namespace Subsurface
|
||||
movement = MathUtils.SmoothStep(movement, TargetMovement * walkSpeed, 0.2f);
|
||||
if (movement == Vector2.Zero) return;
|
||||
|
||||
IgnorePlatforms = (TargetMovement.Y < -Math.Abs(TargetMovement.X));
|
||||
|
||||
Limb colliderLimb;
|
||||
float colliderHeight;
|
||||
|
||||
Limb torso = GetLimb(LimbType.Torso);
|
||||
Limb head = GetLimb(LimbType.Head);
|
||||
Limb torso = GetLimb(LimbType.Torso);
|
||||
Limb head = GetLimb(LimbType.Head);
|
||||
|
||||
if (torso!=null)
|
||||
if (torso != null)
|
||||
{
|
||||
colliderLimb = torso;
|
||||
colliderHeight = TorsoPosition;
|
||||
|
||||
colliderLimb.body.SmoothRotate(TorsoAngle*Dir, 10.0f);
|
||||
colliderLimb.body.SmoothRotate(TorsoAngle * Dir, 10.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
colliderLimb = head;
|
||||
colliderHeight = HeadPosition;
|
||||
|
||||
if (onGround) colliderLimb.body.SmoothRotate(HeadAngle*Dir, 100.0f);
|
||||
if (onGround) colliderLimb.body.SmoothRotate(HeadAngle * Dir, 100.0f);
|
||||
}
|
||||
|
||||
Vector2 colliderPos = colliderLimb.SimPosition;
|
||||
@@ -331,13 +343,24 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateStruggling()
|
||||
void UpdateStruggling(float deltaTime)
|
||||
{
|
||||
Limb head = GetLimb(LimbType.Head);
|
||||
Limb tail = GetLimb(LimbType.Tail);
|
||||
|
||||
if (head != null) head.body.ApplyTorque(head.Mass * Dir * 0.1f);
|
||||
if (tail != null) tail.body.ApplyTorque(tail.Mass * -Dir * 0.1f);
|
||||
if (head != null) head.body.ApplyTorque(head.Mass * Dir * (float)Math.Sin(walkPos) * 5.0f);
|
||||
if (tail != null) tail.body.ApplyTorque(tail.Mass * -Dir * (float)Math.Sin(walkPos) * 5.0f);
|
||||
|
||||
walkPos += deltaTime * 5.0f;
|
||||
|
||||
Vector2 centerOfMass = GetCenterOfMass();
|
||||
|
||||
foreach (Limb limb in limbs)
|
||||
{
|
||||
if (limb.type == LimbType.Head || limb.type == LimbType.Tail) continue;
|
||||
|
||||
limb.body.ApplyForce((centerOfMass - limb.SimPosition) * (float)Math.Sin(walkPos) * limb.Mass * 10.0f);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Flip()
|
||||
|
||||
@@ -18,6 +18,12 @@ namespace Subsurface
|
||||
|
||||
public override void UpdateAnim(float deltaTime)
|
||||
{
|
||||
if (character.IsDead)
|
||||
{
|
||||
UpdateStruggling();
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 colliderPos = GetLimb(LimbType.Torso).SimPosition;
|
||||
|
||||
if (inWater) stairs = null;
|
||||
@@ -543,12 +549,9 @@ namespace Subsurface
|
||||
leftHandPos = Vector2.Transform(leftHandPos, rotationMatrix);
|
||||
|
||||
MoveLimb(leftHand, handPos + leftHandPos, 3.5f);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void UpdateClimbing()
|
||||
{
|
||||
if (character.SelectedConstruction == null || character.SelectedConstruction.GetComponent<Ladder>()==null)
|
||||
@@ -662,14 +665,17 @@ namespace Subsurface
|
||||
Limb rightLeg = GetLimb(LimbType.RightFoot);
|
||||
Limb torso = GetLimb(LimbType.Torso);
|
||||
|
||||
walkPos += 0.2f;
|
||||
//walkPos += 0.2f;
|
||||
|
||||
if (inWater) return;
|
||||
|
||||
Vector2 footPos = torso.body.Position+ new Vector2(TorsoPosition*Dir,0.0f);
|
||||
HandIK(GetLimb(LimbType.RightHand), GetLimb(LimbType.Head).SimPosition,0.1f);
|
||||
HandIK(GetLimb(LimbType.LeftHand), GetLimb(LimbType.Head).SimPosition,0.1f);
|
||||
|
||||
//Vector2 footPos = torso.body.Position+ new Vector2(TorsoPosition*Dir,0.0f);
|
||||
|
||||
MoveLimb(leftLeg, footPos, 0.7f);
|
||||
MoveLimb(rightLeg, footPos, 0.7f);
|
||||
//MoveLimb(leftLeg, footPos, 0.7f);
|
||||
//MoveLimb(rightLeg, footPos, 0.7f);
|
||||
}
|
||||
|
||||
public override void HoldItem(float deltaTime, Camera cam, Item item, Vector2[] handlePos, Vector2 holdPos, Vector2 aimPos, float holdAngle)
|
||||
@@ -690,7 +696,7 @@ namespace Subsurface
|
||||
Vector2 itemPos = character.GetInputState(InputType.SecondaryHeld) ? aimPos : holdPos;
|
||||
|
||||
float itemAngle;
|
||||
if (character.GetInputState(InputType.SecondaryHeld) && itemPos != Vector2.Zero)
|
||||
if (stunTimer <= 0.0f && character.GetInputState(InputType.SecondaryHeld) && itemPos != Vector2.Zero)
|
||||
{
|
||||
Vector2 mousePos = ConvertUnits.ToSimUnits(character.CursorPosition);
|
||||
|
||||
@@ -767,27 +773,54 @@ namespace Subsurface
|
||||
if (itemPos == Vector2.Zero) continue;
|
||||
|
||||
Limb hand = (i == 0) ? rightHand : leftHand;
|
||||
Limb arm = (i == 0) ? rightArm : leftArm;
|
||||
|
||||
//hand length
|
||||
float a = 37.0f;
|
||||
HandIK(hand, transformedHoldPos + transformedHandlePos[i]);
|
||||
|
||||
//arm length
|
||||
float b = 28.0f;
|
||||
//Limb arm = (i == 0) ? rightArm : leftArm;
|
||||
|
||||
//distance from shoulder to holdpos
|
||||
float c = ConvertUnits.ToDisplayUnits(Vector2.Distance(transformedHoldPos + transformedHandlePos[i], shoulderPos));
|
||||
c = MathHelper.Clamp(a + b - 1, b-a, c);
|
||||
////hand length
|
||||
//float a = 37.0f;
|
||||
|
||||
float ang2 = MathUtils.VectorToAngle((transformedHoldPos + transformedHandlePos[i]) - shoulderPos)+MathHelper.PiOver2;
|
||||
////arm length
|
||||
//float b = 28.0f;
|
||||
|
||||
float armAngle = MathUtils.SolveTriangleSSS(a, b, c);
|
||||
float handAngle = MathUtils.SolveTriangleSSS(b, a, c);
|
||||
////distance from shoulder to holdpos
|
||||
//float c = ConvertUnits.ToDisplayUnits(Vector2.Distance(transformedHoldPos + transformedHandlePos[i], shoulderPos));
|
||||
//c = MathHelper.Clamp(a + b - 1, b-a, c);
|
||||
|
||||
arm.body.SmoothRotate((ang2 - armAngle * Dir), 20.0f);
|
||||
hand.body.SmoothRotate((ang2 + handAngle * Dir), 100.0f);
|
||||
}
|
||||
|
||||
//float ang2 = MathUtils.VectorToAngle((transformedHoldPos + transformedHandlePos[i]) - shoulderPos)+MathHelper.PiOver2;
|
||||
|
||||
//float armAngle = MathUtils.SolveTriangleSSS(a, b, c);
|
||||
//float handAngle = MathUtils.SolveTriangleSSS(b, a, c);
|
||||
|
||||
//arm.body.SmoothRotate((ang2 - armAngle * Dir), 20.0f);
|
||||
//hand.body.SmoothRotate((ang2 + handAngle * Dir), 100.0f);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandIK(Limb hand, Vector2 pos, float force = 1.0f)
|
||||
{
|
||||
Vector2 shoulderPos = limbJoints[2].WorldAnchorA;
|
||||
|
||||
Limb arm = (hand.type == LimbType.LeftHand) ? GetLimb(LimbType.LeftArm) : GetLimb(LimbType.RightArm);
|
||||
|
||||
//hand length
|
||||
float a = 37.0f;
|
||||
|
||||
//arm length
|
||||
float b = 28.0f;
|
||||
|
||||
//distance from shoulder to holdpos
|
||||
float c = ConvertUnits.ToDisplayUnits(Vector2.Distance(pos, shoulderPos));
|
||||
c = MathHelper.Clamp(a + b - 1, b - a, c);
|
||||
|
||||
float ang2 = MathUtils.VectorToAngle(pos - shoulderPos) + MathHelper.PiOver2;
|
||||
|
||||
float armAngle = MathUtils.SolveTriangleSSS(a, b, c);
|
||||
float handAngle = MathUtils.SolveTriangleSSS(b, a, c);
|
||||
|
||||
arm.body.SmoothRotate((ang2 - armAngle * Dir), 20.0f*force);
|
||||
hand.body.SmoothRotate((ang2 + handAngle * Dir), 100.0f*force);
|
||||
}
|
||||
|
||||
public override void Flip()
|
||||
|
||||
@@ -337,13 +337,13 @@ namespace Subsurface
|
||||
if (particleVel != Vector2.Zero) particleVel = Vector2.Normalize(particleVel);
|
||||
|
||||
Game1.ParticleManager.CreateParticle("blood",
|
||||
SimPosition,
|
||||
particleVel * Rand.Range(1.0f, 3.0f));
|
||||
Position,
|
||||
particleVel * Rand.Range(100.0f, 300.0f));
|
||||
}
|
||||
|
||||
for (int i = 0; i < bloodAmount / 2; i++)
|
||||
{
|
||||
Game1.ParticleManager.CreateParticle("waterblood", SimPosition, Vector2.Zero);
|
||||
Game1.ParticleManager.CreateParticle("waterblood", Position, Vector2.Zero);
|
||||
}
|
||||
|
||||
return new AttackResult(amount, bleedingAmount, hitArmor);
|
||||
|
||||
@@ -49,6 +49,8 @@ namespace Subsurface
|
||||
public bool onGround;
|
||||
private bool ignorePlatforms;
|
||||
|
||||
private Limb refLimb;
|
||||
|
||||
protected Structure stairs;
|
||||
|
||||
protected Direction dir;
|
||||
@@ -60,6 +62,14 @@ namespace Subsurface
|
||||
get { return lowestLimb; }
|
||||
}
|
||||
|
||||
public Limb RefLimb
|
||||
{
|
||||
get
|
||||
{
|
||||
return refLimb;
|
||||
}
|
||||
}
|
||||
|
||||
public float Mass
|
||||
{
|
||||
get;
|
||||
@@ -226,6 +236,10 @@ namespace Subsurface
|
||||
|
||||
}
|
||||
|
||||
refLimb = GetLimb(LimbType.Torso);
|
||||
if (refLimb == null) refLimb = GetLimb(LimbType.Head);
|
||||
if (refLimb == null) DebugConsole.ThrowError("Character ''" + character + "'' doesn't have a head or torso!");
|
||||
|
||||
foreach (var joint in limbJoints)
|
||||
{
|
||||
|
||||
@@ -348,14 +362,12 @@ namespace Subsurface
|
||||
if (limb.pullJoint != null)
|
||||
{
|
||||
Vector2 pos = ConvertUnits.ToDisplayUnits(limb.pullJoint.WorldAnchorA);
|
||||
pos.Y = -pos.Y;
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)pos.Y, 5, 5), Color.Red, true, 0.01f);
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 5, 5), Color.Red, true, 0.01f);
|
||||
|
||||
if (limb.AnimTargetPos == Vector2.Zero) continue;
|
||||
|
||||
Vector2 pos2 = ConvertUnits.ToDisplayUnits(limb.AnimTargetPos);
|
||||
pos2.Y = -pos2.Y;
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos2.X, (int)pos2.Y, 5, 5), Color.Blue, true, 0.01f);
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos2.X, (int)-pos2.Y, 5, 5), Color.Blue, true, 0.01f);
|
||||
|
||||
GUI.DrawLine(spriteBatch, pos, pos2, Color.Green);
|
||||
}
|
||||
@@ -368,7 +380,14 @@ namespace Subsurface
|
||||
|
||||
pos = ConvertUnits.ToDisplayUnits(joint.WorldAnchorB);
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 5, 5), Color.White, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (refLimb.body.TargetPosition != Vector2.Zero)
|
||||
{
|
||||
Vector2 pos = ConvertUnits.ToDisplayUnits(refLimb.body.TargetPosition);
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X-5, (int)-pos.Y-5, 10, 10), Color.LightBlue, false);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -531,17 +550,17 @@ namespace Subsurface
|
||||
|
||||
//create a splash particle
|
||||
Subsurface.Particles.Particle splash = Game1.ParticleManager.CreateParticle("watersplash",
|
||||
new Vector2(limb.SimPosition.X, ConvertUnits.ToSimUnits(limbHull.Surface)),
|
||||
new Vector2(0.0f, Math.Abs(-limb.LinearVelocity.Y * 0.1f)),
|
||||
new Vector2(limb.Position.X, limbHull.Surface),
|
||||
new Vector2(0.0f, Math.Abs(-limb.LinearVelocity.Y * 10.0f)),
|
||||
0.0f);
|
||||
|
||||
if (splash != null) splash.yLimits = ConvertUnits.ToSimUnits(
|
||||
new Vector2(
|
||||
limbHull.Rect.Y,
|
||||
limbHull.Rect.Y - limbHull.Rect.Height));
|
||||
//if (splash != null) splash.yLimits = ConvertUnits.ToSimUnits(
|
||||
// new Vector2(
|
||||
// limbHull.Rect.Y,
|
||||
// limbHull.Rect.Y - limbHull.Rect.Height));
|
||||
|
||||
Game1.ParticleManager.CreateParticle("bubbles",
|
||||
new Vector2(limb.SimPosition.X, ConvertUnits.ToSimUnits(limbHull.Surface)),
|
||||
new Vector2(limb.Position.X, limbHull.Surface),
|
||||
limb.LinearVelocity*0.001f,
|
||||
0.0f);
|
||||
|
||||
@@ -572,9 +591,6 @@ namespace Subsurface
|
||||
|
||||
private void UpdateNetplayerPosition()
|
||||
{
|
||||
Limb refLimb = GetLimb(LimbType.Torso);
|
||||
if (refLimb == null) refLimb = GetLimb(LimbType.Head);
|
||||
|
||||
if (refLimb.body.TargetPosition == Vector2.Zero) return;
|
||||
|
||||
//if the limb is further away than resetdistance, all limbs are immediately snapped to their targetpositions
|
||||
@@ -583,7 +599,7 @@ namespace Subsurface
|
||||
//if the limb is closer than alloweddistance, just ignore the difference
|
||||
float allowedDistance = NetConfig.AllowedRagdollDistance;
|
||||
|
||||
float dist = Vector2.Distance(limbs[0].body.Position, refLimb.body.TargetPosition);
|
||||
float dist = Vector2.Distance(refLimb.body.Position, refLimb.body.TargetPosition);
|
||||
bool resetAll = (dist > resetDistance && character.LargeUpdateTimer == 1);
|
||||
|
||||
Vector2 newMovement = (refLimb.body.TargetPosition - refLimb.body.Position);
|
||||
|
||||
Reference in New Issue
Block a user