Melee weapons (+ stun baton), improved throw animation, new damage sound effects

This commit is contained in:
Regalis
2015-09-07 16:31:04 +03:00
parent b77fa5df90
commit 7eae6fb026
38 changed files with 527 additions and 163 deletions

View File

@@ -170,7 +170,7 @@ namespace Subsurface.Items.Components
transformedItemPos = Vector2.Transform(transformedItemPos, transform);
transformedItemInterval = Vector2.Transform(transformedItemInterval, transform);
transformedItemPos += ConvertUnits.ToDisplayUnits(item.body.Position);
transformedItemPos += ConvertUnits.ToDisplayUnits(item.body.SimPosition);
currentRotation += item.body.Rotation;
}

View File

@@ -216,7 +216,7 @@ namespace Subsurface.Items.Components
//LinkedGap.Move(amount);
body.SetTransform(body.Position + ConvertUnits.ToSimUnits(amount), 0.0f);
body.SetTransform(body.SimPosition + ConvertUnits.ToSimUnits(amount), 0.0f);
convexHull.Move(amount);
if (convexHull2 != null) convexHull2.Move(amount);

View File

@@ -223,7 +223,7 @@ namespace Subsurface.Items.Components
//item.sprite.Depth = picker.AnimController.GetLimb(LimbType.RightHand).sprite.Depth + 0.01f;
ac.HoldItem(deltaTime, cam, item, handlePos, holdPos, aimPos, holdAngle);
ac.HoldItem(deltaTime, item, handlePos, holdPos, aimPos, picker.GetInputState(InputType.SecondaryHeld), holdAngle);
}
protected void Flip(Item item)

View File

@@ -0,0 +1,189 @@
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Contacts;
using Microsoft.Xna.Framework;
using System.Xml.Linq;
namespace Subsurface.Items.Components
{
class MeleeWeapon : Holdable
{
private float hitPos;
private bool hitting;
private Attack attack;
private float range;
[HasDefaultValue(0.0f, false)]
public float Range
{
get { return ConvertUnits.ToDisplayUnits(range); }
set { range = ConvertUnits.ToSimUnits(value); }
}
public MeleeWeapon(Item item, XElement element)
: base(item, element)
{
//throwForce = ToolBox.GetAttributeFloat(element, "throwforce", 1.0f);
foreach (XElement subElement in element.Elements())
{
if (subElement.Name.ToString().ToLower() != "attack") continue;
attack = new Attack(subElement);
}
if (attack==null)
{
DebugConsole.ThrowError("Item ''"+item.Name+"'' doesn't have an attack configured");
}
}
public override bool Use(float deltaTime, Character character = null)
{
if (character == null) return false;
if (!character.GetInputState(InputType.SecondaryHeld) || hitting) return false;
if (hitPos < MathHelper.Pi * 0.69f) return false;
item.body.FarseerBody.CollisionCategories = Physics.CollisionProjectile;
item.body.FarseerBody.CollidesWith = Physics.CollisionCharacter | Physics.CollisionWall;
item.body.FarseerBody.OnCollision += OnCollision;
foreach (Limb l in character.AnimController.limbs)
{
item.body.FarseerBody.IgnoreCollisionWith(l.body.FarseerBody);
if (l.type == LimbType.LeftFoot || l.type == LimbType.LeftThigh || l.type == LimbType.LeftLeg) continue;
if (l.type == LimbType.Head || l.type == LimbType.Torso)
{
l.body.ApplyLinearImpulse(new Vector2(character.AnimController.Dir * 7.0f, -4.0f));
}
else
{
l.body.ApplyLinearImpulse(new Vector2(character.AnimController.Dir * 5.0f, -2.0f));
}
}
hitting = true;
isActive = true;
return true;
}
public override void Drop(Character dropper)
{
base.Drop(dropper);
hitting = false;
hitPos = 0.0f;
}
public override void UpdateBroken(float deltaTime, Camera cam)
{
Update(deltaTime, cam);
}
public override void Update(float deltaTime, Camera cam)
{
if (!item.body.Enabled) return;
if (!picker.HasSelectedItem(item)) isActive = false;
if (!picker.GetInputState(InputType.SecondaryHeld) && !hitting) hitPos = 0.0f;
ApplyStatusEffects(ActionType.OnActive, deltaTime, picker);
if (item.body.Dir != picker.AnimController.Dir) Flip(item);
AnimController ac = picker.AnimController;
Limb rightHand = ac.GetLimb(LimbType.RightHand);
if (!hitting)
{
if (picker.GetInputState(InputType.SecondaryHeld))
{
hitPos = (float)System.Math.Min(hitPos+deltaTime*5.0f, MathHelper.Pi*0.7f);
ac.HoldItem(deltaTime, item, handlePos, new Vector2(0.6f, -0.1f), new Vector2(-0.3f, 0.2f), false, hitPos);
}
else
{
ac.HoldItem(deltaTime, item, handlePos, new Vector2(hitPos, 0.0f), aimPos, false, 0.0f);
}
}
else
{
//Vector2 diff = Vector2.Normalize(picker.CursorPosition - ac.RefLimb.Position);
//diff.X = diff.X * ac.Dir;
hitPos -= deltaTime*15.0f;
//angl = -hitPos * 2.0f;
// System.Diagnostics.Debug.WriteLine("<1.0f "+hitPos);
ac.HoldItem(deltaTime, item, handlePos, new Vector2(0.6f, -0.1f), new Vector2(-0.3f, 0.2f), false, hitPos);
//}
//else
//{
// System.Diagnostics.Debug.WriteLine(">1.0f " + hitPos);
// ac.HoldItem(deltaTime, item, handlePos, new Vector2(0.5f, 0.2f), new Vector2(1.0f, 0.2f), false, 0.0f);
//}
if (hitPos < -MathHelper.PiOver4*1.2f)
{
RestoreCollision();
hitting = false;
}
}
}
private void RestoreCollision()
{
item.body.FarseerBody.OnCollision -= OnCollision;
item.body.CollisionCategories = Physics.CollisionMisc;
item.body.CollidesWith = Physics.CollisionWall;
foreach (Limb l in picker.AnimController.limbs)
{
item.body.FarseerBody.RestoreCollisionWith(l.body.FarseerBody);
}
}
private bool OnCollision(Fixture f1, Fixture f2, Contact contact)
{
IDamageable target = null;
Limb limb = f2.Body.UserData as Limb;
if (limb != null)
{
if (limb.character == picker) return false;
target = limb.character;
}
if (target==null)
{
target = f2.Body.UserData as IDamageable;
}
if (target == null) return false;
attack.DoDamage(target, item.Position, 1.0f);
RestoreCollision();
hitting = false;
return true;
}
}
}

