diff --git a/Subsurface/Content/Characters/Human/human.xml b/Subsurface/Content/Characters/Human/human.xml index 435f4017e..b81c79cc2 100644 --- a/Subsurface/Content/Characters/Human/human.xml +++ b/Subsurface/Content/Characters/Human/human.xml @@ -62,7 +62,7 @@ - + diff --git a/Subsurface/Content/Items/Weapons/weapons.xml b/Subsurface/Content/Items/Weapons/weapons.xml index 178323658..a20e0ff6d 100644 --- a/Subsurface/Content/Items/Weapons/weapons.xml +++ b/Subsurface/Content/Items/Weapons/weapons.xml @@ -45,7 +45,7 @@ price="200" tags="smallitem"> - + @@ -55,6 +55,24 @@ + + + + + + + + + + + + + diff --git a/Subsurface/Content/Particles/ParticlePrefabs.xml b/Subsurface/Content/Particles/ParticlePrefabs.xml index 4b744b1ea..82d533177 100644 --- a/Subsurface/Content/Particles/ParticlePrefabs.xml +++ b/Subsurface/Content/Particles/ParticlePrefabs.xml @@ -3,7 +3,7 @@ 0.0f) damageAmount *= deltaTime; float bleedingAmount = (Duration == 0.0f) ? BleedingDamage : BleedingDamage * deltaTime; - if (damageAmount > 0.0f) + if (particleEmitterPrefab != null) { - return target.AddDamage(position, DamageType, damageAmount, bleedingAmount, Stun, playSound); + particleEmitterPrefab.Emit(position); } - else + + if (sound!=null) { - return new AttackResult(0.0f, 0.0f); + sound.Play(1.0f, 500.0f, position); } + + return target.AddDamage(position, DamageType, damageAmount, bleedingAmount, Stun, playSound); + } } } diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index c8d049924..74ae1457f 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -549,7 +549,7 @@ namespace Subsurface if (GetInputState(InputType.ActionHeld)) selectedConstruction.Use(deltaTime, this); if (GetInputState(InputType.SecondaryHeld)) selectedConstruction.SecondaryUse(deltaTime, this); } - + if (IsNetworkPlayer) { foreach (Key key in keys) @@ -920,9 +920,6 @@ namespace Subsurface private void Implode() { - Limb torso= AnimController.GetLimb(LimbType.Torso); - if (torso == null) torso = AnimController.GetLimb(LimbType.Head); - Vector2 centerOfMass = AnimController.GetCenterOfMass(); health = 0.0f; @@ -935,17 +932,17 @@ namespace Subsurface // limb.Damage = 100.0f; } - AmbientSoundManager.PlayDamageSound(DamageSoundType.Implode, 50.0f, torso.body.FarseerBody); + AmbientSoundManager.PlayDamageSound(DamageSoundType.Implode, 50.0f, AnimController.RefLimb.body.FarseerBody); for (int i = 0; i < 10; i++) { Particle p = Game1.ParticleManager.CreateParticle("waterblood", - torso.Position + new Vector2(Rand.Range(-50f, 50f), Rand.Range(-50f, 50f)), + centerOfMass + Rand.Vector(50.0f), Vector2.Zero); if (p!=null) p.Size *= 2.0f; Game1.ParticleManager.CreateParticle("bubbles", - torso.SimPosition, + centerOfMass + Rand.Vector(50.0f), new Vector2(Rand.Range(-50f, 50f), Rand.Range(-100f,50f))); } @@ -1083,8 +1080,8 @@ namespace Subsurface int i = 0; foreach (Limb limb in AnimController.limbs) { - message.Write(limb.body.Position.X); - message.Write(limb.body.Position.Y); + message.Write(limb.body.SimPosition.X); + message.Write(limb.body.SimPosition.Y); //message.Write(limb.body.LinearVelocity.X); //message.Write(limb.body.LinearVelocity.Y); @@ -1103,8 +1100,8 @@ namespace Subsurface } else { - message.Write(AnimController.RefLimb.Position.X); - message.Write(AnimController.RefLimb.Position.Y); + message.Write(AnimController.RefLimb.SimPosition.X); + message.Write(AnimController.RefLimb.SimPosition.Y); LargeUpdateTimer = Math.Max(0, LargeUpdateTimer-1); } diff --git a/Subsurface/Source/Characters/HumanoidAnimController.cs b/Subsurface/Source/Characters/HumanoidAnimController.cs index f6c7a8833..d354043c0 100644 --- a/Subsurface/Source/Characters/HumanoidAnimController.cs +++ b/Subsurface/Source/Characters/HumanoidAnimController.cs @@ -202,7 +202,7 @@ namespace Subsurface float footMid = (leftFoot.SimPosition.X + rightFoot.SimPosition.X) / 2.0f; - movement = MathUtils.SmoothStep(movement, TargetMovement, 0.5f); + movement = MathUtils.SmoothStep(movement, TargetMovement, 0.4f); movement.Y = 0.0f; //place the anchors of the head and the torso to make the ragdoll stand @@ -678,7 +678,54 @@ namespace Subsurface //MoveLimb(rightLeg, footPos, 0.7f); } - public override void HoldItem(float deltaTime, Camera cam, Item item, Vector2[] handlePos, Vector2 holdPos, Vector2 aimPos, float holdAngle) + //float punchTimer; + //bool punching; + + //public void Punch() + //{ + // if (punchTimer < 0.01f) punching = true; + + // Limb rightHand = GetLimb(LimbType.RightHand); + // Limb head = GetLimb(LimbType.Head); + + // Vector2 diff = Vector2.Normalize(character.CursorPosition - RefLimb.Position); + + // rightHand.body.ApplyLinearImpulse(diff * 20.0f); + // head.body.ApplyLinearImpulse(diff * 5.0f); + // head.body.ApplyTorque(Dir*100.0f); + //} + + //public void Block(float deltaTime) + //{ + // Limb head = GetLimb(LimbType.Head); + // Limb torso = GetLimb(LimbType.Torso); + // Limb leftHand = GetLimb(LimbType.LeftHand); + // Limb leftFoot = GetLimb(LimbType.LeftFoot); + // Limb rightHand = GetLimb(LimbType.RightHand); + + // Vector2 pos = head.SimPosition; + + // rightHand.Disabled = true; + // leftHand.Disabled = true; + + // HandIK(leftHand, pos + new Vector2(0.25f*Dir, 0.0f)); + + // if (punching) + // { + // punchTimer += deltaTime*10.0f; + // if (punchTimer>2.0f) + // { + // punching = false; + // } + // } + // else + // { + // punchTimer = MathHelper.Lerp(punchTimer, 0.0f, 0.3f); + // HandIK(rightHand, pos + new Vector2((0.3f + punchTimer) * Dir, 0.1f)); + // } + //} + + public override void HoldItem(float deltaTime, Item item, Vector2[] handlePos, Vector2 holdPos, Vector2 aimPos, bool aim, float holdAngle) { //calculate the handle positions Matrix itemTransfrom = Matrix.CreateRotationZ(item.body.Rotation); @@ -689,14 +736,12 @@ namespace Subsurface Limb head = GetLimb(LimbType.Head); Limb torso = GetLimb(LimbType.Torso); Limb leftHand = GetLimb(LimbType.LeftHand); - Limb leftArm = GetLimb(LimbType.LeftArm); Limb rightHand = GetLimb(LimbType.RightHand); - Limb rightArm = GetLimb(LimbType.RightArm); - Vector2 itemPos = character.GetInputState(InputType.SecondaryHeld) ? aimPos : holdPos; + Vector2 itemPos = aim ? aimPos : holdPos; float itemAngle; - if (stunTimer <= 0.0f && character.GetInputState(InputType.SecondaryHeld) && itemPos != Vector2.Zero) + if (stunTimer <= 0.0f && aim && itemPos != Vector2.Zero) { Vector2 mousePos = ConvertUnits.ToSimUnits(character.CursorPosition); @@ -731,13 +776,11 @@ namespace Subsurface { transformedHoldPos = rightHand.pullJoint.WorldAnchorA - transformedHandlePos[0]; itemAngle = (rightHand.Rotation + (holdAngle - MathHelper.PiOver2) * Dir); - //rightHand.Disabled = true; } if (character.SelectedItems[1] == item) { transformedHoldPos = leftHand.pullJoint.WorldAnchorA - transformedHandlePos[1]; itemAngle = (leftHand.Rotation + (holdAngle - MathHelper.PiOver2) * Dir); - //leftHand.Disabled = true; } } else @@ -759,13 +802,10 @@ namespace Subsurface transformedHoldPos += Vector2.Transform(itemPos, torsoTransform); } - Vector2 bodyVelocity = torso.body.LinearVelocity / 60.0f; item.body.ResetDynamics(); - item.body.SetTransform(MathUtils.SmoothStep(item.body.Position, transformedHoldPos + bodyVelocity, 0.5f), itemAngle); - - //item.body.SmoothRotate(itemAngle, 50.0f); + item.body.SetTransform(MathUtils.SmoothStep(item.body.SimPosition, transformedHoldPos + bodyVelocity, 0.5f), itemAngle); for (int i = 0; i < 2; i++) { @@ -775,26 +815,6 @@ namespace Subsurface Limb hand = (i == 0) ? rightHand : leftHand; HandIK(hand, transformedHoldPos + transformedHandlePos[i]); - - //Limb arm = (i == 0) ? rightArm : leftArm; - - ////hand length - //float a = 37.0f; - - ////arm length - //float b = 28.0f; - - ////distance from shoulder to holdpos - //float c = ConvertUnits.ToDisplayUnits(Vector2.Distance(transformedHoldPos + transformedHandlePos[i], shoulderPos)); - //c = MathHelper.Clamp(a + b - 1, b-a, c); - - //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); } } @@ -837,7 +857,7 @@ namespace Subsurface { if (character.SelectedItems[i] != null) { - difference = character.SelectedItems[i].body.Position - torso.SimPosition; + difference = character.SelectedItems[i].body.SimPosition - torso.SimPosition; difference = Vector2.Transform(difference, torsoTransform); difference.Y = -difference.Y; @@ -855,14 +875,14 @@ namespace Subsurface case LimbType.LeftArm: case LimbType.RightHand: case LimbType.RightArm: - difference = l.body.Position - torso.SimPosition; + difference = l.body.SimPosition - torso.SimPosition; difference = Vector2.Transform(difference, torsoTransform); difference.Y = -difference.Y; l.body.SetTransform(torso.SimPosition + Vector2.Transform(difference, -torsoTransform), -l.body.Rotation); break; default: - if (!inWater) l.body.SetTransform(l.body.Position, + if (!inWater) l.body.SetTransform(l.body.SimPosition, MathUtils.WrapAnglePi(l.body.Rotation * (l.DoesFlip ? -1.0f : 1.0f))); break; } diff --git a/Subsurface/Source/Characters/Limb.cs b/Subsurface/Source/Characters/Limb.cs index 3b5ecfb33..b21c6fb77 100644 --- a/Subsurface/Source/Characters/Limb.cs +++ b/Subsurface/Source/Characters/Limb.cs @@ -79,12 +79,12 @@ namespace Subsurface public Vector2 Position { - get { return ConvertUnits.ToDisplayUnits(body.Position); } + get { return ConvertUnits.ToDisplayUnits(body.SimPosition); } } public Vector2 SimPosition { - get { return body.Position; } + get { return body.SimPosition; } } public float Rotation @@ -271,7 +271,7 @@ namespace Subsurface public void Move(Vector2 pos, float amount, bool pullFromCenter=false) { - Vector2 pullPos = body.Position; + Vector2 pullPos = body.SimPosition; if (pullJoint!=null && !pullFromCenter) { pullPos = pullJoint.WorldAnchorA; @@ -318,19 +318,8 @@ namespace Subsurface //Bleeding += bleedingAmount; //Damage += amount; - float bloodAmount = hitArmor ? 0 : (int)Math.Min((int)(amount * 2.0f), 20); - //if (closestLimb.Damage>=100.0f) - //{ - // bloodAmount *= 2; - // foreach (var joint in animController.limbJoints) - // { - // if (!(joint.BodyA == closestLimb.body.FarseerBody) && !(joint.BodyB == closestLimb.body.FarseerBody)) continue; - - // joint.Enabled = false; - // break; - // } - //} - + float bloodAmount = hitArmor || bleedingAmount<=0.0f ? 0 : (int)Math.Min((int)(amount * 2.0f), 20); + for (int i = 0; i < bloodAmount; i++) { Vector2 particleVel = SimPosition - position; @@ -357,7 +346,7 @@ namespace Subsurface foreach (Limb limb in character.AnimController.limbs) { limb.body.ResetDynamics(); - limb.body.SetTransform(body.Position, 0.0f); + limb.body.SetTransform(body.SimPosition, 0.0f); } } diff --git a/Subsurface/Source/Characters/Ragdoll.cs b/Subsurface/Source/Characters/Ragdoll.cs index 9d92ece12..776ceacd6 100644 --- a/Subsurface/Source/Characters/Ragdoll.cs +++ b/Subsurface/Source/Characters/Ragdoll.cs @@ -283,7 +283,8 @@ namespace Subsurface } else if (structure.StairDirection!=Direction.None) { - if (inWater || !(targetMovement.Y>Math.Abs(targetMovement.X/2.0f)) && lowestLimb.Position.Y < structure.Rect.Y - structure.Rect.Height + 50.0f) + if ((inWater || !(targetMovement.Y>Math.Abs(targetMovement.X/2.0f))) && + lowestLimb.Position.Y < structure.Rect.Y - structure.Rect.Height + 50.0f) { stairs = null; return false; @@ -341,9 +342,13 @@ namespace Subsurface if (impact > 1.0f && l.HitSound != null && l.soundTimer <= 0.0f) l.HitSound.Play(Math.Min(impact / 5.0f, 1.0f), impact * 100.0f, l.body.FarseerBody); if (impact > l.impactTolerance) - { + { character.Health -= (impact - l.impactTolerance * 0.1f); strongestImpact = Math.Max(strongestImpact, impact - l.impactTolerance); + + AmbientSoundManager.PlayDamageSound(DamageSoundType.LimbBlunt, strongestImpact, l.body.FarseerBody); + + if (Character.Controlled == character) Game1.GameScreen.Cam.Shake = strongestImpact; } } @@ -385,7 +390,10 @@ namespace Subsurface 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); + pos.Y = -pos.Y; + GUI.DrawLine(spriteBatch, pos+new Vector2(-30.0f,0.0f), pos+new Vector2(30.0f,0.0f), Color.LightBlue); + GUI.DrawLine(spriteBatch, pos + new Vector2(0.0f,-30.0f), pos + new Vector2(0.0f,30.0f), Color.LightBlue); + } @@ -502,7 +510,8 @@ namespace Subsurface inWater = false; headInWater = false; - if (currentHull.Volume > currentHull.FullVolume * 0.95f || ConvertUnits.ToSimUnits(currentHull.Surface) - floorY > HeadPosition * 0.95f) + if (currentHull.Volume > currentHull.FullVolume * 0.95f || + ConvertUnits.ToSimUnits(currentHull.Surface) - floorY > HeadPosition * 0.95f) inWater = true; } @@ -517,13 +526,13 @@ namespace Subsurface bool prevInWater = limb.inWater; limb.inWater = false; - - if (limbHull==null) + + if (limbHull == null) { //limb isn't in any room -> it's in the water limb.inWater = true; } - else if (limbHull.Volume>0.0f && Submarine.RectContains(limbHull.Rect, limbPosition)) + else if (limbHull.Volume > 0.0f && Submarine.RectContains(limbHull.Rect, limbPosition)) { if (limbPosition.Y < limbHull.Surface) @@ -578,9 +587,7 @@ namespace Subsurface limbHull.WaveVel[n] = Math.Min(impulse.Y * 1.0f, 5.0f); StrongestImpact = ((impulse.Length() * 0.5f) - limb.impactTolerance); } - } - - + } } limb.Update(deltaTime); @@ -591,7 +598,11 @@ namespace Subsurface private void UpdateNetplayerPosition() { - if (refLimb.body.TargetPosition == Vector2.Zero) return; + if (refLimb.body.TargetPosition == Vector2.Zero) + { + correctionMovement = Vector2.Zero; + return; + } //if the limb is further away than resetdistance, all limbs are immediately snapped to their targetpositions float resetDistance = NetConfig.ResetRagdollDistance; @@ -599,10 +610,10 @@ namespace Subsurface //if the limb is closer than alloweddistance, just ignore the difference float allowedDistance = NetConfig.AllowedRagdollDistance; - float dist = Vector2.Distance(refLimb.body.Position, refLimb.body.TargetPosition); + float dist = Vector2.Distance(refLimb.body.SimPosition, refLimb.body.TargetPosition); bool resetAll = (dist > resetDistance && character.LargeUpdateTimer == 1); - Vector2 newMovement = (refLimb.body.TargetPosition - refLimb.body.Position); + Vector2 newMovement = (refLimb.body.TargetPosition - refLimb.body.SimPosition); if (newMovement == Vector2.Zero || newMovement.Length() < allowedDistance) { @@ -623,7 +634,7 @@ namespace Subsurface } else { - correctionMovement = Vector2.Normalize(newMovement) * Math.Min(1.0f + dist, 3.0f); + correctionMovement = Vector2.Normalize(newMovement) * Math.Min(0.1f + dist, 3.0f); if (Math.Abs(correctionMovement.Y) < 0.1f) correctionMovement.Y = 0.0f; } } diff --git a/Subsurface/Source/Items/Components/Container.cs b/Subsurface/Source/Items/Components/Container.cs index cd5ea359f..e2e66e542 100644 --- a/Subsurface/Source/Items/Components/Container.cs +++ b/Subsurface/Source/Items/Components/Container.cs @@ -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; } diff --git a/Subsurface/Source/Items/Components/Door.cs b/Subsurface/Source/Items/Components/Door.cs index 1a7ee9cd7..ecaac1883 100644 --- a/Subsurface/Source/Items/Components/Door.cs +++ b/Subsurface/Source/Items/Components/Door.cs @@ -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); diff --git a/Subsurface/Source/Items/Components/Holdable/Holdable.cs b/Subsurface/Source/Items/Components/Holdable/Holdable.cs index 33711de9e..fde57fbb2 100644 --- a/Subsurface/Source/Items/Components/Holdable/Holdable.cs +++ b/Subsurface/Source/Items/Components/Holdable/Holdable.cs @@ -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) diff --git a/Subsurface/Source/Items/Components/Holdable/MeleeWeapon.cs b/Subsurface/Source/Items/Components/Holdable/MeleeWeapon.cs new file mode 100644 index 000000000..3c0397c99 --- /dev/null +++ b/Subsurface/Source/Items/Components/Holdable/MeleeWeapon.cs @@ -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; + } + } +} diff --git a/Subsurface/Source/Items/Components/Holdable/RangedWeapon.cs b/Subsurface/Source/Items/Components/Holdable/RangedWeapon.cs index 7055f4f63..c7b854535 100644 --- a/Subsurface/Source/Items/Components/Holdable/RangedWeapon.cs +++ b/Subsurface/Source/Items/Components/Holdable/RangedWeapon.cs @@ -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); } } diff --git a/Subsurface/Source/Items/Components/Holdable/RepairTool.cs b/Subsurface/Source/Items/Components/Holdable/RepairTool.cs index c0df3c6b1..e7a19a492 100644 --- a/Subsurface/Source/Items/Components/Holdable/RepairTool.cs +++ b/Subsurface/Source/Items/Components/Holdable/RepairTool.cs @@ -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( diff --git a/Subsurface/Source/Items/Components/Holdable/Throwable.cs b/Subsurface/Source/Items/Components/Holdable/Throwable.cs index 62a817c7b..1904a7dd8 100644 --- a/Subsurface/Source/Items/Components/Holdable/Throwable.cs +++ b/Subsurface/Source/Items/Components/Holdable/Throwable.cs @@ -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; + } } } } diff --git a/Subsurface/Source/Items/Components/Machines/Radar.cs b/Subsurface/Source/Items/Components/Machines/Radar.cs index 95bf0f84c..44af8c4bc 100644 --- a/Subsurface/Source/Items/Components/Machines/Radar.cs +++ b/Subsurface/Source/Items/Components/Machines/Radar.cs @@ -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; diff --git a/Subsurface/Source/Items/Components/Projectile.cs b/Subsurface/Source/Items/Components/Projectile.cs index 2cd947aeb..d6aa0204a 100644 --- a/Subsurface/Source/Items/Components/Projectile.cs +++ b/Subsurface/Source/Items/Components/Projectile.cs @@ -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; diff --git a/Subsurface/Source/Items/Components/Rope.cs b/Subsurface/Source/Items/Components/Rope.cs index 4147f1dc8..68b129acf 100644 --- a/Subsurface/Source/Items/Components/Rope.cs +++ b/Subsurface/Source/Items/Components/Rope.cs @@ -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]); diff --git a/Subsurface/Source/Items/Components/Signal/LightComponent.cs b/Subsurface/Source/Items/Components/Signal/LightComponent.cs index 6307cb539..27e439af2 100644 --- a/Subsurface/Source/Items/Components/Signal/LightComponent.cs +++ b/Subsurface/Source/Items/Components/Signal/LightComponent.cs @@ -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(); diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs index 87368807b..6ba5a8bc3 100644 --- a/Subsurface/Source/Items/Item.cs +++ b/Subsurface/Source/Items/Item.cs @@ -314,7 +314,7 @@ namespace Subsurface { body.SetTransform(position, rotation); - Vector2 displayPos = ConvertUnits.ToDisplayUnits(body.Position); + Vector2 displayPos = ConvertUnits.ToDisplayUnits(body.SimPosition); rect.X = (int)(displayPos.X - rect.Width / 2.0f); rect.Y = (int)(displayPos.Y + rect.Height / 2.0f); @@ -328,7 +328,7 @@ namespace Subsurface { amount = ConvertUnits.ToSimUnits(amount); //Vector2 pos = new Vector2(rect.X + rect.Width / 2.0f, rect.Y - rect.Height / 2.0f); - body.SetTransform(body.Position+amount, body.Rotation); + body.SetTransform(body.SimPosition+amount, body.Rotation); } foreach (ItemComponent ic in components) { @@ -357,7 +357,7 @@ namespace Subsurface public virtual Hull FindHull() { - CurrentHull = Hull.FindHull((body == null) ? Position : ConvertUnits.ToDisplayUnits(body.Position), CurrentHull); + CurrentHull = Hull.FindHull((body == null) ? Position : ConvertUnits.ToDisplayUnits(body.SimPosition), CurrentHull); return CurrentHull; } @@ -495,7 +495,7 @@ namespace Subsurface if (body.LinearVelocity.Length()>0.001f) FindHull(); - Vector2 displayPos = ConvertUnits.ToDisplayUnits(body.Position); + Vector2 displayPos = ConvertUnits.ToDisplayUnits(body.SimPosition); rect.X = (int)(displayPos.X - rect.Width / 2.0f); rect.Y = (int)(displayPos.Y + rect.Height / 2.0f); @@ -505,10 +505,10 @@ namespace Subsurface if (CurrentHull != null) { float surfaceY = ConvertUnits.ToSimUnits(CurrentHull.Surface); - if (surfaceY > body.Position.Y) return; + if (surfaceY > body.SimPosition.Y) return; //the item has gone through the surface of the water -> apply an impulse which serves as surface tension - if ((body.Position.Y - (body.LinearVelocity.Y / 60.0f)) < surfaceY) + if ((body.SimPosition.Y - (body.LinearVelocity.Y / 60.0f)) < surfaceY) { Vector2 impulse = -body.LinearVelocity * (body.Mass / body.Density); body.ApplyLinearImpulse(impulse); @@ -528,7 +528,7 @@ namespace Subsurface if (body.LinearVelocity != Vector2.Zero && body.LinearVelocity.Length() > 1000.0f) { body.ResetDynamics(); - if (body.Position.Length() > 1000.0f) + if (body.SimPosition.Length() > 1000.0f) { Remove(); return; @@ -635,7 +635,7 @@ namespace Subsurface } } - editingHUD = new GUIFrame(new Rectangle(x, y, width, 110 + (editableProperties.Count() + requiredItemCount) * 30), GUI.style); + editingHUD = new GUIFrame(new Rectangle(x, y, width, 60 + (editableProperties.Count() + requiredItemCount) * 30), GUI.style); editingHUD.Padding = new Vector4(10, 10, 0, 0); editingHUD.UserData = this; @@ -707,8 +707,11 @@ namespace Subsurface editingHUD = CreateEditingHUD(true); } - editingHUD.Update((float)Physics.step); - editingHUD.Draw(spriteBatch); + if (editingHUD.Rect.Height>60) + { + editingHUD.Update((float)Physics.step); + editingHUD.Draw(spriteBatch); + } foreach (ItemComponent ic in components) { @@ -882,7 +885,6 @@ namespace Subsurface if (string.IsNullOrEmpty(ic.Msg)) continue; if (!ic.CanBePicked && !ic.CanBeSelected) continue; - Color color = Color.Red; if (ic.HasRequiredSkills(character) && ic.HasRequiredItems(character, false)) color = Color.Orange; diff --git a/Subsurface/Source/Particles/ParticleEmitter.cs b/Subsurface/Source/Particles/ParticleEmitter.cs new file mode 100644 index 000000000..c66370a36 --- /dev/null +++ b/Subsurface/Source/Particles/ParticleEmitter.cs @@ -0,0 +1,65 @@ +using System.Xml.Linq; +using Microsoft.Xna.Framework; +using FarseerPhysics; +using System; + +namespace Subsurface.Particles +{ + class ParticleEmitterPrefab + { + public readonly string Name; + + public readonly ParticlePrefab particlePrefab; + + public readonly float AngleMin, AngleMax; + + public readonly float VelocityMin, VelocityMax; + + public readonly float ParticleAmount; + + public ParticleEmitterPrefab(XElement element) + { + Name = element.Name.ToString(); + + particlePrefab = Game1.ParticleManager.FindPrefab(ToolBox.GetAttributeString(element, "particle", "")); + + if (element.Attribute("startrotation") == null) + { + AngleMin = ToolBox.GetAttributeFloat(element, "anglemin", 0.0f); + AngleMax = ToolBox.GetAttributeFloat(element, "anglemax", 0.0f); + } + else + { + AngleMin = ToolBox.GetAttributeFloat(element, "angle", 0.0f); + AngleMax = AngleMin; + } + + AngleMin = MathHelper.ToRadians(AngleMin); + AngleMin = MathHelper.ToRadians(AngleMax); + + if (element.Attribute("velocity") == null) + { + VelocityMin = ToolBox.GetAttributeFloat(element, "velocitymin", 0.0f); + VelocityMax = ToolBox.GetAttributeFloat(element, "velocitymax", 0.0f); + } + else + { + VelocityMin = ToolBox.GetAttributeFloat(element, "velocity", 0.0f); + VelocityMax = VelocityMin; + } + + ParticleAmount = ToolBox.GetAttributeInt(element, "particleamount", 1); + } + + public void Emit(Vector2 position) + { + for (int i = 0; i + @@ -86,6 +87,7 @@ + @@ -565,6 +567,7 @@ PreserveNewest + Designer PreserveNewest diff --git a/Subsurface_Solution.sln b/Subsurface_Solution.sln index e773231d9..9d5b8a22c 100644 --- a/Subsurface_Solution.sln +++ b/Subsurface_Solution.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 -VisualStudioVersion = 12.0.30501.0 +VisualStudioVersion = 12.0.21005.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Subsurface", "Subsurface\Subsurface.csproj", "{008C0F83-E914-4966-9135-EA885059EDD8}" EndProject @@ -307,4 +307,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection EndGlobal diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo index 04b014ea1..67016dc49 100644 Binary files a/Subsurface_Solution.v12.suo and b/Subsurface_Solution.v12.suo differ