Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaClient/Source/Physics/PhysicsBody.cs
2019-03-27 20:52:47 +02:00

212 lines
8.2 KiB
C#

using Barotrauma.Networking;
using FarseerPhysics;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
namespace Barotrauma
{
partial class PhysicsBody
{
private float bodyShapeTextureScale;
private Texture2D bodyShapeTexture;
public Texture2D BodyShapeTexture
{
get { return bodyShapeTexture; }
}
public void Draw(DeformableSprite deformSprite, Camera cam, Vector2 scale, Color color)
{
if (!Enabled) return;
UpdateDrawPosition();
deformSprite?.Draw(cam,
new Vector3(DrawPosition, MathHelper.Clamp(deformSprite.Sprite.Depth, 0, 1)),
deformSprite.Origin,
-DrawRotation,
scale,
color,
flip: Dir < 0);
}
public void Draw(SpriteBatch spriteBatch, Sprite sprite, Color color, float? depth = null, float scale = 1.0f)
{
if (!Enabled) return;
UpdateDrawPosition();
if (sprite == null) return;
SpriteEffects spriteEffect = (Dir == 1.0f) ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
sprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y), color, -drawRotation, scale, spriteEffect, depth);
}
public void DebugDraw(SpriteBatch spriteBatch, Color color, bool forceColor = false)
{
if (!forceColor)
{
if (!body.Enabled)
{
color = Color.Gray;
}
else if (!body.Awake)
{
color = Color.Blue;
}
}
if (targetPosition != null)
{
Vector2 pos = ConvertUnits.ToDisplayUnits((Vector2)targetPosition);
if (Submarine != null) pos += Submarine.DrawPosition;
GUI.DrawRectangle(spriteBatch,
new Vector2(pos.X - 5, -(pos.Y + 5)),
Vector2.One * 10.0f, Color.Red, false, 0, 3);
}
if (drawOffset != Vector2.Zero)
{
Vector2 pos = ConvertUnits.ToDisplayUnits(body.Position);
if (Submarine != null) pos += Submarine.DrawPosition;
GUI.DrawLine(spriteBatch,
new Vector2(pos.X, -pos.Y),
new Vector2(DrawPosition.X, -DrawPosition.Y),
Color.Cyan, 0, 5);
}
if (bodyShapeTexture == null && IsValidShape(radius, height, width))
{
switch (BodyShape)
{
case Shape.Rectangle:
{
float maxSize = Math.Max(ConvertUnits.ToDisplayUnits(width), ConvertUnits.ToDisplayUnits(height));
if (maxSize > 128.0f)
{
bodyShapeTextureScale = 128.0f / maxSize;
}
else
{
bodyShapeTextureScale = 1.0f;
}
bodyShapeTexture = GUI.CreateRectangle(
(int)ConvertUnits.ToDisplayUnits(width * bodyShapeTextureScale),
(int)ConvertUnits.ToDisplayUnits(height * bodyShapeTextureScale));
break;
}
case Shape.Capsule:
case Shape.HorizontalCapsule:
{
float maxSize = Math.Max(ConvertUnits.ToDisplayUnits(radius), ConvertUnits.ToDisplayUnits(Math.Max(height, width)));
if (maxSize > 128.0f)
{
bodyShapeTextureScale = 128.0f / maxSize;
}
else
{
bodyShapeTextureScale = 1.0f;
}
bodyShapeTexture = GUI.CreateCapsule(
(int)ConvertUnits.ToDisplayUnits(radius * bodyShapeTextureScale),
(int)ConvertUnits.ToDisplayUnits(Math.Max(height, width) * bodyShapeTextureScale));
break;
}
case Shape.Circle:
if (ConvertUnits.ToDisplayUnits(radius) > 128.0f)
{
bodyShapeTextureScale = 128.0f / ConvertUnits.ToDisplayUnits(radius);
}
else
{
bodyShapeTextureScale = 1.0f;
}
bodyShapeTexture = GUI.CreateCircle((int)ConvertUnits.ToDisplayUnits(radius * bodyShapeTextureScale));
break;
default:
throw new NotImplementedException();
}
}
float rot = -DrawRotation;
if (bodyShape == Shape.HorizontalCapsule)
{
rot -= MathHelper.PiOver2;
}
spriteBatch.Draw(
bodyShapeTexture,
new Vector2(DrawPosition.X, -DrawPosition.Y),
null,
color,
rot,
new Vector2(bodyShapeTexture.Width / 2, bodyShapeTexture.Height / 2),
1.0f / bodyShapeTextureScale, SpriteEffects.None, 0.0f);
}
public PosInfo ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime, string parentDebugName)
{
float MaxVel = NetConfig.MaxPhysicsBodyVelocity;
float MaxAngularVel = NetConfig.MaxPhysicsBodyAngularVelocity;
Vector2 newPosition = SimPosition;
float? newRotation = null;
bool awake = body.Awake;
Vector2 newVelocity = LinearVelocity;
float? newAngularVelocity = null;
newPosition = new Vector2(
msg.ReadFloat(),
msg.ReadFloat());
awake = msg.ReadBoolean();
bool fixedRotation = msg.ReadBoolean();
if (!fixedRotation)
{
newRotation = msg.ReadRangedSingle(0.0f, MathHelper.TwoPi, 8);
}
if (awake)
{
newVelocity = new Vector2(
msg.ReadRangedSingle(-MaxVel, MaxVel, 12),
msg.ReadRangedSingle(-MaxVel, MaxVel, 12));
if (!fixedRotation)
{
newAngularVelocity = msg.ReadRangedSingle(-MaxAngularVel, MaxAngularVel, 8);
}
}
msg.ReadPadBits();
if (!MathUtils.IsValid(newPosition) ||
!MathUtils.IsValid(newVelocity) ||
(newRotation.HasValue && !MathUtils.IsValid(newRotation.Value)) ||
(newAngularVelocity.HasValue && !MathUtils.IsValid(newAngularVelocity.Value)))
{
string errorMsg = "Received invalid position data for \"" + parentDebugName
+ "\" (position: " + newPosition + ", rotation: " + (newRotation ?? 0) + ", velocity: " + newVelocity + ", angular velocity: " + (newAngularVelocity ?? 0) + ")";
#if DEBUG
DebugConsole.ThrowError(errorMsg);
#endif
GameAnalyticsManager.AddErrorEventOnce("PhysicsBody.ClientRead:InvalidData" + parentDebugName,
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
errorMsg);
return null;
}
return lastProcessedNetworkState > sendingTime ?
null :
new PosInfo(newPosition, newRotation, newVelocity, newAngularVelocity, sendingTime);
}
partial void DisposeProjSpecific()
{
if (bodyShapeTexture != null)
{
bodyShapeTexture.Dispose();
bodyShapeTexture = null;
}
}
}
}