View File

@@ -28,7 +28,7 @@ namespace Subsurface.Items.Components
Matrix bodyTransform = Matrix.CreateRotationZ(item.body.Rotation);
Vector2 flippedPos = barrelPos;
if (item.body.Dir < 0.0f) flippedPos.X = -flippedPos.X;
return (Vector2.Transform(flippedPos, bodyTransform) + item.body.Position);
return (Vector2.Transform(flippedPos, bodyTransform) + item.body.SimPosition);
}
}

View File

@@ -65,7 +65,7 @@ namespace Subsurface.Items.Components
Matrix bodyTransform = Matrix.CreateRotationZ(item.body.Rotation);
Vector2 flippedPos = barrelPos;
if (item.body.Dir < 0.0f) flippedPos.X = -flippedPos.X;
return (Vector2.Transform(flippedPos, bodyTransform) + item.body.Position);
return (Vector2.Transform(flippedPos, bodyTransform) + item.body.SimPosition);
}
}
@@ -108,7 +108,7 @@ namespace Subsurface.Items.Components
isActive = true;
Vector2 targetPosition = item.body.Position;
Vector2 targetPosition = item.body.SimPosition;
//targetPosition = targetPosition.X, -targetPosition.Y);
targetPosition += new Vector2(

View File

@@ -30,6 +30,22 @@ namespace Subsurface.Items.Components
if (character == null) return false;
if (!character.GetInputState(InputType.SecondaryHeld) || throwing) return false;
//Vector2 diff = Vector2.Normalize(character.CursorPosition - character.AnimController.RefLimb.Position);
//if (character.SelectedItems[1]==item)
//{
// Limb leftHand = character.AnimController.GetLimb(LimbType.LeftHand);
// leftHand.body.ApplyLinearImpulse(diff * 20.0f);
// leftHand.Disabled = true;
//}
//if (character.SelectedItems[0] == item)
//{
// Limb rightHand = character.AnimController.GetLimb(LimbType.RightHand);
// rightHand.body.ApplyLinearImpulse(diff * 20.0f);
// rightHand.Disabled = true;
//}
throwing = true;
isActive = true;
@@ -39,7 +55,6 @@ namespace Subsurface.Items.Components
public override void SecondaryUse(float deltaTime, Character character = null)
{
if (throwing) return;
throwPos = 0.25f;
}
public override void Drop(Character dropper)
@@ -68,31 +83,59 @@ namespace Subsurface.Items.Components
AnimController ac = picker.AnimController;
ac.HoldItem(deltaTime, cam, item, handlePos, new Vector2(throwPos, 0.0f), aimPos, holdAngle);
if (!throwing) return;
throwPos += deltaTime*5.0f;
Vector2 throwVector = ConvertUnits.ToSimUnits(picker.CursorPosition) - item.body.Position;
throwVector = Vector2.Normalize(throwVector);
if (handlePos[0]!=Vector2.Zero)
if (!throwing)
{
Limb leftHand = ac.GetLimb(LimbType.LeftHand);
leftHand.body.ApplyForce(throwVector*10.0f);
if (picker.GetInputState(InputType.SecondaryHeld))
{
throwPos = (float)System.Math.Min(throwPos+deltaTime*5.0f, MathHelper.Pi*0.7f);
ac.HoldItem(deltaTime, item, handlePos, new Vector2(0.6f, -0.0f), new Vector2(-0.3f, 0.2f), false, throwPos);
}
else
{
ac.HoldItem(deltaTime, item, handlePos, new Vector2(throwPos, 0.0f), aimPos, false, 0.0f);
}
}
else
{
//Vector2 diff = Vector2.Normalize(picker.CursorPosition - ac.RefLimb.Position);
//diff.X = diff.X * ac.Dir;
if (handlePos[1] != Vector2.Zero)
{
Limb rightHand = ac.GetLimb(LimbType.RightHand);
rightHand.body.ApplyForce(throwVector * 10.0f);
}
if (throwPos>1.0f)
{
item.Drop();
item.body.ApplyLinearImpulse(throwVector * throwForce * item.body.Mass * 3.0f);
throwPos -= deltaTime*15.0f;
//angl = -hitPos * 2.0f;
// System.Diagnostics.Debug.WriteLine("<1.0f "+hitPos);
ac.HoldItem(deltaTime, item, handlePos, new Vector2(0.6f, 0.0f), new Vector2(-0.3f, 0.2f), false, throwPos);
//}
//else
//{
// System.Diagnostics.Debug.WriteLine(">1.0f " + hitPos);
// ac.HoldItem(deltaTime, item, handlePos, new Vector2(0.5f, 0.2f), new Vector2(1.0f, 0.2f), false, 0.0f);
//}
if (throwPos < -0.0)
{
Vector2 throwVector = picker.CursorPosition - picker.AnimController.RefLimb.Position;
throwVector = Vector2.Normalize(throwVector);
item.Drop();
item.body.ApplyLinearImpulse(throwVector * throwForce * item.body.Mass * 3.0f);
ac.GetLimb(LimbType.Head).body.ApplyLinearImpulse(throwVector*10.0f);
ac.GetLimb(LimbType.Torso).body.ApplyLinearImpulse(throwVector * 10.0f);
Limb rightHand = ac.GetLimb(LimbType.RightHand);
item.body.AngularVelocity = rightHand.body.AngularVelocity;
throwing = false;
}
}
}
}

