38f1ddb...178a853: v0.8.9.1, removed content folder

This commit is contained in:
Joonas Rikkonen
2019-03-18 19:46:58 +02:00
parent 38f1ddb6fe
commit 6c0679c297
1054 changed files with 151673 additions and 144931 deletions
@@ -3,6 +3,7 @@ using FarseerPhysics.Collision;
using FarseerPhysics.Common;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Contacts;
using FarseerPhysics.Dynamics.Joints;
using FarseerPhysics.Factories;
using Microsoft.Xna.Framework;
using System;
@@ -15,6 +16,12 @@ namespace Barotrauma
{
class SubmarineBody
{
public const float NeutralBallastPercentage = 0.07f;
const float HorizontalDrag = 0.01f;
const float VerticalDrag = 0.05f;
const float MaxDrag = 0.1f;
public const float DamageDepth = -30000.0f;
private const float ImpactDamageMultiplier = 10.0f;
@@ -65,43 +72,36 @@ namespace Barotrauma
get { return Position.Y < DamageDepth; }
}
public SubmarineBody(Submarine sub)
public Submarine Submarine
{
get { return submarine; }
}
public SubmarineBody(Submarine sub, bool showWarningMessages = true)
{
this.submarine = sub;
Body farseerBody = null;
if (!Hull.hullList.Any())
{
Body = new PhysicsBody(1,1,1,1);
farseerBody = Body.FarseerBody;
DebugConsole.ThrowError("WARNING: no hulls found, generating a physics body for the submarine failed.");
farseerBody = BodyFactory.CreateRectangle(GameMain.World, 1.0f, 1.0f, 1.0f);
if (showWarningMessages)
{
DebugConsole.ThrowError("WARNING: no hulls found, generating a physics body for the submarine failed.");
}
}
else
{
List<Vector2> convexHull = GenerateConvexHull();
HullVertices = convexHull;
for (int i = 0; i < convexHull.Count; i++)
{
convexHull[i] = ConvertUnits.ToSimUnits(convexHull[i]);
}
convexHull.Reverse();
//get farseer 'vertices' from vectors
Vertices shapevertices = new Vertices(convexHull);
AABB hullAABB = shapevertices.GetAABB();
Borders = new Rectangle(
(int)ConvertUnits.ToDisplayUnits(hullAABB.LowerBound.X),
(int)ConvertUnits.ToDisplayUnits(hullAABB.UpperBound.Y),
(int)ConvertUnits.ToDisplayUnits(hullAABB.Extents.X * 2.0f),
(int)ConvertUnits.ToDisplayUnits(hullAABB.Extents.Y * 2.0f));
Vector2 minExtents = Vector2.Zero, maxExtents = Vector2.Zero;
farseerBody = BodyFactory.CreateBody(GameMain.World, this);
foreach (Structure wall in Structure.WallList)
{
if (wall.Submarine != submarine) continue;
@@ -109,11 +109,17 @@ namespace Barotrauma
Rectangle rect = wall.Rect;
FixtureFactory.AttachRectangle(
ConvertUnits.ToSimUnits(rect.Width),
ConvertUnits.ToSimUnits(rect.Height),
ConvertUnits.ToSimUnits(wall.BodyWidth),
ConvertUnits.ToSimUnits(wall.BodyHeight),
50.0f,
-wall.BodyRotation,
ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height / 2)),
farseerBody, this);
minExtents.X = Math.Min(rect.X, minExtents.X);
minExtents.Y = Math.Min(rect.Y - rect.Height, minExtents.Y);
maxExtents.X = Math.Max(rect.Right, maxExtents.X);
maxExtents.Y = Math.Max(rect.Y, maxExtents.Y);
}
foreach (Hull hull in Hull.hullList)
@@ -127,39 +133,68 @@ namespace Barotrauma
5.0f,
ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height / 2)),
farseerBody, this);
minExtents.X = Math.Min(rect.X, minExtents.X);
minExtents.Y = Math.Min(rect.Y - rect.Height, minExtents.Y);
maxExtents.X = Math.Max(rect.Right, maxExtents.X);
maxExtents.Y = Math.Max(rect.Y, maxExtents.Y);
}
foreach (Item item in Item.ItemList)
{
if (item.StaticBodyConfig == null) continue;
if (item.StaticBodyConfig == null || item.Submarine != submarine) continue;
float radius = ConvertUnits.ToSimUnits(item.StaticBodyConfig.GetAttributeFloat("radius", 0.0f));
float width = ConvertUnits.ToSimUnits(item.StaticBodyConfig.GetAttributeFloat("width", 0.0f));
float height = ConvertUnits.ToSimUnits(item.StaticBodyConfig.GetAttributeFloat("height", 0.0f));
float radius = item.StaticBodyConfig.GetAttributeFloat("radius", 0.0f) * item.Scale;
float width = item.StaticBodyConfig.GetAttributeFloat("width", 0.0f) * item.Scale;
float height = item.StaticBodyConfig.GetAttributeFloat("height", 0.0f) * item.Scale;
if (width != 0.0f && height != 0.0f)
Vector2 simPos = ConvertUnits.ToSimUnits(item.Position);
float simRadius = ConvertUnits.ToSimUnits(radius);
float simWidth = ConvertUnits.ToSimUnits(width);
float simHeight = ConvertUnits.ToSimUnits(height);
if (width > 0.0f && height > 0.0f)
{
FixtureFactory.AttachRectangle(width, height, 5.0f, ConvertUnits.ToSimUnits(item.Position), farseerBody, this).UserData = item;
FixtureFactory.AttachRectangle(simWidth, simHeight, 5.0f, simPos, farseerBody, this).UserData = item;
minExtents.X = Math.Min(item.Position.X - width / 2, minExtents.X);
minExtents.Y = Math.Min(item.Position.Y - height / 2, minExtents.Y);
maxExtents.X = Math.Max(item.Position.X + width / 2, maxExtents.X);
maxExtents.Y = Math.Max(item.Position.Y + height / 2, maxExtents.Y);
}
else if (radius != 0.0f && width != 0.0f)
else if (radius > 0.0f && width > 0.0f)
{
FixtureFactory.AttachRectangle(width, radius * 2, 5.0f, ConvertUnits.ToSimUnits(item.Position), farseerBody, this).UserData = item;
FixtureFactory.AttachCircle(radius, 5.0f, farseerBody, ConvertUnits.ToSimUnits(item.Position) - Vector2.UnitX * width / 2, this).UserData = item;
FixtureFactory.AttachCircle(radius, 5.0f, farseerBody, ConvertUnits.ToSimUnits(item.Position) + Vector2.UnitX * width / 2, this).UserData = item;
FixtureFactory.AttachRectangle(simWidth, simRadius * 2, 5.0f, simPos, farseerBody, this).UserData = item;
FixtureFactory.AttachCircle(simRadius, 5.0f, farseerBody, simPos - Vector2.UnitX * simWidth / 2, this).UserData = item;
FixtureFactory.AttachCircle(simRadius, 5.0f, farseerBody, simPos + Vector2.UnitX * simWidth / 2, this).UserData = item;
minExtents.X = Math.Min(item.Position.X - width / 2 - radius, minExtents.X);
minExtents.Y = Math.Min(item.Position.Y - radius, minExtents.Y);
maxExtents.X = Math.Max(item.Position.X + width / 2 + radius, maxExtents.X);
maxExtents.Y = Math.Max(item.Position.Y + radius, maxExtents.Y);
}
else if (radius != 0.0f && height != 0.0f)
else if (radius > 0.0f && height > 0.0f)
{
FixtureFactory.AttachRectangle(radius * 2, height, 5.0f, ConvertUnits.ToSimUnits(item.Position), farseerBody, this).UserData = item;
FixtureFactory.AttachCircle(radius, 5.0f, farseerBody, ConvertUnits.ToSimUnits(item.Position) - Vector2.UnitY * height / 2, this).UserData = item;
FixtureFactory.AttachCircle(radius, 5.0f, farseerBody, ConvertUnits.ToSimUnits(item.Position) + Vector2.UnitX * height / 2, this).UserData = item;
FixtureFactory.AttachRectangle(simRadius * 2, height, 5.0f, simPos, farseerBody, this).UserData = item;
FixtureFactory.AttachCircle(simRadius, 5.0f, farseerBody, simPos - Vector2.UnitY * simHeight / 2, this).UserData = item;
FixtureFactory.AttachCircle(simRadius, 5.0f, farseerBody, simPos + Vector2.UnitX * simHeight / 2, this).UserData = item;
minExtents.X = Math.Min(item.Position.X - radius, minExtents.X);
minExtents.Y = Math.Min(item.Position.Y - height / 2 - radius, minExtents.Y);
maxExtents.X = Math.Max(item.Position.X + radius, maxExtents.X);
maxExtents.Y = Math.Max(item.Position.Y + height / 2 + radius, maxExtents.Y);
}
else if (radius != 0.0f)
else if (radius > 0.0f)
{
FixtureFactory.AttachCircle(radius, 5.0f, farseerBody, ConvertUnits.ToSimUnits(item.Position), this).UserData = item;
FixtureFactory.AttachCircle(simRadius, 5.0f, farseerBody, simPos, this).UserData = item;
minExtents.X = Math.Min(item.Position.X - radius, minExtents.X);
minExtents.Y = Math.Min(item.Position.Y - radius, minExtents.Y);
maxExtents.X = Math.Max(item.Position.X + radius, maxExtents.X);
maxExtents.Y = Math.Max(item.Position.Y + radius, maxExtents.Y);
}
}
Borders = new Rectangle((int)minExtents.X, (int)maxExtents.Y, (int)(maxExtents.X - minExtents.X), (int)(maxExtents.Y - minExtents.Y));
}
farseerBody.BodyType = BodyType.Dynamic;
farseerBody.CollisionCategories = Physics.CollisionWall;
farseerBody.CollidesWith =
@@ -209,6 +244,8 @@ namespace Barotrauma
public void Update(float deltaTime)
{
if (Body.FarseerBody.IsStatic) { return; }
if (GameMain.Client != null)
{
if (memPos.Count == 0) return;
@@ -286,15 +323,25 @@ namespace Barotrauma
//-------------------------
Vector2 totalForce = CalculateBuoyancy();
if (Body.LinearVelocity.LengthSquared() > 0.0001f)
{
float dragCoefficient = 0.01f;
//TODO: sync current drag with clients?
float attachedMass = 0.0f;
JointEdge jointEdge = Body.FarseerBody.JointList;
while (jointEdge != null)
{
Body otherBody = jointEdge.Joint.BodyA == Body.FarseerBody ? jointEdge.Joint.BodyB : jointEdge.Joint.BodyA;
Character character = (otherBody.UserData as Limb)?.character;
if (character != null) attachedMass += character.Mass;
float speedLength = (Body.LinearVelocity == Vector2.Zero) ? 0.0f : Body.LinearVelocity.Length();
float drag = speedLength * speedLength * dragCoefficient * Body.Mass;
totalForce += -Vector2.Normalize(Body.LinearVelocity) * drag;
jointEdge = jointEdge.Next;
}
float horizontalDragCoefficient = MathHelper.Clamp(HorizontalDrag + attachedMass / 5000.0f, 0.0f, MaxDrag);
totalForce.X -= Math.Sign(Body.LinearVelocity.X) * Body.LinearVelocity.X * Body.LinearVelocity.X * horizontalDragCoefficient * Body.Mass;
float verticalDragCoefficient = MathHelper.Clamp(VerticalDrag + attachedMass / 5000.0f, 0.0f, MaxDrag);
totalForce.Y -= Math.Sign(Body.LinearVelocity.Y) * Body.LinearVelocity.Y * Body.LinearVelocity.Y * verticalDragCoefficient * Body.Mass;
}
ApplyForce(totalForce);
@@ -323,20 +370,23 @@ namespace Barotrauma
{
//if the character isn't inside the bounding box, continue
if (!Submarine.RectContains(worldBorders, limb.WorldPosition)) continue;
//cast a line from the position of the character to the same direction as the translation of the sub
//and see where it intersects with the bounding box
Vector2? intersection = MathUtils.GetLineRectangleIntersection(limb.WorldPosition,
limb.WorldPosition + translateDir*100000.0f, worldBorders);
if (!MathUtils.GetLineRectangleIntersection(limb.WorldPosition,
limb.WorldPosition + translateDir * 100000.0f, worldBorders, out Vector2 intersection))
{
//should never happen when casting a line out from inside the bounding box
Debug.Assert(false);
continue;
}
//should never be null when casting a line out from inside the bounding box
Debug.Assert(intersection != null);
//"+ translatedir" in order to move the character slightly away from the wall
c.AnimController.SetPosition(ConvertUnits.ToSimUnits(c.WorldPosition + ((Vector2)intersection - limb.WorldPosition)) + translateDir);
c.AnimController.SetPosition(ConvertUnits.ToSimUnits(c.WorldPosition + (intersection - limb.WorldPosition)) + translateDir);
return;
}
}
}
}
@@ -354,12 +404,13 @@ namespace Barotrauma
}
float waterPercentage = volume <= 0.0f ? 0.0f : waterVolume / volume;
float buoyancy = NeutralBallastPercentage - waterPercentage;
float neutralPercentage = 0.07f;
float buoyancy = neutralPercentage - waterPercentage;
if (buoyancy > 0.0f) buoyancy *= 2.0f;
if (buoyancy > 0.0f)
buoyancy *= 2.0f;
else
buoyancy = Math.Max(buoyancy, -0.5f);
return new Vector2(0.0f, buoyancy * Body.Mass * 10.0f);
}
@@ -406,26 +457,29 @@ namespace Barotrauma
{
if (f2.Body.UserData is Limb limb)
{
bool collision = CheckLimbCollision(contact, limb);
bool collision = CheckCharacterCollision(contact, limb.character);
if (collision) HandleLimbCollision(contact, limb);
return collision;
}
if (f2.Body.UserData is Character character)
{
return CheckCharacterCollision(contact, character);
}
contact.GetWorldManifold(out Vector2 normal, out FixedArray2<Vector2> points);
if (contact.FixtureA.Body == f1.Body)
{
normal = -normal;
}
if (f2.UserData is VoronoiCell cell)
{
Vector2 collisionNormal = Vector2.Normalize(ConvertUnits.ToDisplayUnits(Body.SimPosition) - cell.Center);
if (!MathUtils.IsValid(collisionNormal)) collisionNormal = Rand.Vector(1.0f);
HandleLevelCollision(contact, collisionNormal);
HandleLevelCollision(contact, normal);
return true;
}
if (f2.Body.UserData is Structure structure)
{
contact.GetWorldManifold(out Vector2 normal, out FixedArray2<Vector2> points);
if (contact.FixtureA.Body == f1.Body)
{
normal = -normal;
}
HandleLevelCollision(contact, normal);
return true;
@@ -440,16 +494,16 @@ namespace Barotrauma
return true;
}
private bool CheckLimbCollision(Contact contact, Limb limb)
private bool CheckCharacterCollision(Contact contact, Character character)
{
if (limb.character.Submarine != null) return false;
//characters that can't enter the sub always collide regardless of gaps
if (!character.AnimController.CanEnterSubmarine) return true;
if (character.Submarine != null) return false;
Vector2 contactNormal;
FixedArray2<Vector2> points;
contact.GetWorldManifold(out contactNormal, out points);
contact.GetWorldManifold(out Vector2 contactNormal, out FixedArray2<Vector2> points);
Vector2 normalizedVel = limb.character.AnimController.Collider.LinearVelocity == Vector2.Zero ?
Vector2.Zero : Vector2.Normalize(limb.character.AnimController.Collider.LinearVelocity);
Vector2 normalizedVel = character.AnimController.Collider.LinearVelocity == Vector2.Zero ?
Vector2.Zero : Vector2.Normalize(character.AnimController.Collider.LinearVelocity);
Vector2 targetPos = ConvertUnits.ToDisplayUnits(points[0] - contactNormal);
Hull newHull = Hull.FindHull(targetPos, null);
@@ -458,16 +512,17 @@ namespace Barotrauma
{
targetPos = ConvertUnits.ToDisplayUnits(points[0] + normalizedVel);
newHull = Hull.FindHull(targetPos, null);
if (newHull == null) return true;
}
var gaps = newHull.ConnectedGaps;
targetPos = limb.character.WorldPosition;
var gaps = newHull?.ConnectedGaps ?? Gap.GapList.Where(g => g.Submarine == submarine);
targetPos = character.WorldPosition;
Gap adjacentGap = Gap.FindAdjacent(gaps, targetPos, 200.0f);
if (adjacentGap == null) return true;
var ragdoll = limb.character.AnimController;
ragdoll.FindHull(newHull.WorldPosition, true);
if (newHull != null)
{
character.AnimController.FindHull(newHull.WorldPosition, true);
}
return false;
}
@@ -508,8 +563,6 @@ namespace Barotrauma
//if the limb is in contact with the level, apply an artifical impact to prevent the sub from bouncing on top of it
//not a very realistic way to handle the collisions (makes it seem as if the characters were made of reinforced concrete),
//but more realistic than bouncing and prevents using characters as "bumpers" that prevent all collision damage
//TODO: apply impact damage and/or gib the character that got crushed between the sub and the level?
Vector2 avgContactNormal = Vector2.Zero;
foreach (Contact levelContact in levelContacts)
{
@@ -556,7 +609,9 @@ namespace Barotrauma
Vector2 n;
FixedArray2<Vector2> contactPos;
contact.GetWorldManifold(out n, out contactPos);
limb.character.DamageLimb(ConvertUnits.ToDisplayUnits(contactPos[0]), limb, DamageType.Blunt, damageAmount, 0.0f, 0.0f, true, 0.0f);
limb.character.LastDamageSource = submarine;
limb.character.DamageLimb(ConvertUnits.ToDisplayUnits(contactPos[0]), limb,
new List<Affliction>() { AfflictionPrefab.InternalDamage.Instantiate(damageAmount) }, 0.0f, true, 0.0f);
if (limb.character.IsDead)
{
@@ -685,19 +740,23 @@ namespace Barotrauma
{
if (impact < 3.0f) return;
Vector2 tempNormal;
FixedArray2<Vector2> worldPoints;
contact.GetWorldManifold(out tempNormal, out worldPoints);
contact.GetWorldManifold(out Vector2 tempNormal, out FixedArray2<Vector2> worldPoints);
Vector2 lastContactPoint = worldPoints[0];
Vector2 impulse = direction * impact * 0.5f;
impulse = impulse.ClampLength(5.0f);
#if CLIENT
if (Character.Controlled != null && Character.Controlled.Submarine == submarine)
{
GameMain.GameScreen.Cam.Shake = impact * 2.0f;
float angularVelocity =
(lastContactPoint.X - Body.SimPosition.X) / ConvertUnits.ToSimUnits(submarine.Borders.Width / 2) * impulse.Y
- (lastContactPoint.Y - Body.SimPosition.Y) / ConvertUnits.ToSimUnits(submarine.Borders.Height / 2) * impulse.X;
GameMain.GameScreen.Cam.AngularVelocity = MathHelper.Clamp(angularVelocity * 0.1f, -1.0f, 1.0f);
}
#endif
Vector2 impulse = direction * impact * 0.5f;
impulse = impulse.ClampLength(5.0f);
foreach (Character c in Character.CharacterList)
{
if (c.Submarine != submarine) continue;
@@ -739,7 +798,7 @@ namespace Barotrauma
"StructureBlunt",
impact * 10.0f,
ConvertUnits.ToDisplayUnits(lastContactPoint),
MathHelper.Clamp(maxDamage * 4.0f, 1000.0f, 4000.0f),
MathHelper.Clamp(maxDamage * 4.0f, 2000.0f, 10000.0f),
maxDamageStructure.Tags);
}
#endif