Client LuaCsForBarotrauma
BarotraumaClient/ClientSource/Physics/PhysicsBody.cs
2 using FarseerPhysics;
3 using Lidgren.Network;
4 using Microsoft.Xna.Framework;
5 using Microsoft.Xna.Framework.Graphics;
6 using System;
7 
8 namespace Barotrauma
9 {
10  partial class PhysicsBody
11  {
12  private float bodyShapeTextureScale;
13 
14  private Texture2D bodyShapeTexture;
15  public Texture2D BodyShapeTexture
16  {
17  get { return bodyShapeTexture; }
18  }
19 
20  public void Draw(DeformableSprite deformSprite, Camera cam, Vector2 scale, Color color, bool invert = false)
21  {
22  if (!Enabled) { return; }
24  deformSprite?.Draw(cam,
25  new Vector3(DrawPosition, MathHelper.Clamp(deformSprite.Sprite.Depth, 0, 1)),
26  deformSprite.Origin,
27  -DrawRotation,
28  scale, color, Dir < 0, invert);
29  }
30 
31  public void Draw(SpriteBatch spriteBatch, Sprite sprite, Color color, float? depth = null, float scale = 1.0f, bool mirrorX = false, bool mirrorY = false, Vector2? origin = null)
32  {
33  if (!Enabled) { return; }
35  if (sprite == null) { return; }
36  SpriteEffects spriteEffect = (Dir == 1.0f) ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
37  if (mirrorX)
38  {
39  spriteEffect = spriteEffect == SpriteEffects.None ? SpriteEffects.FlipHorizontally : SpriteEffects.None;
40  }
41  if (mirrorY)
42  {
43  spriteEffect |= SpriteEffects.FlipVertically;
44  }
45  sprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y), color, origin ?? sprite.Origin, - drawRotation, scale, spriteEffect, depth);
46  }
47 
48  public void DebugDraw(SpriteBatch spriteBatch, Color color, bool forceColor = false)
49  {
50  if (!forceColor)
51  {
52  if (!FarseerBody.Enabled)
53  {
54  color = Color.Black;
55  }
56  else if (!FarseerBody.Awake)
57  {
58  color = Color.Blue;
59  }
60  }
61 
62  if (targetPosition != null)
63  {
64  Vector2 pos = ConvertUnits.ToDisplayUnits((Vector2)targetPosition);
65  if (Submarine != null) pos += Submarine.DrawPosition;
66 
67  GUI.DrawRectangle(spriteBatch,
68  new Vector2(pos.X - 5, -(pos.Y + 5)),
69  Vector2.One * 10.0f, GUIStyle.Red, false, 0, 3);
70  }
71 
72  if (drawOffset != Vector2.Zero)
73  {
74  Vector2 pos = ConvertUnits.ToDisplayUnits(FarseerBody.Position);
75  if (Submarine != null) pos += Submarine.DrawPosition;
76 
77  GUI.DrawLine(spriteBatch,
78  new Vector2(pos.X, -pos.Y),
79  new Vector2(DrawPosition.X, -DrawPosition.Y),
80  Color.Cyan, 0, 5);
81  }
82  if (bodyShapeTexture == null && IsValidShape(Radius, Height, Width))
83  {
84  switch (BodyShape)
85  {
86  case Shape.Rectangle:
87  {
88  float maxSize = Math.Max(ConvertUnits.ToDisplayUnits(Width), ConvertUnits.ToDisplayUnits(Height));
89  if (maxSize > 128.0f)
90  {
91  bodyShapeTextureScale = 128.0f / maxSize;
92  }
93  else
94  {
95  bodyShapeTextureScale = 1.0f;
96  }
97 
98  bodyShapeTexture = GUI.CreateRectangle(
99  (int)ConvertUnits.ToDisplayUnits(Width * bodyShapeTextureScale),
100  (int)ConvertUnits.ToDisplayUnits(Height * bodyShapeTextureScale));
101  break;
102  }
103  case Shape.Capsule:
104  case Shape.HorizontalCapsule:
105  {
106  float maxSize = Math.Max(ConvertUnits.ToDisplayUnits(Radius), ConvertUnits.ToDisplayUnits(Math.Max(Height, Width)));
107  if (maxSize > 128.0f)
108  {
109  bodyShapeTextureScale = 128.0f / maxSize;
110  }
111  else
112  {
113  bodyShapeTextureScale = 1.0f;
114  }
115 
116  bodyShapeTexture = GUI.CreateCapsule(
117  (int)ConvertUnits.ToDisplayUnits(Radius * bodyShapeTextureScale),
118  (int)ConvertUnits.ToDisplayUnits(Math.Max(Height, Width) * bodyShapeTextureScale));
119  break;
120  }
121  case Shape.Circle:
122  if (ConvertUnits.ToDisplayUnits(Radius) > 128.0f)
123  {
124  bodyShapeTextureScale = 128.0f / ConvertUnits.ToDisplayUnits(Radius);
125  }
126  else
127  {
128  bodyShapeTextureScale = 1.0f;
129  }
130  bodyShapeTexture = GUI.CreateCircle((int)ConvertUnits.ToDisplayUnits(Radius * bodyShapeTextureScale));
131  break;
132  default:
133  throw new NotImplementedException();
134  }
135  }
136 
137  float rot = -DrawRotation;
138  if (bodyShape == Shape.HorizontalCapsule)
139  {
140  rot -= MathHelper.PiOver2;
141  }
142 
143  if (bodyShapeTexture != null)
144  {
145  spriteBatch.Draw(
146  bodyShapeTexture,
147  new Vector2(DrawPosition.X, -DrawPosition.Y),
148  null,
149  color,
150  rot,
151  new Vector2(bodyShapeTexture.Width / 2, bodyShapeTexture.Height / 2),
152  1.0f / bodyShapeTextureScale, SpriteEffects.None, 0.0f);
153  }
154  }
155 
156  public PosInfo ClientRead(IReadMessage msg, float sendingTime, string parentDebugName)
157  {
158  float MaxVel = NetConfig.MaxPhysicsBodyVelocity;
159  float MaxAngularVel = NetConfig.MaxPhysicsBodyAngularVelocity;
160 
161  Vector2 newPosition = SimPosition;
162  float? newRotation = null;
163  bool awake = FarseerBody.Awake;
164  Vector2 newVelocity = LinearVelocity;
165  float? newAngularVelocity = null;
166 
167  newPosition = new Vector2(
168  msg.ReadSingle(),
169  msg.ReadSingle());
170 
171  awake = msg.ReadBoolean();
172  bool fixedRotation = msg.ReadBoolean();
173 
174  if (!fixedRotation)
175  {
176  newRotation = msg.ReadRangedSingle(0.0f, MathHelper.TwoPi, 8);
177  }
178  if (awake)
179  {
180  newVelocity = new Vector2(
181  msg.ReadRangedSingle(-MaxVel, MaxVel, 12),
182  msg.ReadRangedSingle(-MaxVel, MaxVel, 12));
183  newVelocity = NetConfig.Quantize(newVelocity, -MaxVel, MaxVel, 12);
184 
185  if (!fixedRotation)
186  {
187  newAngularVelocity = msg.ReadRangedSingle(-MaxAngularVel, MaxAngularVel, 8);
188  newAngularVelocity = NetConfig.Quantize(newAngularVelocity.Value, -MaxAngularVel, MaxAngularVel, 8);
189  }
190  }
191  msg.ReadPadBits();
192 
193  if (!MathUtils.IsValid(newPosition) ||
194  !MathUtils.IsValid(newVelocity) ||
195  (newRotation.HasValue && !MathUtils.IsValid(newRotation.Value)) ||
196  (newAngularVelocity.HasValue && !MathUtils.IsValid(newAngularVelocity.Value)))
197  {
198  string errorMsg = "Received invalid position data for \"" + parentDebugName
199  + "\" (position: " + newPosition + ", rotation: " + (newRotation ?? 0) + ", velocity: " + newVelocity + ", angular velocity: " + (newAngularVelocity ?? 0) + ")";
200 #if DEBUG
201  DebugConsole.ThrowError(errorMsg);
202 #endif
203  GameAnalyticsManager.AddErrorEventOnce("PhysicsBody.ClientRead:InvalidData" + parentDebugName,
204  GameAnalyticsManager.ErrorSeverity.Error,
205  errorMsg);
206  return null;
207  }
208 
209  return lastProcessedNetworkState > sendingTime ?
210  null :
211  new PosInfo(newPosition, newRotation, newVelocity, newAngularVelocity, sendingTime);
212  }
213 
214  partial void DisposeProjSpecific()
215  {
216  if (bodyShapeTexture != null)
217  {
218  bodyShapeTexture.Dispose();
219  bodyShapeTexture = null;
220  }
221  }
222  }
223 }
void Draw(Camera cam, Vector3 pos, Vector2 origin, float rotate, Vector2 scale, Color color, bool mirror=false, bool invert=false)
PosInfo ClientRead(IReadMessage msg, float sendingTime, string parentDebugName)
static bool IsValidShape(float radius, float height, float width)
void DebugDraw(SpriteBatch spriteBatch, Color color, bool forceColor=false)
void Draw(DeformableSprite deformSprite, Camera cam, Vector2 scale, Color color, bool invert=false)
void Draw(SpriteBatch spriteBatch, Sprite sprite, Color color, float? depth=null, float scale=1.0f, bool mirrorX=false, bool mirrorY=false, Vector2? origin=null)
void Draw(ISpriteBatch spriteBatch, Vector2 pos, float rotate=0.0f, float scale=1.0f, SpriteEffects spriteEffect=SpriteEffects.None)
Single ReadRangedSingle(Single min, Single max, int bitCount)