Client LuaCsForBarotrauma
BarotraumaClient/ClientSource/Items/Components/RepairTool.cs
2 using FarseerPhysics;
3 using Microsoft.Xna.Framework;
4 using Microsoft.Xna.Framework.Graphics;
5 using System;
6 using System.Collections.Generic;
7 using System.Linq;
8 using System.Text;
9 using System.Threading.Tasks;
10 using System.Xml.Linq;
11 
13 {
14  partial class RepairTool
15 #if DEBUG
16  : IDrawableComponent
17 #endif
18  {
19 #if DEBUG
20  public Vector2 DrawSize
21  {
22  get { return GameMain.DebugDraw ? Vector2.One * Range : Vector2.Zero; }
23  }
24 #endif
25 
26  private readonly List<ParticleEmitter> particleEmitters = new List<ParticleEmitter>();
27  private readonly List<ParticleEmitter> particleEmitterHitStructure = new List<ParticleEmitter>();
28  private readonly List<ParticleEmitter> particleEmitterHitCharacter = new List<ParticleEmitter>();
29  private readonly List<(RelatedItem relatedItem, ParticleEmitter emitter)> particleEmitterHitItem = new List<(RelatedItem relatedItem, ParticleEmitter emitter)>();
30 
31  private float prevProgressBarState;
32  private Item prevProgressBarTarget = null;
33 
34  partial void InitProjSpecific(ContentXElement element)
35  {
36  foreach (var subElement in element.Elements())
37  {
38  switch (subElement.Name.ToString().ToLowerInvariant())
39  {
40  case "particleemitter":
41  particleEmitters.Add(new ParticleEmitter(subElement));
42  break;
43  case "particleemitterhititem":
44  Identifier[] identifiers = subElement.GetAttributeIdentifierArray("identifiers", Array.Empty<Identifier>());
45  if (identifiers.Length == 0) { identifiers = subElement.GetAttributeIdentifierArray("identifier", Array.Empty<Identifier>()); }
46  Identifier[] excludedIdentifiers = subElement.GetAttributeIdentifierArray("excludedidentifiers", Array.Empty<Identifier>());
47  if (excludedIdentifiers.Length == 0) { excludedIdentifiers = subElement.GetAttributeIdentifierArray("excludedidentifier", Array.Empty<Identifier>()); }
48 
49  particleEmitterHitItem.Add((new RelatedItem(identifiers, excludedIdentifiers), new ParticleEmitter(subElement)));
50  break;
51  case "particleemitterhitstructure":
52  particleEmitterHitStructure.Add(new ParticleEmitter(subElement));
53  break;
54  case "particleemitterhitcharacter":
55  particleEmitterHitCharacter.Add(new ParticleEmitter(subElement));
56  break;
57  }
58  }
59  }
60 
61 
62  partial void UseProjSpecific(float deltaTime, Vector2 raystart)
63  {
64  foreach (ParticleEmitter particleEmitter in particleEmitters)
65  {
66  float particleAngle = MathHelper.ToRadians(BarrelRotation);
67  if (item.body != null)
68  {
69  particleAngle += item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
70  }
71  particleEmitter.Emit(
72  deltaTime, ConvertUnits.ToDisplayUnits(raystart),
73  item.CurrentHull, particleAngle, particleEmitter.Prefab.Properties.CopyEntityAngle ? -particleAngle : 0);
74  }
75  }
76 
77  partial void FixStructureProjSpecific(Character user, float deltaTime, Structure targetStructure, int sectionIndex)
78  {
79  Vector2 progressBarPos = targetStructure.SectionPosition(sectionIndex);
80  if (targetStructure.Submarine != null)
81  {
82  progressBarPos += targetStructure.Submarine.DrawPosition;
83  }
84 
85  var progressBar = user.UpdateHUDProgressBar(
86  targetStructure.ID * 1000 + sectionIndex, //unique "identifier" for each wall section
87  progressBarPos,
88  MathUtils.InverseLerp(targetStructure.Prefab.MinHealth, targetStructure.Health, targetStructure.Health - targetStructure.SectionDamage(sectionIndex)),
89  GUIStyle.Red, GUIStyle.Green);
90 
91  if (progressBar != null) progressBar.Size = new Vector2(60.0f, 20.0f);
92 
93  Vector2 particlePos = ConvertUnits.ToDisplayUnits(pickedPosition);
94  if (targetStructure.Submarine != null) particlePos += targetStructure.Submarine.DrawPosition;
95  foreach (var emitter in particleEmitterHitStructure)
96  {
97  float particleAngle = item.body.Rotation + MathHelper.ToRadians(BarrelRotation) + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
98  emitter.Emit(deltaTime, particlePos, item.CurrentHull, particleAngle + MathHelper.Pi, -particleAngle + MathHelper.Pi);
99  }
100  }
101 
102  partial void FixCharacterProjSpecific(Character user, float deltaTime, Character targetCharacter)
103  {
104  Vector2 particlePos = ConvertUnits.ToDisplayUnits(pickedPosition);
105  if (targetCharacter.Submarine != null) particlePos += targetCharacter.Submarine.DrawPosition;
106  foreach (var emitter in particleEmitterHitCharacter)
107  {
108  float particleAngle = item.body.Rotation + MathHelper.ToRadians(BarrelRotation) + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
109  emitter.Emit(deltaTime, particlePos, item.CurrentHull, particleAngle + MathHelper.Pi, -particleAngle + MathHelper.Pi);
110  }
111  }
112 
113  partial void FixItemProjSpecific(Character user, float deltaTime, Item targetItem, bool showProgressBar)
114  {
115  if (showProgressBar)
116  {
117  float progressBarState = targetItem.ConditionPercentage / 100.0f;
118  if (!MathUtils.NearlyEqual(progressBarState, prevProgressBarState) || prevProgressBarTarget != targetItem)
119  {
120  var door = targetItem.GetComponent<Door>();
121  if (door == null || door.Stuck <= 0)
122  {
123  Vector2 progressBarPos = targetItem.DrawPosition;
124  var progressBar = user?.UpdateHUDProgressBar(
125  targetItem,
126  progressBarPos,
127  progressBarState,
128  GUIStyle.Red, GUIStyle.Green,
129  progressBarState < prevProgressBarState ? "progressbar.cutting" : "");
130  if (progressBar != null) { progressBar.Size = new Vector2(60.0f, 20.0f); }
131  }
132  prevProgressBarState = progressBarState;
133  prevProgressBarTarget = targetItem;
134  }
135  }
136 
137  Vector2 particlePos = ConvertUnits.ToDisplayUnits(pickedPosition);
138  if (targetItem.Submarine != null) particlePos += targetItem.Submarine.DrawPosition;
139  foreach ((RelatedItem relatedItem, ParticleEmitter emitter) in particleEmitterHitItem)
140  {
141  if (!relatedItem.MatchesItem(targetItem)) { continue; }
142  float particleAngle = item.body.Rotation + MathHelper.ToRadians(BarrelRotation) + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
143  emitter.Emit(deltaTime, particlePos, item.CurrentHull, particleAngle + MathHelper.Pi, -particleAngle + MathHelper.Pi);
144  }
145  }
146 #if DEBUG
147  public void Draw(SpriteBatch spriteBatch, bool editing, float itemDepth = -1, Color? overrideColor = null)
148  {
149  if (GameMain.DebugDraw && IsActive)
150  {
151  GUI.DrawLine(spriteBatch,
152  new Vector2(debugRayStartPos.X, -debugRayStartPos.Y),
153  new Vector2(debugRayEndPos.X, -debugRayEndPos.Y),
154  Color.Yellow, width: 3f);
155  }
156  }
157 #endif
158  }
159 }
readonly ParticleEmitterPrefab Prefab
void Emit(float deltaTime, Vector2 position, Hull? hullGuess=null, float angle=0.0f, float particleRotation=0.0f, float velocityMultiplier=1.0f, float sizeMultiplier=1.0f, float amountMultiplier=1.0f, Color? colorMultiplier=null, ParticlePrefab? overrideParticle=null, bool mirrorAngle=false, Tuple< Vector2, Vector2 >? tracerPoints=null)
readonly ParticleEmitterProperties Properties