Client LuaCsForBarotrauma
BarotraumaClient/ClientSource/Map/LinkedSubmarine.cs
1 using System;
2 using Barotrauma.IO;
4 using Microsoft.Xna.Framework;
5 using Microsoft.Xna.Framework.Graphics;
6 using Microsoft.Xna.Framework.Input;
7 using System.Linq;
8 using System.Xml.Linq;
10 
11 namespace Barotrauma
12 {
13  partial class LinkedSubmarine : MapEntity
14  {
15  public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true)
16  {
17  if (!editing || wallVertices == null) { return; }
18 
19  Draw(spriteBatch, Position);
20 
21  if (!Item.ShowLinks) { return; }
22 
23  foreach (MapEntity e in linkedTo)
24  {
25  bool isLinkAllowed = e is Item item && item.HasTag(Tags.DockingPort);
26 
27  GUI.DrawLine(spriteBatch,
28  new Vector2(WorldPosition.X, -WorldPosition.Y),
29  new Vector2(e.WorldPosition.X, -e.WorldPosition.Y),
30  isLinkAllowed ? GUIStyle.Green * 0.5f : GUIStyle.Red * 0.5f, width: 3);
31  }
32  }
33 
34  public void Draw(SpriteBatch spriteBatch, Vector2 drawPos, float alpha = 1.0f)
35  {
36  Color color = (IsHighlighted) ? GUIStyle.Orange : GUIStyle.Green;
37  if (IsSelected) { color = GUIStyle.Red; }
38 
39  Vector2 pos = drawPos;
40 
41  for (int i = 0; i < wallVertices.Count; i++)
42  {
43  Vector2 startPos = wallVertices[i] + pos;
44  startPos.Y = -startPos.Y;
45 
46  Vector2 endPos = wallVertices[(i + 1) % wallVertices.Count] + pos;
47  endPos.Y = -endPos.Y;
48 
49  GUI.DrawLine(spriteBatch,
50  startPos,
51  endPos,
52  color * alpha, 0.0f, 5);
53  }
54 
55  pos.Y = -pos.Y;
56  GUI.DrawLine(spriteBatch, pos + Vector2.UnitY * 50.0f, pos - Vector2.UnitY * 50.0f, color * alpha, 0.0f, 5);
57  GUI.DrawLine(spriteBatch, pos + Vector2.UnitX * 50.0f, pos - Vector2.UnitX * 50.0f, color * alpha, 0.0f, 5);
58  }
59 
60  public override void UpdateEditing(Camera cam, float deltaTime)
61  {
62  if (editingHUD == null || editingHUD.UserData as LinkedSubmarine != this)
63  {
64  editingHUD = CreateEditingHUD();
65  }
66 
67  editingHUD.UpdateManually(deltaTime);
68 
69  if (!PlayerInput.PrimaryMouseButtonClicked() || !PlayerInput.KeyDown(Keys.Space)) { return; }
70 
71  Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
72 
73  foreach (MapEntity entity in HighlightedEntities)
74  {
75  if (entity == this|| entity is not Item || !entity.IsMouseOn(position)) { continue; }
76  if (((Item)entity).GetComponent<DockingPort>() == null) { continue; }
77  if (linkedTo.Contains(entity))
78  {
79  linkedTo.Remove(entity);
80  entity.linkedTo.Remove(this);
81  }
82  else
83  {
84  linkedTo.Add(entity);
85  if (!entity.linkedTo.Contains(this)) { entity.linkedTo.Add(this); }
86  }
87  }
88  }
89 
90  private GUIComponent CreateEditingHUD(bool inGame = false)
91  {
92  editingHUD = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.25f), GUI.Canvas, Anchor.CenterRight) { MinSize = new Point(400, 0) })
93  {
94  UserData = this
95  };
96  var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.8f), editingHUD.RectTransform, Anchor.Center))
97  {
98  Stretch = true,
99  AbsoluteSpacing = (int)(GUI.Scale * 5)
100  };
101 
102  new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.2f), paddedFrame.RectTransform),
103  TextManager.Get("LinkedSub"), font: GUIStyle.LargeFont);
104 
105  if (!inGame)
106  {
107  new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.2f), paddedFrame.RectTransform),
108  TextManager.Get("LinkLinkedSub"), textColor: GUIStyle.Orange, font: GUIStyle.SmallFont);
109  }
110 
111  var pathContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.2f), paddedFrame.RectTransform), isHorizontal: true);
112 
113  string filePath = this.filePath;
114  if (filePath.StartsWith("Submarines"))
115  {
116  //this is the old submarines path, try to find a local mod that has a submarine with this name
117  string subName = Path.GetFileNameWithoutExtension(filePath);
118  string foundPath = ContentPackageManager.LocalPackages.Concat(ContentPackageManager.VanillaCorePackage.ToEnumerable())
119  .SelectMany(p => p.GetFiles<SubmarineFile>())
120  .FirstOrDefault(f => Path.GetFileNameWithoutExtension(f.Path.Value).Equals(subName, StringComparison.OrdinalIgnoreCase))
121  ?.Path.Value;
122  if (foundPath.IsNullOrEmpty())
123  {
124  //no such sub found among the local mods, just guess the correct path
125  foundPath = Path.Combine(ContentPackage.LocalModsDir, subName, $"{subName}.sub");
126  }
127 
128  filePath = foundPath;
129  }
130 
131  var pathBox = new GUITextBox(new RectTransform(new Vector2(0.75f, 1.0f), pathContainer.RectTransform), filePath, font: GUIStyle.SmallFont);
132  var reloadButton = new GUIButton(new RectTransform(new Vector2(0.25f / pathBox.RectTransform.RelativeSize.X, 1.0f), pathBox.RectTransform, Anchor.CenterRight, Pivot.CenterLeft),
133  TextManager.Get("ReloadLinkedSub"), style: "GUIButtonSmall")
134  {
135  OnClicked = Reload,
136  UserData = pathBox,
137  ToolTip = TextManager.Get("ReloadLinkedSubTooltip")
138  };
139 
140  editingHUD.RectTransform.Resize(new Point(
141  editingHUD.Rect.Width,
142  (int)(paddedFrame.Children.Sum(c => c.Rect.Height + paddedFrame.AbsoluteSpacing) / paddedFrame.RectTransform.RelativeSize.Y)));
143 
145 
146  return editingHUD;
147  }
148 
149  private bool Reload(GUIButton button, object obj)
150  {
151  var pathBox = obj as GUITextBox;
152 
153  if (!File.Exists(pathBox.Text))
154  {
155  new GUIMessageBox(TextManager.Get("Error"), TextManager.GetWithVariable("ReloadLinkedSubError", "[file]", pathBox.Text));
156  pathBox.Flash(GUIStyle.Red);
157  pathBox.Text = filePath;
158  return false;
159  }
160 
161  XDocument doc = SubmarineInfo.OpenFile(pathBox.Text);
162  if (doc == null || doc.Root == null) { return false; }
163  doc.Root.SetAttributeValue("filepath", pathBox.Text);
164 
165  pathBox.Flash(GUIStyle.Green);
166 
167  GenerateWallVertices(doc.Root);
168  saveElement = doc.Root;
169  saveElement.Name = "LinkedSubmarine";
170  CargoCapacity = doc.Root.GetAttributeInt("cargocapacity", 0);
171 
172  filePath = pathBox.Text;
173 
174  return true;
175  }
176  }
177 }
Vector2 ScreenToWorld(Vector2 coords)
Definition: Camera.cs:410
virtual Vector2 WorldPosition
Definition: Entity.cs:49
void UpdateManually(float deltaTime, bool alsoChildren=false, bool recursive=true)
By default, all the gui elements are updated automatically in the same order they appear on the updat...
virtual Rectangle Rect
RectTransform RectTransform
override void Draw(SpriteBatch spriteBatch, bool editing, bool back=true)
void Draw(SpriteBatch spriteBatch, Vector2 drawPos, float alpha=1.0f)
override void UpdateEditing(Camera cam, float deltaTime)
static IEnumerable< MapEntity > HighlightedEntities
static bool KeyDown(InputType inputType)
void Resize(Point absoluteSize, bool resizeChildren=true)