Client LuaCsForBarotrauma
BarotraumaClient/ClientSource/Map/ItemAssemblyPrefab.cs
2 using Microsoft.Xna.Framework;
3 using Microsoft.Xna.Framework.Graphics;
4 using System;
5 using System.Collections.Generic;
6 using System.Linq;
7 using System.Xml.Linq;
8 
9 namespace Barotrauma
10 {
11  partial class ItemAssemblyPrefab : MapEntityPrefab
12  {
13  public void DrawIcon(SpriteBatch spriteBatch, GUICustomComponent guiComponent)
14  {
15  Rectangle drawArea = guiComponent.Rect;
16 
17  float scale = Math.Min(drawArea.Width / (float)Bounds.Width, drawArea.Height / (float)Bounds.Height) * 0.9f;
18 
19  foreach (var displayEntity in DisplayEntities)
20  {
21  var entityPrefab = FindByIdentifier(displayEntity.Identifier);
22  if (entityPrefab is CoreEntityPrefab || entityPrefab == null) { continue; }
23  var drawRect = new Rectangle(
24  (int)(displayEntity.Rect.X * scale) + drawArea.Center.X, (int)((displayEntity.Rect.Y) * scale) - drawArea.Center.Y,
25  (int)(displayEntity.Rect.Width * scale), (int)(displayEntity.Rect.Height * scale));
26  entityPrefab.DrawPlacing(spriteBatch, drawRect, entityPrefab.Scale * scale, rotation: displayEntity.RotationRad);
27  }
28  }
29 
30  public override void DrawPlacing(SpriteBatch spriteBatch, Camera cam)
31  {
32  base.DrawPlacing(spriteBatch, cam);
33  Draw(
34  spriteBatch,
36  }
37 
38  public void Draw(SpriteBatch spriteBatch, Vector2 pos)
39  {
40  foreach (var displayEntity in DisplayEntities)
41  {
42  var entityPrefab = FindByIdentifier(displayEntity.Identifier);
43  if (entityPrefab == null) { continue; }
44  Rectangle drawRect = displayEntity.Rect;
45  drawRect.Location += pos.ToPoint();
46  entityPrefab.DrawPlacing(spriteBatch, drawRect, entityPrefab.Scale, rotation: displayEntity.RotationRad);
47  }
48  }
49 
50  public static XElement Save(List<MapEntity> entities, string name, string description, bool hideInMenus = false)
51  {
52  XElement element = new XElement("ItemAssembly",
53  new XAttribute("name", name),
54  new XAttribute("description", description),
55  new XAttribute("hideinmenus", hideInMenus));
56 
57  //move the entities so that their "center of mass" is at {0,0}
58  var assemblyEntities = MapEntity.CopyEntities(entities);
59  for (int i = 0; i < assemblyEntities.Count && i < entities.Count; i++)
60  {
61  assemblyEntities[i].Layer = entities[i].Layer;
62  }
63 
64  //find wires and items that are contained inside another item
65  //place them at {0,0} to prevent them from messing up the origin of the prefab and to hide them in preview
66  List<MapEntity> disabledEntities = new List<MapEntity>();
67  foreach (MapEntity mapEntity in assemblyEntities)
68  {
69  if (mapEntity is Item item)
70  {
71  var wire = item.GetComponent<Wire>();
72  if (item.ParentInventory != null ||
73  (wire != null && wire.Connections.Any(c => c != null)))
74  {
75  item.SetTransform(Vector2.Zero, 0.0f);
76  disabledEntities.Add(mapEntity);
77  }
78  }
79  }
80 
81  float minX = int.MaxValue, maxX = int.MinValue;
82  float minY = int.MaxValue, maxY = int.MinValue;
83  foreach (MapEntity mapEntity in assemblyEntities)
84  {
85  if (disabledEntities.Contains(mapEntity)) { continue; }
86  minX = Math.Min(minX, mapEntity.WorldRect.X);
87  maxX = Math.Max(maxX, mapEntity.WorldRect.Right);
88  minY = Math.Min(minY, mapEntity.WorldRect.Y - mapEntity.WorldRect.Height);
89  maxY = Math.Max(maxY, mapEntity.WorldRect.Y);
90  }
91  Vector2 center = new Vector2((minX + maxX) / 2.0f, (minY + maxY) / 2.0f);
92  if (Submarine.MainSub != null) { center -= Submarine.MainSub.HiddenSubPosition; }
93 
94  Vector2 offsetFromGrid = new Vector2(
95  MathUtils.RoundTowardsClosest(center.X, Submarine.GridSize.X) - center.X,
96  MathUtils.RoundTowardsClosest(center.Y, Submarine.GridSize.Y) - center.Y - Submarine.GridSize.Y / 2);
97 
98  MapEntity.SelectedList.Clear();
99  assemblyEntities.ForEach(e => MapEntity.AddSelection(e));
100 
101  foreach (MapEntity mapEntity in assemblyEntities)
102  {
103  mapEntity.Move(-center - offsetFromGrid);
104  mapEntity.Submarine = Submarine.MainSub;
105  var entityElement = mapEntity.Save(element);
106  if (disabledEntities.Contains(mapEntity))
107  {
108  entityElement.Add(new XAttribute("hideinassemblypreview", "true"));
109  }
110  }
111 
112  //restore the previous selection
113  MapEntity.SelectedList.Clear();
114  entities.ForEach(e => MapEntity.AddSelection(e));
115 
116  return element;
117  }
118  }
119 }
Submarine Submarine
Definition: Entity.cs:53
virtual Rectangle Rect
GUIComponent that can be used to render custom content on the UI
void DrawIcon(SpriteBatch spriteBatch, GUICustomComponent guiComponent)
static XElement Save(List< MapEntity > entities, string name, string description, bool hideInMenus=false)
override void DrawPlacing(SpriteBatch spriteBatch, Camera cam)
virtual void Move(Vector2 amount, bool ignoreContacts=true)
static List< MapEntity > CopyEntities(List< MapEntity > entities)
copies a list of entities to the "clipboard" (copiedList)
virtual XElement Save(XElement parentElement)
static MapEntityPrefab FindByIdentifier(Identifier identifier)
static Vector2 MouseToWorldGrid(Camera cam, Submarine sub, Vector2? mousePos=null, bool round=false)