View File

@@ -99,7 +99,7 @@ namespace Subsurface.Items.Components
pingCircle.Draw(spriteBatch, center, Color.White * (1.0f-pingState), 0.0f, (rect.Width/pingCircle.size.X)*pingState);
}
float radius = pingCircle.size.X / 2.0f;
float radius = rect.Width / 2.0f;
float simScale = 1.5f;
float displayScale = 0.015f;

View File

@@ -200,7 +200,7 @@ namespace Subsurface.Items.Components
{
if (stickJoint != null) return false;
stickJoint = new PrismaticJoint(targetBody, item.body.FarseerBody, item.body.Position, axis, true);
stickJoint = new PrismaticJoint(targetBody, item.body.FarseerBody, item.body.SimPosition, axis, true);
stickJoint.MotorEnabled = true;
stickJoint.MaxMotorForce = 30.0f;

View File

@@ -83,8 +83,8 @@ namespace Subsurface.Items.Components
Path ropePath = new Path();
ropePath.Add(item.body.Position);
ropePath.Add(item.body.Position + new Vector2(length, 0.0f));
ropePath.Add(item.body.SimPosition);
ropePath.Add(item.body.SimPosition + new Vector2(length, 0.0f));
ropePath.Closed = false;
Vertices box = PolygonTools.CreateRectangle(sectionLength, 0.05f);
@@ -202,7 +202,7 @@ namespace Subsurface.Items.Components
if (Vector2.Distance(TransformedBarrelPos, projectile.SimPosition)>len*sectionLength)
{
Vector2 stopForce = projectile.SimPosition - ropeBodies[ropeBodies.Length-1].Position;
Vector2 stopForce = projectile.SimPosition - ropeBodies[ropeBodies.Length-1].SimPosition;
stopForce = Vector2.Normalize(stopForce);
float dotProduct = Vector2.Dot(stopForce, Vector2.Normalize(projectile.body.LinearVelocity));
@@ -286,7 +286,7 @@ namespace Subsurface.Items.Components
foreach (PhysicsBody b in ropeBodies)
{
b.SetTransform(item.body.Position, 0.0f);
b.SetTransform(item.body.SimPosition, 0.0f);
b.UserData = false;
b.Enabled = true;
}
@@ -296,7 +296,7 @@ namespace Subsurface.Items.Components
if (joint!=null) joint.Enabled = true;
}
ropeBodies[ropeBodies.Length - 1].SetTransform(projectile.body.Position, projectile.body.Rotation);
ropeBodies[ropeBodies.Length - 1].SetTransform(projectile.body.SimPosition, projectile.body.Rotation);
//attach projectile to the last section of the rope
if (ropeJoints[ropeJoints.Length-1] != null) Game1.World.RemoveJoint(ropeJoints[ropeJoints.Length-1]);

View File

@@ -86,7 +86,7 @@ namespace Subsurface.Items.Components
if (item.body != null)
{
light.Position = ConvertUnits.ToDisplayUnits(item.body.Position);
light.Position = ConvertUnits.ToDisplayUnits(item.body.SimPosition);
}
Pickable pickable = item.GetComponent<Pickable>();