Split Machines ItemComponents
There's still a lot of work to do before we can get the server to compile
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
using Barotrauma.Lights;
|
||||
using Barotrauma.Networking;
|
||||
using FarseerPhysics;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class Door : ItemComponent, IDrawableComponent, IServerSerializable
|
||||
{
|
||||
private ConvexHull convexHull;
|
||||
private ConvexHull convexHull2;
|
||||
|
||||
private Vector2[] GetConvexHullCorners(Rectangle rect)
|
||||
{
|
||||
Vector2[] corners = new Vector2[4];
|
||||
corners[0] = new Vector2(rect.X, rect.Y - rect.Height);
|
||||
corners[1] = new Vector2(rect.X, rect.Y);
|
||||
corners[2] = new Vector2(rect.Right, rect.Y);
|
||||
corners[3] = new Vector2(rect.Right, rect.Y - rect.Height);
|
||||
|
||||
return corners;
|
||||
}
|
||||
|
||||
private void UpdateConvexHulls()
|
||||
{
|
||||
doorRect = new Rectangle(
|
||||
item.Rect.Center.X - (int)(doorSprite.size.X / 2),
|
||||
item.Rect.Y - item.Rect.Height / 2 + (int)(doorSprite.size.Y / 2.0f),
|
||||
(int)doorSprite.size.X,
|
||||
(int)doorSprite.size.Y);
|
||||
|
||||
Rectangle rect = doorRect;
|
||||
if (isHorizontal)
|
||||
{
|
||||
rect.Width = (int)(rect.Width * (1.0f - openState));
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.Height = (int)(rect.Height * (1.0f - openState));
|
||||
}
|
||||
|
||||
if (window.Height > 0 && window.Width > 0)
|
||||
{
|
||||
rect.Height = -window.Y;
|
||||
|
||||
rect.Y += (int)(doorRect.Height * openState);
|
||||
rect.Height = Math.Max(rect.Height - (rect.Y - doorRect.Y), 0);
|
||||
rect.Y = Math.Min(doorRect.Y, rect.Y);
|
||||
|
||||
if (convexHull2 != null)
|
||||
{
|
||||
Rectangle rect2 = doorRect;
|
||||
rect2.Y = rect2.Y + window.Y - window.Height;
|
||||
|
||||
rect2.Y += (int)(doorRect.Height * openState);
|
||||
rect2.Y = Math.Min(doorRect.Y, rect2.Y);
|
||||
rect2.Height = rect2.Y - (doorRect.Y - (int)(doorRect.Height * (1.0f - openState)));
|
||||
//convexHull2.SetVertices(GetConvexHullCorners(rect2));
|
||||
|
||||
if (rect2.Height == 0)
|
||||
{
|
||||
convexHull2.Enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
convexHull2.Enabled = true;
|
||||
convexHull2.SetVertices(GetConvexHullCorners(rect2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (convexHull == null) return;
|
||||
|
||||
if (rect.Height == 0 || rect.Width == 0)
|
||||
{
|
||||
convexHull.Enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
convexHull.Enabled = true;
|
||||
convexHull.SetVertices(GetConvexHullCorners(rect));
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing)
|
||||
{
|
||||
Color color = (item.IsSelected) ? Color.Green : Color.White;
|
||||
color = color * (item.Condition / 100.0f);
|
||||
color.A = 255;
|
||||
|
||||
//prefab.sprite.Draw(spriteBatch, new Vector2(rect.X, -rect.Y), new Vector2(rect.Width, rect.Height), color);
|
||||
|
||||
if (stuck > 0.0f && weldedSprite != null)
|
||||
{
|
||||
Vector2 weldSpritePos = new Vector2(item.Rect.Center.X, item.Rect.Y - item.Rect.Height / 2.0f);
|
||||
if (item.Submarine != null) weldSpritePos += item.Submarine.Position;
|
||||
weldSpritePos.Y = -weldSpritePos.Y;
|
||||
|
||||
weldedSprite.Draw(spriteBatch,
|
||||
weldSpritePos, Color.White * (stuck / 100.0f), 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
if (openState == 1.0f)
|
||||
{
|
||||
body.Enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (isHorizontal)
|
||||
{
|
||||
Vector2 pos = new Vector2(item.Rect.X, item.Rect.Y - item.Rect.Height / 2);
|
||||
if (item.Submarine != null) pos += item.Submarine.DrawPosition;
|
||||
pos.Y = -pos.Y;
|
||||
|
||||
spriteBatch.Draw(doorSprite.Texture, pos,
|
||||
new Rectangle((int)(doorSprite.SourceRect.X + doorSprite.size.X * openState), (int)doorSprite.SourceRect.Y,
|
||||
(int)(doorSprite.size.X * (1.0f - openState)), (int)doorSprite.size.Y),
|
||||
color, 0.0f, doorSprite.Origin, 1.0f, SpriteEffects.None, doorSprite.Depth);
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 pos = new Vector2(item.Rect.Center.X, item.Rect.Y);
|
||||
if (item.Submarine != null) pos += item.Submarine.DrawPosition;
|
||||
pos.Y = -pos.Y;
|
||||
|
||||
spriteBatch.Draw(doorSprite.Texture, pos,
|
||||
new Rectangle(doorSprite.SourceRect.X, (int)(doorSprite.SourceRect.Y + doorSprite.size.Y * openState),
|
||||
(int)doorSprite.size.X, (int)(doorSprite.size.Y * (1.0f - openState))),
|
||||
color, 0.0f, doorSprite.Origin, 1.0f, SpriteEffects.None, doorSprite.Depth);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Xml.Linq;
|
||||
using Lidgren.Network;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Barotrauma.Networking;
|
||||
using System.IO;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
class ItemSound
|
||||
{
|
||||
public readonly Sound Sound;
|
||||
public readonly ActionType Type;
|
||||
|
||||
public string VolumeProperty;
|
||||
|
||||
public float VolumeMultiplier;
|
||||
|
||||
public readonly float Range;
|
||||
|
||||
public readonly bool Loop;
|
||||
|
||||
public ItemSound(Sound sound, ActionType type, float range, bool loop = false)
|
||||
{
|
||||
this.Sound = sound;
|
||||
this.Type = type;
|
||||
this.Range = range;
|
||||
|
||||
this.Loop = loop;
|
||||
}
|
||||
}
|
||||
|
||||
partial class ItemComponent : IPropertyObject
|
||||
{
|
||||
private Dictionary<ActionType, List<ItemSound>> sounds;
|
||||
|
||||
private GUIFrame guiFrame;
|
||||
|
||||
protected GUIFrame GuiFrame
|
||||
{
|
||||
get
|
||||
{
|
||||
if (guiFrame == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error: the component " + name + " in " + item.Name + " doesn't have a GuiFrame component");
|
||||
guiFrame = new GUIFrame(new Rectangle(0, 0, 100, 100), Color.Black);
|
||||
}
|
||||
return guiFrame;
|
||||
}
|
||||
}
|
||||
|
||||
private ItemSound loopingSound;
|
||||
private int loopingSoundIndex;
|
||||
public void PlaySound(ActionType type, Vector2 position)
|
||||
{
|
||||
if (loopingSound != null)
|
||||
{
|
||||
loopingSoundIndex = loopingSound.Sound.Loop(loopingSoundIndex, GetSoundVolume(loopingSound), position, loopingSound.Range);
|
||||
return;
|
||||
}
|
||||
|
||||
List<ItemSound> matchingSounds;
|
||||
if (!sounds.TryGetValue(type, out matchingSounds)) return;
|
||||
|
||||
ItemSound itemSound = null;
|
||||
if (!Sounds.SoundManager.IsPlaying(loopingSoundIndex))
|
||||
{
|
||||
int index = Rand.Int(matchingSounds.Count);
|
||||
itemSound = matchingSounds[index];
|
||||
}
|
||||
|
||||
if (itemSound == null) return;
|
||||
|
||||
if (itemSound.Loop)
|
||||
{
|
||||
loopingSound = itemSound;
|
||||
|
||||
loopingSoundIndex = loopingSound.Sound.Loop(loopingSoundIndex, GetSoundVolume(loopingSound), position, loopingSound.Range);
|
||||
}
|
||||
else
|
||||
{
|
||||
float volume = GetSoundVolume(itemSound);
|
||||
if (volume == 0.0f) return;
|
||||
itemSound.Sound.Play(volume, itemSound.Range, position);
|
||||
}
|
||||
}
|
||||
|
||||
public void StopSounds(ActionType type)
|
||||
{
|
||||
if (loopingSoundIndex <= 0) return;
|
||||
|
||||
if (loopingSound == null) return;
|
||||
|
||||
if (loopingSound.Type != type) return;
|
||||
|
||||
if (Sounds.SoundManager.IsPlaying(loopingSoundIndex))
|
||||
{
|
||||
Sounds.SoundManager.Stop(loopingSoundIndex);
|
||||
loopingSound = null;
|
||||
loopingSoundIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
private float GetSoundVolume(ItemSound sound)
|
||||
{
|
||||
if (sound == null) return 0.0f;
|
||||
if (sound.VolumeProperty == "") return 1.0f;
|
||||
|
||||
ObjectProperty op = null;
|
||||
if (properties.TryGetValue(sound.VolumeProperty.ToLowerInvariant(), out op))
|
||||
{
|
||||
float newVolume = 0.0f;
|
||||
try
|
||||
{
|
||||
newVolume = (float)op.GetValue();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
newVolume *= sound.VolumeMultiplier;
|
||||
|
||||
return MathHelper.Clamp(newVolume, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
//public virtual void Draw(SpriteBatch spriteBatch, bool editing = false)
|
||||
//{
|
||||
// item.drawableComponents = Array.FindAll(item.drawableComponents, i => i != this);
|
||||
//}
|
||||
|
||||
public virtual void DrawHUD(SpriteBatch spriteBatch, Character character) { }
|
||||
|
||||
public virtual void AddToGUIUpdateList() { }
|
||||
|
||||
public virtual void UpdateHUD(Character character) { }
|
||||
|
||||
private bool LoadElemProjSpecific(XElement subElement)
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
{
|
||||
case "guiframe":
|
||||
string rectStr = ToolBox.GetAttributeString(subElement, "rect", "0.0,0.0,0.5,0.5");
|
||||
|
||||
string[] components = rectStr.Split(',');
|
||||
if (components.Length < 4) break;
|
||||
|
||||
Vector4 rect = ToolBox.GetAttributeVector4(subElement, "rect", Vector4.One);
|
||||
if (components[0].Contains(".")) rect.X *= GameMain.GraphicsWidth;
|
||||
if (components[1].Contains(".")) rect.Y *= GameMain.GraphicsHeight;
|
||||
if (components[2].Contains(".")) rect.Z *= GameMain.GraphicsWidth;
|
||||
if (components[3].Contains(".")) rect.W *= GameMain.GraphicsHeight;
|
||||
|
||||
string style = ToolBox.GetAttributeString(subElement, "style", "");
|
||||
|
||||
Vector4 color = ToolBox.GetAttributeVector4(subElement, "color", Vector4.One);
|
||||
|
||||
Alignment alignment = Alignment.Center;
|
||||
try
|
||||
{
|
||||
alignment = (Alignment)Enum.Parse(typeof(Alignment),
|
||||
ToolBox.GetAttributeString(subElement, "alignment", "Center"), true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
DebugConsole.ThrowError("Error in " + subElement.Parent + "! \"" + subElement.Parent.Attribute("type").Value + "\" is not a valid alignment");
|
||||
}
|
||||
|
||||
guiFrame = new GUIFrame(
|
||||
new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Z, (int)rect.W),
|
||||
new Color(color.X, color.Y, color.Z) * color.W,
|
||||
alignment, style);
|
||||
|
||||
break;
|
||||
case "sound":
|
||||
string filePath = ToolBox.GetAttributeString(subElement, "file", "");
|
||||
|
||||
if (filePath == "") filePath = ToolBox.GetAttributeString(subElement, "sound", "");
|
||||
|
||||
if (filePath == "")
|
||||
{
|
||||
DebugConsole.ThrowError("Error when instantiating item \"" + item.Name + "\" - sound with no file path set");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!filePath.Contains("/") && !filePath.Contains("\\") && !filePath.Contains(Path.DirectorySeparatorChar))
|
||||
{
|
||||
filePath = Path.Combine(Path.GetDirectoryName(item.Prefab.ConfigFile), filePath);
|
||||
}
|
||||
|
||||
ActionType type;
|
||||
|
||||
try
|
||||
{
|
||||
type = (ActionType)Enum.Parse(typeof(ActionType), ToolBox.GetAttributeString(subElement, "type", ""), true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Invalid sound type in " + subElement + "!", e);
|
||||
break;
|
||||
}
|
||||
|
||||
Sound sound = Sound.Load(filePath);
|
||||
|
||||
float range = ToolBox.GetAttributeFloat(subElement, "range", 800.0f);
|
||||
bool loop = ToolBox.GetAttributeBool(subElement, "loop", false);
|
||||
ItemSound itemSound = new ItemSound(sound, type, range, loop);
|
||||
itemSound.VolumeProperty = ToolBox.GetAttributeString(subElement, "volume", "");
|
||||
itemSound.VolumeMultiplier = ToolBox.GetAttributeFloat(subElement, "volumemultiplier", 1.0f);
|
||||
|
||||
List<ItemSound> soundList = null;
|
||||
if (!sounds.TryGetValue(itemSound.Type, out soundList))
|
||||
{
|
||||
soundList = new List<ItemSound>();
|
||||
sounds.Add(itemSound.Type, soundList);
|
||||
}
|
||||
|
||||
soundList.Add(itemSound);
|
||||
break;
|
||||
default:
|
||||
return false; //unknown element
|
||||
}
|
||||
return true; //element processed
|
||||
}
|
||||
|
||||
//Starts a coroutine that will read the correct state of the component from the NetBuffer when correctionTimer reaches zero.
|
||||
protected void StartDelayedCorrection(ServerNetObject type, NetBuffer buffer, float sendingTime)
|
||||
{
|
||||
if (delayedCorrectionCoroutine != null) CoroutineManager.StopCoroutines(delayedCorrectionCoroutine);
|
||||
|
||||
delayedCorrectionCoroutine = CoroutineManager.StartCoroutine(DoDelayedCorrection(type, buffer, sendingTime));
|
||||
}
|
||||
|
||||
private IEnumerable<object> DoDelayedCorrection(ServerNetObject type, NetBuffer buffer, float sendingTime)
|
||||
{
|
||||
while (correctionTimer > 0.0f)
|
||||
{
|
||||
correctionTimer -= CoroutineManager.DeltaTime;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
((IServerSerializable)this).ClientRead(type, buffer, sendingTime);
|
||||
|
||||
correctionTimer = 0.0f;
|
||||
delayedCorrectionCoroutine = null;
|
||||
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
public virtual XElement Save(XElement parentElement)
|
||||
{
|
||||
XElement componentElement = new XElement(name);
|
||||
|
||||
foreach (RelatedItem ri in requiredItems)
|
||||
{
|
||||
XElement newElement = new XElement("requireditem");
|
||||
ri.Save(newElement);
|
||||
componentElement.Add(newElement);
|
||||
}
|
||||
|
||||
ObjectProperty.SaveProperties(this, componentElement);
|
||||
|
||||
parentElement.Add(componentElement);
|
||||
return componentElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class ItemContainer : ItemComponent, IDrawableComponent
|
||||
{
|
||||
//TODO: shouldn't this be overriding the base method?
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing = false)
|
||||
{
|
||||
if (hideItems || (item.body != null && !item.body.Enabled)) return;
|
||||
|
||||
Vector2 transformedItemPos = itemPos;
|
||||
Vector2 transformedItemInterval = itemInterval;
|
||||
float currentRotation = itemRotation;
|
||||
|
||||
if (item.body == null)
|
||||
{
|
||||
transformedItemPos = new Vector2(item.Rect.X, item.Rect.Y);
|
||||
if (item.Submarine != null) transformedItemPos += item.Submarine.DrawPosition;
|
||||
transformedItemPos = transformedItemPos + itemPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
//item.body.Enabled = true;
|
||||
|
||||
Matrix transform = Matrix.CreateRotationZ(item.body.Rotation);
|
||||
|
||||
if (item.body.Dir == -1.0f)
|
||||
{
|
||||
transformedItemPos.X = -transformedItemPos.X;
|
||||
transformedItemInterval.X = -transformedItemInterval.X;
|
||||
}
|
||||
transformedItemPos = Vector2.Transform(transformedItemPos, transform);
|
||||
transformedItemInterval = Vector2.Transform(transformedItemInterval, transform);
|
||||
|
||||
transformedItemPos += item.DrawPosition;
|
||||
|
||||
currentRotation += item.body.Rotation;
|
||||
}
|
||||
|
||||
foreach (Item containedItem in Inventory.Items)
|
||||
{
|
||||
if (containedItem == null) continue;
|
||||
|
||||
containedItem.Sprite.Draw(
|
||||
spriteBatch,
|
||||
new Vector2(transformedItemPos.X, -transformedItemPos.Y),
|
||||
-currentRotation,
|
||||
1.0f,
|
||||
(item.body != null && item.body.Dir == -1) ? SpriteEffects.FlipHorizontally : SpriteEffects.None);
|
||||
|
||||
transformedItemPos += transformedItemInterval;
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateHUD(Character character)
|
||||
{
|
||||
Inventory.Update((float)Timing.Step);
|
||||
}
|
||||
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
Inventory.Draw(spriteBatch);
|
||||
}
|
||||
|
||||
public override XElement Save(XElement parentElement)
|
||||
{
|
||||
XElement componentElement = base.Save(parentElement);
|
||||
|
||||
string[] itemIdStrings = new string[Inventory.Items.Length];
|
||||
for (int i = 0; i < Inventory.Items.Length; i++)
|
||||
{
|
||||
itemIdStrings[i] = (Inventory.Items[i] == null) ? "0" : Inventory.Items[i].ID.ToString();
|
||||
}
|
||||
|
||||
componentElement.Add(new XAttribute("contained", string.Join(",", itemIdStrings)));
|
||||
|
||||
return componentElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Barotrauma.Lights;
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Networking;
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class LightComponent : Powered, IServerSerializable, IDrawableComponent
|
||||
{
|
||||
private LightSource light;
|
||||
|
||||
public void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch, bool editing = false)
|
||||
{
|
||||
if (light.LightSprite != null && (item.body == null || item.body.Enabled))
|
||||
{
|
||||
light.LightSprite.Draw(spriteBatch, new Vector2(item.DrawPosition.X, -item.DrawPosition.Y), lightColor * lightBrightness, 0.0f, 1.0f, Microsoft.Xna.Framework.Graphics.SpriteEffects.None, item.Sprite.Depth - 0.0001f);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
|
||||
{
|
||||
IsOn = msg.ReadBoolean();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using Barotrauma.Networking;
|
||||
using Lidgren.Network;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class Deconstructor : Powered, IServerSerializable, IClientSerializable
|
||||
{
|
||||
GUIProgressBar progressBar;
|
||||
GUIButton activateButton;
|
||||
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
GuiFrame.Draw(spriteBatch);
|
||||
}
|
||||
|
||||
public override void AddToGUIUpdateList()
|
||||
{
|
||||
GuiFrame.AddToGUIUpdateList();
|
||||
}
|
||||
|
||||
public override void UpdateHUD(Character character)
|
||||
{
|
||||
GuiFrame.Update((float)Timing.Step);
|
||||
}
|
||||
|
||||
private bool ToggleActive(GUIButton button, object obj)
|
||||
{
|
||||
SetActive(!IsActive, Character.Controlled);
|
||||
|
||||
currPowerConsumption = IsActive ? powerConsumption : 0.0f;
|
||||
|
||||
if (GameMain.Server != null)
|
||||
{
|
||||
item.CreateServerEvent(this);
|
||||
}
|
||||
else if (GameMain.Client != null)
|
||||
{
|
||||
item.CreateClientEvent(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ClientWrite(NetBuffer msg, object[] extraData = null)
|
||||
{
|
||||
msg.Write(IsActive);
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
|
||||
{
|
||||
SetActive(msg.ReadBoolean());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class Engine : Powered
|
||||
{
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
//isActive = true;
|
||||
GuiFrame.Draw(spriteBatch);
|
||||
|
||||
//int width = 300, height = 300;
|
||||
//int x = Game1.GraphicsWidth / 2 - width / 2;
|
||||
//int y = Game1.GraphicsHeight / 2 - height / 2 - 50;
|
||||
|
||||
//GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black, true);
|
||||
|
||||
GUI.Font.DrawString(spriteBatch, "Force: " + (int)(targetForce) + " %", new Vector2(GuiFrame.Rect.X + 30, GuiFrame.Rect.Y + 30), Color.White);
|
||||
}
|
||||
|
||||
public override void AddToGUIUpdateList()
|
||||
{
|
||||
GuiFrame.AddToGUIUpdateList();
|
||||
}
|
||||
|
||||
public override void UpdateHUD(Character character)
|
||||
{
|
||||
GuiFrame.Update(1.0f / 60.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
using Barotrauma.Networking;
|
||||
using Lidgren.Network;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class Fabricator : Powered, IServerSerializable, IClientSerializable
|
||||
{
|
||||
private GUIListBox itemList;
|
||||
|
||||
private GUIFrame selectedItemFrame;
|
||||
|
||||
private GUIProgressBar progressBar;
|
||||
private GUIButton activateButton;
|
||||
|
||||
private void InitProjSpecific()
|
||||
{
|
||||
GuiFrame.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
|
||||
|
||||
itemList = new GUIListBox(new Rectangle(0, 0, GuiFrame.Rect.Width / 2 - 20, 0), "", GuiFrame);
|
||||
itemList.OnSelected = SelectItem;
|
||||
|
||||
foreach (FabricableItem fi in fabricableItems)
|
||||
{
|
||||
GUIFrame frame = new GUIFrame(new Rectangle(0, 0, 0, 50), Color.Transparent, null, itemList)
|
||||
{
|
||||
UserData = fi,
|
||||
Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f),
|
||||
HoverColor = Color.Gold * 0.2f,
|
||||
SelectedColor = Color.Gold * 0.5f,
|
||||
ToolTip = fi.TargetItem.Description
|
||||
};
|
||||
|
||||
GUITextBlock textBlock = new GUITextBlock(
|
||||
new Rectangle(40, 0, 0, 25),
|
||||
fi.TargetItem.Name,
|
||||
Color.Transparent, Color.White,
|
||||
Alignment.Left, Alignment.Left,
|
||||
null, frame);
|
||||
textBlock.ToolTip = fi.TargetItem.Description;
|
||||
textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
|
||||
|
||||
if (fi.TargetItem.sprite != null)
|
||||
{
|
||||
GUIImage img = new GUIImage(new Rectangle(0, 0, 40, 40), fi.TargetItem.sprite, Alignment.Left, frame);
|
||||
img.Scale = Math.Min(Math.Min(40.0f / img.SourceRect.Width, 40.0f / img.SourceRect.Height), 1.0f);
|
||||
img.Color = fi.TargetItem.SpriteColor;
|
||||
img.ToolTip = fi.TargetItem.Description;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool SelectItem(GUIComponent component, object obj)
|
||||
{
|
||||
FabricableItem targetItem = obj as FabricableItem;
|
||||
if (targetItem == null) return false;
|
||||
|
||||
if (selectedItemFrame != null) GuiFrame.RemoveChild(selectedItemFrame);
|
||||
|
||||
//int width = 200, height = 150;
|
||||
selectedItemFrame = new GUIFrame(new Rectangle(0, 0, (int)(GuiFrame.Rect.Width * 0.4f), 300), Color.Black * 0.8f, Alignment.CenterY | Alignment.Right, null, GuiFrame);
|
||||
|
||||
selectedItemFrame.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
|
||||
|
||||
progressBar = new GUIProgressBar(new Rectangle(0, 0, 0, 20), Color.Green, "", 0.0f, Alignment.BottomCenter, selectedItemFrame);
|
||||
progressBar.IsHorizontal = true;
|
||||
|
||||
if (targetItem.TargetItem.sprite != null)
|
||||
{
|
||||
int y = 0;
|
||||
|
||||
GUIImage img = new GUIImage(new Rectangle(10, 0, 40, 40), targetItem.TargetItem.sprite, Alignment.TopLeft, selectedItemFrame);
|
||||
img.Scale = Math.Min(Math.Min(40.0f / img.SourceRect.Width, 40.0f / img.SourceRect.Height), 1.0f);
|
||||
img.Color = targetItem.TargetItem.SpriteColor;
|
||||
|
||||
new GUITextBlock(
|
||||
new Rectangle(60, 0, 0, 25),
|
||||
targetItem.TargetItem.Name,
|
||||
Color.Transparent, Color.White,
|
||||
Alignment.TopLeft,
|
||||
Alignment.TopLeft, null,
|
||||
selectedItemFrame, true);
|
||||
|
||||
y += 40;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(targetItem.TargetItem.Description))
|
||||
{
|
||||
var description = new GUITextBlock(
|
||||
new Rectangle(0, y, 0, 0),
|
||||
targetItem.TargetItem.Description,
|
||||
"", Alignment.TopLeft, Alignment.TopLeft,
|
||||
selectedItemFrame, true, GUI.SmallFont);
|
||||
|
||||
y += description.Rect.Height + 10;
|
||||
}
|
||||
|
||||
|
||||
List<Skill> inadequateSkills = new List<Skill>();
|
||||
|
||||
if (Character.Controlled != null)
|
||||
{
|
||||
inadequateSkills = targetItem.RequiredSkills.FindAll(skill => Character.Controlled.GetSkillLevel(skill.Name) < skill.Level);
|
||||
}
|
||||
|
||||
Color textColor = Color.White;
|
||||
string text;
|
||||
if (!inadequateSkills.Any())
|
||||
{
|
||||
text = "Required items:\n";
|
||||
foreach (Tuple<ItemPrefab, int> ip in targetItem.RequiredItems)
|
||||
{
|
||||
text += " - " + ip.Item1.Name + " x" + ip.Item2 + "\n";
|
||||
}
|
||||
text += "Required time: " + targetItem.RequiredTime + " s";
|
||||
}
|
||||
else
|
||||
{
|
||||
text = "Skills required to calibrate:\n";
|
||||
foreach (Skill skill in inadequateSkills)
|
||||
{
|
||||
text += " - " + skill.Name + " lvl " + skill.Level + "\n";
|
||||
}
|
||||
|
||||
textColor = Color.Red;
|
||||
}
|
||||
|
||||
new GUITextBlock(
|
||||
new Rectangle(0, y, 0, 25),
|
||||
text,
|
||||
Color.Transparent, textColor,
|
||||
Alignment.TopLeft,
|
||||
Alignment.TopLeft, null,
|
||||
selectedItemFrame);
|
||||
|
||||
activateButton = new GUIButton(new Rectangle(0, -30, 100, 20), "Create", Color.White, Alignment.CenterX | Alignment.Bottom, "", selectedItemFrame);
|
||||
activateButton.OnClicked = StartButtonClicked;
|
||||
activateButton.UserData = targetItem;
|
||||
activateButton.Enabled = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool StartButtonClicked(GUIButton button, object obj)
|
||||
{
|
||||
if (fabricatedItem == null)
|
||||
{
|
||||
StartFabricating(obj as FabricableItem, Character.Controlled);
|
||||
}
|
||||
else
|
||||
{
|
||||
CancelFabricating(Character.Controlled);
|
||||
}
|
||||
|
||||
if (GameMain.Server != null)
|
||||
{
|
||||
item.CreateServerEvent(this);
|
||||
}
|
||||
else if (GameMain.Client != null)
|
||||
{
|
||||
item.CreateClientEvent(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
GuiFrame.Draw(spriteBatch);
|
||||
}
|
||||
|
||||
public override void AddToGUIUpdateList()
|
||||
{
|
||||
GuiFrame.AddToGUIUpdateList();
|
||||
}
|
||||
|
||||
public override void UpdateHUD(Character character)
|
||||
{
|
||||
FabricableItem targetItem = itemList.SelectedData as FabricableItem;
|
||||
if (targetItem != null)
|
||||
{
|
||||
activateButton.Enabled = CanBeFabricated(targetItem, character);
|
||||
}
|
||||
|
||||
if (character != null)
|
||||
{
|
||||
bool itemsChanged = false;
|
||||
if (prevContainedItems == null)
|
||||
{
|
||||
itemsChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var itemContainer = item.GetComponent<ItemContainer>();
|
||||
for (int i = 0; i < itemContainer.Inventory.Items.Length; i++)
|
||||
{
|
||||
if (prevContainedItems[i] != itemContainer.Inventory.Items[i])
|
||||
{
|
||||
itemsChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (itemsChanged) CheckFabricableItems(character);
|
||||
}
|
||||
|
||||
|
||||
GuiFrame.Update((float)Timing.Step);
|
||||
}
|
||||
|
||||
public void ClientWrite(NetBuffer msg, object[] extraData = null)
|
||||
{
|
||||
int itemIndex = fabricatedItem == null ? -1 : fabricableItems.IndexOf(fabricatedItem);
|
||||
msg.WriteRangedInteger(-1, fabricableItems.Count - 1, itemIndex);
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
|
||||
{
|
||||
int itemIndex = msg.ReadRangedInteger(-1, fabricableItems.Count - 1);
|
||||
|
||||
if (itemIndex == -1)
|
||||
{
|
||||
CancelFabricating();
|
||||
}
|
||||
else
|
||||
{
|
||||
//if already fabricating the selected item, return
|
||||
if (fabricatedItem != null && fabricableItems.IndexOf(fabricatedItem) == itemIndex) return;
|
||||
if (itemIndex < 0 || itemIndex >= fabricableItems.Count) return;
|
||||
|
||||
SelectItem(null, fabricableItems[itemIndex]);
|
||||
StartFabricating(fabricableItems[itemIndex]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class MiniMap : Powered
|
||||
{
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
if (item.Submarine == null) return;
|
||||
|
||||
int width = GuiFrame.Rect.Width, height = GuiFrame.Rect.Height;
|
||||
int x = GuiFrame.Rect.X;
|
||||
int y = GuiFrame.Rect.Y;
|
||||
|
||||
GuiFrame.Draw(spriteBatch);
|
||||
|
||||
if (!hasPower) return;
|
||||
|
||||
Rectangle miniMap = new Rectangle(x + 20, y + 40, width - 40, height - 60);
|
||||
|
||||
float size = Math.Min((float)miniMap.Width / (float)item.Submarine.Borders.Width, (float)miniMap.Height / (float)item.Submarine.Borders.Height);
|
||||
foreach (Hull hull in Hull.hullList)
|
||||
{
|
||||
Point topLeft = new Point(
|
||||
miniMap.X + (int)((hull.Rect.X - item.Submarine.HiddenSubPosition.X - item.Submarine.Borders.X) * size),
|
||||
miniMap.Y - (int)((hull.Rect.Y - item.Submarine.HiddenSubPosition.Y - item.Submarine.Borders.Y) * size));
|
||||
|
||||
Point bottomRight = new Point(
|
||||
topLeft.X + (int)(hull.Rect.Width * size),
|
||||
topLeft.Y + (int)(hull.Rect.Height * size));
|
||||
|
||||
topLeft.X = (int)MathUtils.RoundTowardsClosest(topLeft.X, 4);
|
||||
topLeft.Y = (int)MathUtils.RoundTowardsClosest(topLeft.Y, 4);
|
||||
bottomRight.X = (int)MathUtils.RoundTowardsClosest(bottomRight.X, 4);
|
||||
bottomRight.Y = (int)MathUtils.RoundTowardsClosest(bottomRight.Y, 4);
|
||||
|
||||
Rectangle hullRect = new Rectangle(
|
||||
topLeft, bottomRight - topLeft);
|
||||
|
||||
HullData hullData;
|
||||
hullDatas.TryGetValue(hull, out hullData);
|
||||
|
||||
Color borderColor = Color.Green;
|
||||
|
||||
|
||||
//hull integrity -----------------------------------
|
||||
|
||||
float? gapOpenSum = 0.0f;
|
||||
if (ShowHullIntegrity)
|
||||
{
|
||||
gapOpenSum = hull.ConnectedGaps.Where(g => !g.IsRoomToRoom).Sum(g => g.Open);
|
||||
borderColor = Color.Lerp(borderColor, Color.Red, Math.Min((float)gapOpenSum, 1.0f));
|
||||
}
|
||||
|
||||
//oxygen -----------------------------------
|
||||
|
||||
float? oxygenAmount = null;
|
||||
if (RequireOxygenDetectors && (hullData == null || hullData.Oxygen == null))
|
||||
{
|
||||
borderColor *= 0.5f;
|
||||
}
|
||||
else
|
||||
{
|
||||
oxygenAmount = hullData != null && hullData.Oxygen != null ? (float)hullData.Oxygen : hull.OxygenPercentage;
|
||||
GUI.DrawRectangle(spriteBatch, hullRect, Color.Lerp(Color.Red * 0.5f, Color.Green * 0.3f, (float)oxygenAmount / 100.0f), true);
|
||||
}
|
||||
|
||||
//water -----------------------------------
|
||||
|
||||
float? waterAmount = null;
|
||||
if (RequireWaterDetectors && (hullData == null || hullData.Water == null))
|
||||
{
|
||||
borderColor *= 0.5f;
|
||||
}
|
||||
else
|
||||
{
|
||||
waterAmount = hullData != null && hullData.Water != null ?
|
||||
(float)hullData.Water :
|
||||
Math.Min(hull.Volume / hull.FullVolume, 1.0f);
|
||||
|
||||
if (hullRect.Height * waterAmount > 3.0f)
|
||||
{
|
||||
Rectangle waterRect = new Rectangle(
|
||||
hullRect.X,
|
||||
(int)(hullRect.Y + hullRect.Height * (1.0f - waterAmount)),
|
||||
hullRect.Width,
|
||||
(int)(hullRect.Height * waterAmount));
|
||||
|
||||
waterRect.Inflate(-3, -3);
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, waterRect, Color.DarkBlue, true);
|
||||
GUI.DrawLine(spriteBatch, new Vector2(waterRect.X, waterRect.Y), new Vector2(waterRect.Right, waterRect.Y), Color.LightBlue);
|
||||
}
|
||||
}
|
||||
|
||||
if (hullRect.Contains(PlayerInput.MousePosition))
|
||||
{
|
||||
borderColor = Color.White;
|
||||
|
||||
if (gapOpenSum > 0.1f)
|
||||
{
|
||||
GUI.DrawString(spriteBatch,
|
||||
new Vector2(x + 10, y + height - 60),
|
||||
"Hull breach", Color.Red, Color.Black * 0.5f, 2, GUI.SmallFont);
|
||||
}
|
||||
|
||||
GUI.DrawString(spriteBatch,
|
||||
new Vector2(x + 10, y + height - 60),
|
||||
oxygenAmount == null ? "Air quality data not available" : "Air quality: " + (int)oxygenAmount + " %",
|
||||
oxygenAmount == null ? Color.Red : Color.Lerp(Color.Red, Color.LightGreen, (float)oxygenAmount / 100.0f),
|
||||
Color.Black * 0.5f, 2, GUI.SmallFont);
|
||||
|
||||
GUI.DrawString(spriteBatch,
|
||||
new Vector2(x + 10, y + height - 40),
|
||||
waterAmount == null ? "Water level data not available" : "Water level: " + (int)(waterAmount * 100.0f) + " %",
|
||||
waterAmount == null ? Color.Red : Color.Lerp(Color.LightGreen, Color.Red, (float)waterAmount),
|
||||
Color.Black * 0.5f, 2, GUI.SmallFont);
|
||||
}
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, hullRect, borderColor, false, 0.0f, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class Pump : Powered, IServerSerializable, IClientSerializable
|
||||
{
|
||||
private GUITickBox isActiveTickBox;
|
||||
|
||||
private void InitProjSpecific()
|
||||
{
|
||||
isActiveTickBox = new GUITickBox(new Rectangle(0, 0, 20, 20), "Running", Alignment.TopLeft, GuiFrame);
|
||||
isActiveTickBox.OnSelected = (GUITickBox box) =>
|
||||
{
|
||||
targetLevel = null;
|
||||
IsActive = !IsActive;
|
||||
if (!IsActive) currPowerConsumption = 0.0f;
|
||||
|
||||
if (GameMain.Server != null)
|
||||
{
|
||||
item.CreateServerEvent(this);
|
||||
GameServer.Log(Character.Controlled + (IsActive ? " turned on " : " turned off ") + item.Name, ServerLog.MessageType.ItemInteraction);
|
||||
}
|
||||
else if (GameMain.Client != null)
|
||||
{
|
||||
correctionTimer = CorrectionDelay;
|
||||
item.CreateClientEvent(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
var button = new GUIButton(new Rectangle(160, 40, 35, 30), "OUT", "", GuiFrame);
|
||||
button.OnClicked = (GUIButton btn, object obj) =>
|
||||
{
|
||||
FlowPercentage -= 10.0f;
|
||||
|
||||
if (GameMain.Server != null)
|
||||
{
|
||||
item.CreateServerEvent(this);
|
||||
GameServer.Log(Character.Controlled + " set the pumping speed of " + item.Name + " to " + (int)(flowPercentage) + " %", ServerLog.MessageType.ItemInteraction);
|
||||
}
|
||||
else if (GameMain.Client != null)
|
||||
{
|
||||
correctionTimer = CorrectionDelay;
|
||||
item.CreateClientEvent(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
button = new GUIButton(new Rectangle(210, 40, 35, 30), "IN", "", GuiFrame);
|
||||
button.OnClicked = (GUIButton btn, object obj) =>
|
||||
{
|
||||
FlowPercentage += 10.0f;
|
||||
|
||||
if (GameMain.Server != null)
|
||||
{
|
||||
item.CreateServerEvent(this);
|
||||
GameServer.Log(Character.Controlled + " set the pumping speed of " + item.Name + " to " + (int)(flowPercentage) + " %", ServerLog.MessageType.ItemInteraction);
|
||||
}
|
||||
else if (GameMain.Client != null)
|
||||
{
|
||||
correctionTimer = CorrectionDelay;
|
||||
item.CreateClientEvent(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
int x = GuiFrame.Rect.X;
|
||||
int y = GuiFrame.Rect.Y;
|
||||
|
||||
GuiFrame.Draw(spriteBatch);
|
||||
|
||||
GUI.Font.DrawString(spriteBatch, "Pumping speed: " + (int)flowPercentage + " %", new Vector2(x + 40, y + 85), Color.White);
|
||||
|
||||
}
|
||||
|
||||
public override void AddToGUIUpdateList()
|
||||
{
|
||||
GuiFrame.AddToGUIUpdateList();
|
||||
}
|
||||
|
||||
public override void UpdateHUD(Character character)
|
||||
{
|
||||
GuiFrame.Update(1.0f / 60.0f);
|
||||
}
|
||||
|
||||
public void ClientWrite(Lidgren.Network.NetBuffer msg, object[] extraData = null)
|
||||
{
|
||||
//flowpercentage can only be adjusted at 10% intervals -> no need for more accuracy than this
|
||||
msg.WriteRangedInteger(-10, 10, (int)(flowPercentage / 10.0f));
|
||||
msg.Write(IsActive);
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, Lidgren.Network.NetBuffer msg, float sendingTime)
|
||||
{
|
||||
if (correctionTimer > 0.0f)
|
||||
{
|
||||
StartDelayedCorrection(type, msg.ExtractBits(5 + 1), sendingTime);
|
||||
return;
|
||||
}
|
||||
|
||||
FlowPercentage = msg.ReadRangedInteger(-10, 10) * 10.0f;
|
||||
IsActive = msg.ReadBoolean();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,443 @@
|
||||
using Barotrauma.Networking;
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using Voronoi2;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class Radar : Powered, IServerSerializable, IClientSerializable
|
||||
{
|
||||
private GUITickBox isActiveTickBox;
|
||||
|
||||
private List<RadarBlip> radarBlips;
|
||||
|
||||
public override void AddToGUIUpdateList()
|
||||
{
|
||||
GuiFrame.AddToGUIUpdateList();
|
||||
}
|
||||
|
||||
public override void UpdateHUD(Character character)
|
||||
{
|
||||
GuiFrame.Update((float)Timing.Step);
|
||||
|
||||
for (int i = radarBlips.Count - 1; i >= 0; i--)
|
||||
{
|
||||
radarBlips[i].FadeTimer -= (float)Timing.Step * 0.5f;
|
||||
if (radarBlips[i].FadeTimer <= 0.0f) radarBlips.RemoveAt(i);
|
||||
}
|
||||
|
||||
if (IsActive)
|
||||
{
|
||||
float pingRadius = displayRadius * pingState;
|
||||
Ping(item.WorldPosition, pingRadius, prevPingRadius, displayScale, range, 2.0f);
|
||||
prevPingRadius = pingRadius;
|
||||
}
|
||||
|
||||
float passivePingRadius = (float)Math.Sin(Timing.TotalTime * 10);
|
||||
if (passivePingRadius > 0.0f)
|
||||
{
|
||||
foreach (AITarget t in AITarget.List)
|
||||
{
|
||||
if (t.SoundRange <= 0.0f) continue;
|
||||
|
||||
if (Vector2.Distance(t.WorldPosition, item.WorldPosition) < t.SoundRange)
|
||||
{
|
||||
Ping(t.WorldPosition, t.SoundRange * passivePingRadius * 0.2f, t.SoundRange * prevPassivePingRadius * 0.2f, displayScale, t.SoundRange, 0.5f);
|
||||
|
||||
radarBlips.Add(new RadarBlip(t.WorldPosition, 1.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
prevPassivePingRadius = passivePingRadius;
|
||||
|
||||
}
|
||||
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
GuiFrame.Draw(spriteBatch);
|
||||
|
||||
int radius = GuiFrame.Rect.Height / 2 - 10;
|
||||
DrawRadar(spriteBatch, new Rectangle((int)GuiFrame.Center.X - radius, (int)GuiFrame.Center.Y - radius, radius * 2, radius * 2));
|
||||
}
|
||||
|
||||
private void DrawRadar(SpriteBatch spriteBatch, Rectangle rect)
|
||||
{
|
||||
center = new Vector2(rect.X + rect.Width * 0.5f, rect.Center.Y);
|
||||
displayRadius = (rect.Width / 2.0f) * (1.0f - displayBorderSize);
|
||||
displayScale = displayRadius / range;
|
||||
|
||||
if (IsActive)
|
||||
{
|
||||
pingCircle.Draw(spriteBatch, center, Color.White * (1.0f - pingState), 0.0f, (displayRadius * 2 / pingCircle.size.X) * pingState);
|
||||
}
|
||||
|
||||
if (item.Submarine != null && !DetectSubmarineWalls)
|
||||
{
|
||||
float simScale = displayScale * Physics.DisplayToSimRation;
|
||||
|
||||
foreach (Submarine submarine in Submarine.Loaded)
|
||||
{
|
||||
if (submarine != item.Submarine && !submarine.DockedTo.Contains(item.Submarine)) continue;
|
||||
|
||||
Vector2 offset = ConvertUnits.ToSimUnits(submarine.WorldPosition - item.WorldPosition);
|
||||
|
||||
for (int i = 0; i < submarine.HullVertices.Count; i++)
|
||||
{
|
||||
Vector2 start = (submarine.HullVertices[i] + offset) * simScale;
|
||||
start.Y = -start.Y;
|
||||
Vector2 end = (submarine.HullVertices[(i + 1) % submarine.HullVertices.Count] + offset) * simScale;
|
||||
end.Y = -end.Y;
|
||||
|
||||
GUI.DrawLine(spriteBatch, center + start, center + end, Color.LightBlue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (radarBlips.Count > 0)
|
||||
{
|
||||
spriteBatch.End();
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive);
|
||||
|
||||
foreach (RadarBlip radarBlip in radarBlips)
|
||||
{
|
||||
DrawBlip(spriteBatch, radarBlip, center, radarBlip.FadeTimer / 2.0f);
|
||||
}
|
||||
|
||||
spriteBatch.End();
|
||||
spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, GameMain.ScissorTestEnable);
|
||||
}
|
||||
|
||||
if (GameMain.DebugDraw)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, rect.Location.ToVector2(), radarBlips.Count.ToString(), Color.White);
|
||||
}
|
||||
|
||||
if (screenOverlay != null)
|
||||
{
|
||||
screenOverlay.Draw(spriteBatch, center, 0.0f, rect.Width / screenOverlay.size.X);
|
||||
}
|
||||
|
||||
if (GameMain.GameSession == null) return;
|
||||
|
||||
DrawMarker(spriteBatch,
|
||||
GameMain.GameSession.StartLocation.Name,
|
||||
(Level.Loaded.StartPosition - item.WorldPosition), displayScale, center, (rect.Width * 0.5f));
|
||||
|
||||
DrawMarker(spriteBatch,
|
||||
GameMain.GameSession.EndLocation.Name,
|
||||
(Level.Loaded.EndPosition - item.WorldPosition), displayScale, center, (rect.Width * 0.5f));
|
||||
|
||||
if (GameMain.GameSession.Mission != null)
|
||||
{
|
||||
var mission = GameMain.GameSession.Mission;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(mission.RadarLabel) && mission.RadarPosition != Vector2.Zero)
|
||||
{
|
||||
DrawMarker(spriteBatch,
|
||||
mission.RadarLabel,
|
||||
mission.RadarPosition - item.WorldPosition, displayScale, center, (rect.Width * 0.55f));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Submarine sub in Submarine.Loaded)
|
||||
{
|
||||
if (!sub.OnRadar) continue;
|
||||
if (item.Submarine == sub || sub.DockedTo.Contains(item.Submarine)) continue;
|
||||
if (sub.WorldPosition.Y > Level.Loaded.Size.Y) continue;
|
||||
|
||||
DrawMarker(spriteBatch, sub.Name, sub.WorldPosition - item.WorldPosition, displayScale, center, (rect.Width * 0.45f));
|
||||
}
|
||||
|
||||
if (!GameMain.DebugDraw) return;
|
||||
|
||||
var steering = item.GetComponent<Steering>();
|
||||
if (steering == null || steering.SteeringPath == null) return;
|
||||
|
||||
Vector2 prevPos = Vector2.Zero;
|
||||
|
||||
foreach (WayPoint wp in steering.SteeringPath.Nodes)
|
||||
{
|
||||
Vector2 pos = (wp.Position - item.WorldPosition) * displayScale;
|
||||
if (pos.Length() > displayRadius) continue;
|
||||
|
||||
pos.Y = -pos.Y;
|
||||
pos += center;
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X - 3 / 2, (int)pos.Y - 3, 6, 6), (steering.SteeringPath.CurrentNode == wp) ? Color.LightGreen : Color.Green, false);
|
||||
|
||||
if (prevPos != Vector2.Zero)
|
||||
{
|
||||
GUI.DrawLine(spriteBatch, pos, prevPos, Color.Green);
|
||||
}
|
||||
|
||||
prevPos = pos;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void Ping(Vector2 pingSource, float pingRadius, float prevPingRadius, float displayScale, float range, float pingStrength = 1.0f)
|
||||
{
|
||||
foreach (Submarine submarine in Submarine.Loaded)
|
||||
{
|
||||
if (item.Submarine == submarine && !DetectSubmarineWalls) continue;
|
||||
if (item.Submarine != null && item.Submarine.DockedTo.Contains(submarine)) continue;
|
||||
if (submarine.HullVertices == null) continue;
|
||||
|
||||
for (int i = 0; i < submarine.HullVertices.Count; i++)
|
||||
{
|
||||
Vector2 start = ConvertUnits.ToDisplayUnits(submarine.HullVertices[i]);
|
||||
Vector2 end = ConvertUnits.ToDisplayUnits(submarine.HullVertices[(i + 1) % submarine.HullVertices.Count]);
|
||||
|
||||
if (item.Submarine == submarine)
|
||||
{
|
||||
start += Rand.Vector(500.0f);
|
||||
end += Rand.Vector(500.0f);
|
||||
}
|
||||
|
||||
CreateBlipsForLine(
|
||||
start + submarine.WorldPosition,
|
||||
end + submarine.WorldPosition,
|
||||
pingRadius, prevPingRadius,
|
||||
200.0f, 2.0f, range, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (Level.Loaded != null && (item.CurrentHull == null || !DetectSubmarineWalls))
|
||||
{
|
||||
if (Level.Loaded.Size.Y - pingSource.Y < range)
|
||||
{
|
||||
CreateBlipsForLine(
|
||||
new Vector2(pingSource.X - range, Level.Loaded.Size.Y),
|
||||
new Vector2(pingSource.X + range, Level.Loaded.Size.Y),
|
||||
pingRadius, prevPingRadius,
|
||||
250.0f, 150.0f, range, pingStrength);
|
||||
}
|
||||
|
||||
List<VoronoiCell> cells = Level.Loaded.GetCells(pingSource, 7);
|
||||
foreach (VoronoiCell cell in cells)
|
||||
{
|
||||
foreach (GraphEdge edge in cell.edges)
|
||||
{
|
||||
if (!edge.isSolid) continue;
|
||||
float cellDot = Vector2.Dot(cell.Center - pingSource, (edge.Center + cell.Translation) - cell.Center);
|
||||
if (cellDot > 0) continue;
|
||||
|
||||
float facingDot = Vector2.Dot(
|
||||
Vector2.Normalize(edge.point1 - edge.point2),
|
||||
Vector2.Normalize(cell.Center - pingSource));
|
||||
|
||||
CreateBlipsForLine(
|
||||
edge.point1 + cell.Translation,
|
||||
edge.point2 + cell.Translation,
|
||||
pingRadius, prevPingRadius,
|
||||
350.0f, 3.0f * (Math.Abs(facingDot) + 1.0f), range, pingStrength);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (RuinGeneration.Ruin ruin in Level.Loaded.Ruins)
|
||||
{
|
||||
if (!MathUtils.CircleIntersectsRectangle(pingSource, range, ruin.Area)) continue;
|
||||
|
||||
foreach (var ruinShape in ruin.RuinShapes)
|
||||
{
|
||||
foreach (RuinGeneration.Line wall in ruinShape.Walls)
|
||||
{
|
||||
float cellDot = Vector2.Dot(
|
||||
Vector2.Normalize(ruinShape.Center - pingSource),
|
||||
Vector2.Normalize((wall.A + wall.B) / 2.0f - ruinShape.Center));
|
||||
if (cellDot > 0) continue;
|
||||
|
||||
CreateBlipsForLine(
|
||||
wall.A, wall.B,
|
||||
pingRadius, prevPingRadius,
|
||||
100.0f, 1000.0f, range, pingStrength);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Character c in Character.CharacterList)
|
||||
{
|
||||
if (c.AnimController.CurrentHull != null || !c.Enabled) continue;
|
||||
if (DetectSubmarineWalls && c.AnimController.CurrentHull == null && item.CurrentHull != null) continue;
|
||||
|
||||
foreach (Limb limb in c.AnimController.Limbs)
|
||||
{
|
||||
float pointDist = (limb.WorldPosition - pingSource).Length() * displayScale;
|
||||
|
||||
if (limb.SimPosition == Vector2.Zero || pointDist > displayRadius) continue;
|
||||
|
||||
if (pointDist > prevPingRadius && pointDist < pingRadius)
|
||||
{
|
||||
for (int i = 0; i <= limb.Mass / 100.0f; i++)
|
||||
{
|
||||
var blip = new RadarBlip(limb.WorldPosition + Rand.Vector(limb.Mass / 10.0f), MathHelper.Clamp(limb.Mass, 0.1f, pingStrength));
|
||||
radarBlips.Add(blip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateBlipsForLine(Vector2 point1, Vector2 point2, float pingRadius, float prevPingRadius,
|
||||
float lineStep, float zStep, float range, float pingStrength)
|
||||
{
|
||||
float length = (point1 - point2).Length();
|
||||
|
||||
Vector2 lineDir = (point2 - point1) / length;
|
||||
|
||||
range *= displayScale;
|
||||
|
||||
for (float x = 0; x < length; x += lineStep * Rand.Range(0.8f, 1.2f))
|
||||
{
|
||||
Vector2 point = point1 + lineDir * x;
|
||||
//point += cell.Translation;
|
||||
|
||||
float pointDist = Vector2.Distance(item.WorldPosition, point) * displayScale;
|
||||
|
||||
if (pointDist > displayRadius) continue;
|
||||
if (pointDist < prevPingRadius || pointDist > pingRadius) continue;
|
||||
|
||||
float alpha = pingStrength * Rand.Range(1.5f, 2.0f);
|
||||
for (float z = 0; z < displayRadius - pointDist * displayScale; z += zStep)
|
||||
{
|
||||
Vector2 pos = point + Rand.Vector(150.0f) + Vector2.Normalize(point - item.WorldPosition) * z / displayScale;
|
||||
float fadeTimer = alpha * (1.0f - pointDist / range);
|
||||
|
||||
int minDist = 200;
|
||||
radarBlips.RemoveAll(b => b.FadeTimer < fadeTimer && Math.Abs(pos.X - b.Position.X) < minDist && Math.Abs(pos.Y - b.Position.Y) < minDist);
|
||||
|
||||
var blip = new RadarBlip(pos, fadeTimer);
|
||||
|
||||
radarBlips.Add(blip);
|
||||
zStep += 0.5f;
|
||||
|
||||
if (z == 0)
|
||||
{
|
||||
alpha = Math.Min(alpha - 0.5f, 1.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
alpha -= 0.1f;
|
||||
}
|
||||
|
||||
if (alpha < 0) break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawBlip(SpriteBatch spriteBatch, RadarBlip blip, Vector2 center, float strength)
|
||||
{
|
||||
strength = MathHelper.Clamp(strength, 0.0f, 1.0f);
|
||||
|
||||
Color[] colors = new Color[] {
|
||||
Color.TransparentBlack,
|
||||
new Color(0, 50, 160),
|
||||
new Color(0, 133, 166),
|
||||
new Color(2, 159, 30),
|
||||
new Color(255, 255, 255) };
|
||||
|
||||
float scaledT = strength * (colors.Length - 1);
|
||||
Color color = Color.Lerp(colors[(int)scaledT], colors[(int)Math.Min(scaledT + 1, colors.Length - 1)], (scaledT - (int)scaledT));
|
||||
|
||||
Vector2 pos = (blip.Position - item.WorldPosition) * displayScale;
|
||||
pos.Y = -pos.Y;
|
||||
|
||||
if (pos.Length() > displayRadius)
|
||||
{
|
||||
blip.FadeTimer = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
float posDist = pos.Length();
|
||||
Vector2 dir = pos / posDist;
|
||||
float distFactor = (posDist / displayRadius);
|
||||
|
||||
Vector2 normal = new Vector2(dir.Y, -dir.X);
|
||||
|
||||
float scale = (strength + 3.0f) * Math.Max(distFactor * 3.0f, 1.0f);
|
||||
|
||||
if (radarBlip == null)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, center + pos, Vector2.One * 4, Color.Magenta, true);
|
||||
return;
|
||||
}
|
||||
|
||||
radarBlip.Draw(spriteBatch, center + pos, color, radarBlip.Origin, MathUtils.VectorToAngle(pos),
|
||||
new Vector2(scale * 0.3f, scale) * 0.04f, SpriteEffects.None, 0);
|
||||
|
||||
pos += Rand.Range(0.0f, 1.0f) * dir + Rand.Range(-scale, scale) * normal;
|
||||
|
||||
radarBlip.Draw(spriteBatch, center + pos, color * 0.5f, radarBlip.Origin, MathUtils.VectorToAngle(pos),
|
||||
new Vector2(scale * 0.3f, scale) * 0.08f, SpriteEffects.None, 0);
|
||||
}
|
||||
|
||||
private void DrawMarker(SpriteBatch spriteBatch, string label, Vector2 position, float scale, Vector2 center, float radius)
|
||||
{
|
||||
//position += Level.Loaded.Position;
|
||||
|
||||
float dist = position.Length();
|
||||
|
||||
position *= scale;
|
||||
position.Y = -position.Y;
|
||||
|
||||
float textAlpha = MathHelper.Clamp(1.5f - dist / 50000.0f, 0.5f, 1.0f);
|
||||
|
||||
Vector2 dir = Vector2.Normalize(position);
|
||||
|
||||
Vector2 markerPos = (dist * scale > radius) ? dir * radius : position;
|
||||
markerPos += center;
|
||||
|
||||
markerPos.X = (int)markerPos.X;
|
||||
markerPos.Y = (int)markerPos.Y;
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)markerPos.X, (int)markerPos.Y, 5, 5), Color.LightBlue);
|
||||
|
||||
if (dir.X < 0.0f) markerPos.X -= GUI.SmallFont.MeasureString(label).X + 10;
|
||||
|
||||
string wrappedLabel = ToolBox.WrapText(label, 150, GUI.SmallFont);
|
||||
|
||||
wrappedLabel += "\n" + ((int)(dist * Physics.DisplayToRealWorldRatio) + " m");
|
||||
|
||||
GUI.DrawString(spriteBatch,
|
||||
new Vector2(markerPos.X + 10, markerPos.Y),
|
||||
wrappedLabel,
|
||||
Color.LightBlue * textAlpha, Color.Black * textAlpha * 0.5f,
|
||||
2, GUI.SmallFont);
|
||||
}
|
||||
|
||||
public void ClientWrite(Lidgren.Network.NetBuffer msg, object[] extraData = null)
|
||||
{
|
||||
msg.Write(IsActive);
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, Lidgren.Network.NetBuffer msg, float sendingTime)
|
||||
{
|
||||
if (correctionTimer > 0.0f)
|
||||
{
|
||||
StartDelayedCorrection(type, msg.ExtractBits(1), sendingTime);
|
||||
return;
|
||||
}
|
||||
|
||||
IsActive = msg.ReadBoolean();
|
||||
isActiveTickBox.Selected = IsActive;
|
||||
}
|
||||
}
|
||||
|
||||
class RadarBlip
|
||||
{
|
||||
public float FadeTimer;
|
||||
public Vector2 Position;
|
||||
|
||||
public RadarBlip(Vector2 pos, float fadeTimer)
|
||||
{
|
||||
Position = pos;
|
||||
FadeTimer = Math.Max(fadeTimer, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using Lidgren.Network;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Barotrauma.Networking;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class Reactor : Powered, IDrawableComponent, IServerSerializable, IClientSerializable
|
||||
{
|
||||
private GUITickBox autoTempTickBox;
|
||||
|
||||
private void InitProjSpecific()
|
||||
{
|
||||
var button = new GUIButton(new Rectangle(410, 70, 40, 40), "-", "", GuiFrame);
|
||||
button.OnPressed = () =>
|
||||
{
|
||||
lastUser = Character.Controlled;
|
||||
if (nextServerLogWriteTime == null)
|
||||
{
|
||||
nextServerLogWriteTime = Math.Max(lastServerLogWriteTime + 1.0f, (float)Timing.TotalTime);
|
||||
}
|
||||
unsentChanges = true;
|
||||
ShutDownTemp -= 100.0f;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
button = new GUIButton(new Rectangle(460, 70, 40, 40), "+", "", GuiFrame);
|
||||
button.OnPressed = () =>
|
||||
{
|
||||
lastUser = Character.Controlled;
|
||||
if (nextServerLogWriteTime == null)
|
||||
{
|
||||
nextServerLogWriteTime = Math.Max(lastServerLogWriteTime + 1.0f, (float)Timing.TotalTime);
|
||||
}
|
||||
unsentChanges = true;
|
||||
ShutDownTemp += 100.0f;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
autoTempTickBox = new GUITickBox(new Rectangle(410, 170, 20, 20), "Automatic temperature control", Alignment.TopLeft, GuiFrame);
|
||||
autoTempTickBox.OnSelected = ToggleAutoTemp;
|
||||
|
||||
button = new GUIButton(new Rectangle(210, 290, 40, 40), "+", "", GuiFrame);
|
||||
button.OnPressed = () =>
|
||||
{
|
||||
lastUser = Character.Controlled;
|
||||
if (nextServerLogWriteTime == null)
|
||||
{
|
||||
nextServerLogWriteTime = Math.Max(lastServerLogWriteTime + 1.0f, (float)Timing.TotalTime);
|
||||
}
|
||||
unsentChanges = true;
|
||||
FissionRate += 1.0f;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
button = new GUIButton(new Rectangle(210, 340, 40, 40), "-", "", GuiFrame);
|
||||
button.OnPressed = () =>
|
||||
{
|
||||
lastUser = Character.Controlled;
|
||||
if (nextServerLogWriteTime == null)
|
||||
{
|
||||
nextServerLogWriteTime = Math.Max(lastServerLogWriteTime + 1.0f, (float)Timing.TotalTime);
|
||||
}
|
||||
unsentChanges = true;
|
||||
FissionRate -= 1.0f;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
button = new GUIButton(new Rectangle(500, 290, 40, 40), "+", "", GuiFrame);
|
||||
button.OnPressed = () =>
|
||||
{
|
||||
lastUser = Character.Controlled;
|
||||
if (nextServerLogWriteTime == null)
|
||||
{
|
||||
nextServerLogWriteTime = Math.Max(lastServerLogWriteTime + 1.0f, (float)Timing.TotalTime);
|
||||
}
|
||||
unsentChanges = true;
|
||||
CoolingRate += 1.0f;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
button = new GUIButton(new Rectangle(500, 340, 40, 40), "-", "", GuiFrame);
|
||||
button.OnPressed = () =>
|
||||
{
|
||||
lastUser = Character.Controlled;
|
||||
if (nextServerLogWriteTime == null)
|
||||
{
|
||||
nextServerLogWriteTime = Math.Max(lastServerLogWriteTime + 1.0f, (float)Timing.TotalTime);
|
||||
}
|
||||
unsentChanges = true;
|
||||
CoolingRate -= 1.0f;
|
||||
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
private void UpdateGraph(float deltaTime)
|
||||
{
|
||||
graphTimer += deltaTime * 1000.0f;
|
||||
|
||||
if (graphTimer > updateGraphInterval)
|
||||
{
|
||||
UpdateGraph(fissionRateGraph, fissionRate);
|
||||
UpdateGraph(coolingRateGraph, coolingRate);
|
||||
UpdateGraph(tempGraph, temperature);
|
||||
|
||||
UpdateGraph(loadGraph, load);
|
||||
|
||||
graphTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing = false)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Vector2(item.Rect.X + item.Rect.Width / 2 - 6, -item.Rect.Y + 29),
|
||||
new Vector2(12, 42), Color.Black);
|
||||
|
||||
if (temperature > 0)
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Vector2(item.Rect.X + item.Rect.Width / 2 - 5, -item.Rect.Y + 30 + (40.0f * (1.0f - temperature / 10000.0f))),
|
||||
new Vector2(10, 40 * (temperature / 10000.0f)), new Color(temperature / 10000.0f, 1.0f - (temperature / 10000.0f), 0.0f, 1.0f), true);
|
||||
}
|
||||
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
IsActive = true;
|
||||
|
||||
int x = GuiFrame.Rect.X;
|
||||
int y = GuiFrame.Rect.Y;
|
||||
|
||||
GuiFrame.Draw(spriteBatch);
|
||||
|
||||
float xOffset = graphTimer / updateGraphInterval;
|
||||
|
||||
//GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black, true);
|
||||
|
||||
GUI.Font.DrawString(spriteBatch, "Output: " + (int)temperature + " kW",
|
||||
new Vector2(x + 450, y + 30), Color.Red);
|
||||
GUI.Font.DrawString(spriteBatch, "Grid load: " + (int)load + " kW",
|
||||
new Vector2(x + 600, y + 30), Color.Yellow);
|
||||
|
||||
float maxLoad = 0.0f;
|
||||
foreach (float loadVal in loadGraph)
|
||||
{
|
||||
maxLoad = Math.Max(maxLoad, loadVal);
|
||||
}
|
||||
|
||||
DrawGraph(tempGraph, spriteBatch,
|
||||
new Rectangle(x + 30, y + 30, 400, 250), Math.Max(10000.0f, maxLoad), xOffset, Color.Red);
|
||||
|
||||
DrawGraph(loadGraph, spriteBatch,
|
||||
new Rectangle(x + 30, y + 30, 400, 250), Math.Max(10000.0f, maxLoad), xOffset, Color.Yellow);
|
||||
|
||||
GUI.Font.DrawString(spriteBatch, "Shutdown Temperature: " + (int)shutDownTemp, new Vector2(x + 450, y + 80), Color.White);
|
||||
|
||||
//GUI.Font.DrawString(spriteBatch, "Automatic Temperature Control: " + ((autoTemp) ? "ON" : "OFF"), new Vector2(x + 450, y + 180), Color.White);
|
||||
|
||||
y += 300;
|
||||
|
||||
GUI.Font.DrawString(spriteBatch, "Fission rate: " + (int)fissionRate + " %", new Vector2(x + 30, y), Color.White);
|
||||
DrawGraph(fissionRateGraph, spriteBatch,
|
||||
new Rectangle(x + 30, y + 30, 200, 100), 100.0f, xOffset, Color.Orange);
|
||||
|
||||
|
||||
GUI.Font.DrawString(spriteBatch, "Cooling rate: " + (int)coolingRate + " %", new Vector2(x + 320, y), Color.White);
|
||||
DrawGraph(coolingRateGraph, spriteBatch,
|
||||
new Rectangle(x + 320, y + 30, 200, 100), 100.0f, xOffset, Color.LightBlue);
|
||||
|
||||
|
||||
//y = y - 260;
|
||||
}
|
||||
|
||||
public override void AddToGUIUpdateList()
|
||||
{
|
||||
GuiFrame.AddToGUIUpdateList();
|
||||
}
|
||||
|
||||
public override void UpdateHUD(Character character)
|
||||
{
|
||||
GuiFrame.Update(1.0f / 60.0f);
|
||||
}
|
||||
|
||||
private bool ToggleAutoTemp(GUITickBox tickBox)
|
||||
{
|
||||
unsentChanges = true;
|
||||
autoTemp = tickBox.Selected;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void UpdateGraph<T>(IList<T> graph, T newValue)
|
||||
{
|
||||
for (int i = graph.Count - 1; i > 0; i--)
|
||||
{
|
||||
graph[i] = graph[i - 1];
|
||||
}
|
||||
graph[0] = newValue;
|
||||
}
|
||||
|
||||
static void DrawGraph(IList<float> graph, SpriteBatch spriteBatch, Rectangle rect, float maxVal, float xOffset, Color color)
|
||||
{
|
||||
float lineWidth = (float)rect.Width / (float)(graph.Count - 2);
|
||||
float yScale = (float)rect.Height / maxVal;
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, rect, Color.White);
|
||||
|
||||
Vector2 prevPoint = new Vector2(rect.Right, rect.Bottom - (graph[1] + (graph[0] - graph[1]) * xOffset) * yScale);
|
||||
|
||||
float currX = rect.Right - ((xOffset - 1.0f) * lineWidth);
|
||||
|
||||
for (int i = 1; i < graph.Count - 1; i++)
|
||||
{
|
||||
currX -= lineWidth;
|
||||
|
||||
Vector2 newPoint = new Vector2(currX, rect.Bottom - graph[i] * yScale);
|
||||
|
||||
GUI.DrawLine(spriteBatch, prevPoint, newPoint - new Vector2(1.0f, 0), color);
|
||||
|
||||
prevPoint = newPoint;
|
||||
}
|
||||
|
||||
Vector2 lastPoint = new Vector2(rect.X,
|
||||
rect.Bottom - (graph[graph.Count - 1] + (graph[graph.Count - 2] - graph[graph.Count - 1]) * xOffset) * yScale);
|
||||
|
||||
GUI.DrawLine(spriteBatch, prevPoint, lastPoint, color);
|
||||
}
|
||||
|
||||
public void ClientWrite(NetBuffer msg, object[] extraData = null)
|
||||
{
|
||||
msg.Write(autoTemp);
|
||||
msg.WriteRangedSingle(shutDownTemp, 0.0f, 10000.0f, 15);
|
||||
|
||||
msg.WriteRangedSingle(coolingRate, 0.0f, 100.0f, 8);
|
||||
msg.WriteRangedSingle(fissionRate, 0.0f, 100.0f, 8);
|
||||
|
||||
correctionTimer = CorrectionDelay;
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
|
||||
{
|
||||
if (correctionTimer > 0.0f)
|
||||
{
|
||||
StartDelayedCorrection(type, msg.ExtractBits(16 + 1 + 15 + 8 + 8), sendingTime);
|
||||
return;
|
||||
}
|
||||
|
||||
Temperature = msg.ReadRangedSingle(0.0f, 10000.0f, 16);
|
||||
|
||||
AutoTemp = msg.ReadBoolean();
|
||||
ShutDownTemp = msg.ReadRangedSingle(0.0f, 10000.0f, 15);
|
||||
|
||||
CoolingRate = msg.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||
FissionRate = msg.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
using Barotrauma.Networking;
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
using Voronoi2;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class Steering : Powered, IServerSerializable, IClientSerializable
|
||||
{
|
||||
private GUITickBox autopilotTickBox, maintainPosTickBox;
|
||||
private GUITickBox levelEndTickBox, levelStartTickBox;
|
||||
|
||||
public bool LevelStartSelected
|
||||
{
|
||||
get { return levelStartTickBox.Selected; }
|
||||
set { levelStartTickBox.Selected = value; }
|
||||
}
|
||||
|
||||
public bool LevelEndSelected
|
||||
{
|
||||
get { return levelEndTickBox.Selected; }
|
||||
set { levelEndTickBox.Selected = value; }
|
||||
}
|
||||
|
||||
public bool MaintainPos
|
||||
{
|
||||
get { return maintainPosTickBox.Selected; }
|
||||
set { maintainPosTickBox.Selected = value; }
|
||||
}
|
||||
|
||||
private void InitProjSpecific()
|
||||
{
|
||||
autopilotTickBox = new GUITickBox(new Rectangle(0, 25, 20, 20), "Autopilot", Alignment.TopLeft, GuiFrame);
|
||||
autopilotTickBox.OnSelected = (GUITickBox box) =>
|
||||
{
|
||||
AutoPilot = box.Selected;
|
||||
unsentChanges = true;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
maintainPosTickBox = new GUITickBox(new Rectangle(5, 50, 15, 15), "Maintain position", Alignment.TopLeft, GUI.SmallFont, GuiFrame);
|
||||
maintainPosTickBox.Enabled = false;
|
||||
maintainPosTickBox.OnSelected = ToggleMaintainPosition;
|
||||
|
||||
levelStartTickBox = new GUITickBox(
|
||||
new Rectangle(5, 70, 15, 15),
|
||||
GameMain.GameSession == null ? "" : ToolBox.LimitString(GameMain.GameSession.StartLocation.Name, 20),
|
||||
Alignment.TopLeft, GUI.SmallFont, GuiFrame);
|
||||
levelStartTickBox.Enabled = false;
|
||||
levelStartTickBox.OnSelected = SelectDestination;
|
||||
|
||||
levelEndTickBox = new GUITickBox(
|
||||
new Rectangle(5, 90, 15, 15),
|
||||
GameMain.GameSession == null ? "" : ToolBox.LimitString(GameMain.GameSession.EndLocation.Name, 20),
|
||||
Alignment.TopLeft, GUI.SmallFont, GuiFrame);
|
||||
levelEndTickBox.Enabled = false;
|
||||
levelEndTickBox.OnSelected = SelectDestination;
|
||||
}
|
||||
|
||||
private bool ToggleMaintainPosition(GUITickBox tickBox)
|
||||
{
|
||||
unsentChanges = true;
|
||||
|
||||
levelStartTickBox.Selected = false;
|
||||
levelEndTickBox.Selected = false;
|
||||
|
||||
if (item.Submarine == null)
|
||||
{
|
||||
posToMaintain = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
posToMaintain = item.Submarine.WorldPosition;
|
||||
}
|
||||
|
||||
tickBox.Selected = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
//if (voltage < minVoltage) return;
|
||||
|
||||
int width = GuiFrame.Rect.Width, height = GuiFrame.Rect.Height;
|
||||
int x = GuiFrame.Rect.X;
|
||||
int y = GuiFrame.Rect.Y;
|
||||
|
||||
GuiFrame.Draw(spriteBatch);
|
||||
|
||||
if (voltage < minVoltage && powerConsumption > 0.0f) return;
|
||||
|
||||
Rectangle velRect = new Rectangle(x + 20, y + 20, width - 40, height - 40);
|
||||
//GUI.DrawRectangle(spriteBatch, velRect, Color.White, false);
|
||||
|
||||
if (item.Submarine != null && Level.Loaded != null)
|
||||
{
|
||||
Vector2 realWorldVelocity = ConvertUnits.ToDisplayUnits(item.Submarine.Velocity * Physics.DisplayToRealWorldRatio) * 3.6f;
|
||||
float realWorldDepth = Math.Abs(item.Submarine.Position.Y - Level.Loaded.Size.Y) * Physics.DisplayToRealWorldRatio;
|
||||
GUI.DrawString(spriteBatch, new Vector2(x + 20, y + height - 65),
|
||||
"Velocity: " + (int)realWorldVelocity.X + " km/h", Color.LightGreen, null, 0, GUI.SmallFont);
|
||||
GUI.DrawString(spriteBatch, new Vector2(x + 20, y + height - 50),
|
||||
"Descent velocity: " + -(int)realWorldVelocity.Y + " km/h", Color.LightGreen, null, 0, GUI.SmallFont);
|
||||
|
||||
GUI.DrawString(spriteBatch, new Vector2(x + 20, y + height - 30),
|
||||
"Depth: " + (int)realWorldDepth + " m", Color.LightGreen, null, 0, GUI.SmallFont);
|
||||
}
|
||||
|
||||
GUI.DrawLine(spriteBatch,
|
||||
new Vector2(velRect.Center.X, velRect.Center.Y),
|
||||
new Vector2(velRect.Center.X + currVelocity.X, velRect.Center.Y - currVelocity.Y),
|
||||
Color.Gray);
|
||||
|
||||
Vector2 targetVelPos = new Vector2(velRect.Center.X + targetVelocity.X, velRect.Center.Y - targetVelocity.Y);
|
||||
|
||||
GUI.DrawLine(spriteBatch,
|
||||
new Vector2(velRect.Center.X, velRect.Center.Y),
|
||||
targetVelPos,
|
||||
Color.LightGray);
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)targetVelPos.X - 5, (int)targetVelPos.Y - 5, 10, 10), Color.White);
|
||||
|
||||
if (Vector2.Distance(PlayerInput.MousePosition, new Vector2(velRect.Center.X, velRect.Center.Y)) < 200.0f)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)targetVelPos.X - 10, (int)targetVelPos.Y - 10, 20, 20), Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
public override void AddToGUIUpdateList()
|
||||
{
|
||||
GuiFrame.AddToGUIUpdateList();
|
||||
}
|
||||
|
||||
public override void UpdateHUD(Character character)
|
||||
{
|
||||
GuiFrame.Update(1.0f / 60.0f);
|
||||
|
||||
if (Vector2.Distance(PlayerInput.MousePosition, new Vector2(GuiFrame.Rect.Center.X, GuiFrame.Rect.Center.Y)) < 200.0f)
|
||||
{
|
||||
if (PlayerInput.LeftButtonHeld())
|
||||
{
|
||||
TargetVelocity = PlayerInput.MousePosition - new Vector2(GuiFrame.Rect.Center.X, GuiFrame.Rect.Center.Y);
|
||||
targetVelocity.Y = -targetVelocity.Y;
|
||||
|
||||
unsentChanges = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetDestinationLevelStart()
|
||||
{
|
||||
AutoPilot = true;
|
||||
|
||||
MaintainPos = false;
|
||||
posToMaintain = null;
|
||||
|
||||
levelEndTickBox.Selected = false;
|
||||
|
||||
if (!levelStartTickBox.Selected)
|
||||
{
|
||||
levelStartTickBox.Selected = true;
|
||||
UpdatePath();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetDestinationLevelEnd()
|
||||
{
|
||||
AutoPilot = false;
|
||||
|
||||
MaintainPos = false;
|
||||
posToMaintain = null;
|
||||
|
||||
levelStartTickBox.Selected = false;
|
||||
|
||||
if (!levelEndTickBox.Selected)
|
||||
{
|
||||
levelEndTickBox.Selected = true;
|
||||
UpdatePath();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private bool SelectDestination(GUITickBox tickBox)
|
||||
{
|
||||
unsentChanges = true;
|
||||
|
||||
if (tickBox == levelStartTickBox)
|
||||
{
|
||||
levelEndTickBox.Selected = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
levelStartTickBox.Selected = false;
|
||||
}
|
||||
|
||||
maintainPosTickBox.Selected = false;
|
||||
posToMaintain = null;
|
||||
tickBox.Selected = true;
|
||||
|
||||
UpdatePath();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ClientWrite(Lidgren.Network.NetBuffer msg, object[] extraData = null)
|
||||
{
|
||||
msg.Write(autoPilot);
|
||||
|
||||
if (!autoPilot)
|
||||
{
|
||||
//no need to write steering info if autopilot is controlling
|
||||
msg.Write(targetVelocity.X);
|
||||
msg.Write(targetVelocity.Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.Write(posToMaintain != null);
|
||||
if (posToMaintain != null)
|
||||
{
|
||||
msg.Write(((Vector2)posToMaintain).X);
|
||||
msg.Write(((Vector2)posToMaintain).Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.Write(LevelStartSelected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, Lidgren.Network.NetBuffer msg, float sendingTime)
|
||||
{
|
||||
long msgStartPos = msg.Position;
|
||||
|
||||
bool autoPilot = msg.ReadBoolean();
|
||||
Vector2 newTargetVelocity = targetVelocity;
|
||||
bool maintainPos = false;
|
||||
Vector2? newPosToMaintain = null;
|
||||
bool headingToStart = false;
|
||||
|
||||
if (autoPilot)
|
||||
{
|
||||
maintainPos = msg.ReadBoolean();
|
||||
if (maintainPos)
|
||||
{
|
||||
newPosToMaintain = new Vector2(
|
||||
msg.ReadFloat(),
|
||||
msg.ReadFloat());
|
||||
}
|
||||
else
|
||||
{
|
||||
headingToStart = msg.ReadBoolean();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
newTargetVelocity = new Vector2(msg.ReadFloat(), msg.ReadFloat());
|
||||
}
|
||||
|
||||
if (correctionTimer > 0.0f)
|
||||
{
|
||||
int msgLength = (int)(msg.Position - msgStartPos);
|
||||
msg.Position = msgStartPos;
|
||||
StartDelayedCorrection(type, msg.ExtractBits(msgLength), sendingTime);
|
||||
return;
|
||||
}
|
||||
|
||||
AutoPilot = autoPilot;
|
||||
|
||||
if (!AutoPilot)
|
||||
{
|
||||
targetVelocity = newTargetVelocity;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
MaintainPos = newPosToMaintain != null;
|
||||
posToMaintain = newPosToMaintain;
|
||||
|
||||
if (posToMaintain == null)
|
||||
{
|
||||
LevelStartSelected = headingToStart;
|
||||
LevelEndSelected = !headingToStart;
|
||||
UpdatePath();
|
||||
}
|
||||
else
|
||||
{
|
||||
LevelStartSelected = false;
|
||||
LevelEndSelected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Barotrauma.Networking;
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class PowerContainer : Powered, IDrawableComponent, IServerSerializable, IClientSerializable
|
||||
{
|
||||
private void InitProjSpecific()
|
||||
{
|
||||
if (canBeSelected)
|
||||
{
|
||||
var button = new GUIButton(new Rectangle(160, 50, 30, 30), "-", "", GuiFrame);
|
||||
button.OnClicked = (GUIButton btn, object obj) =>
|
||||
{
|
||||
RechargeSpeed = rechargeSpeed - maxRechargeSpeed * 0.1f;
|
||||
|
||||
if (GameMain.Server != null)
|
||||
{
|
||||
item.CreateServerEvent(this);
|
||||
GameServer.Log(Character.Controlled + " set the recharge speed of " + item.Name + " to " + (int)((rechargeSpeed / maxRechargeSpeed) * 100.0f) + " %", ServerLog.MessageType.ItemInteraction);
|
||||
}
|
||||
else if (GameMain.Client != null)
|
||||
{
|
||||
item.CreateClientEvent(this);
|
||||
correctionTimer = CorrectionDelay;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
button = new GUIButton(new Rectangle(200, 50, 30, 30), "+", "", GuiFrame);
|
||||
button.OnClicked = (GUIButton btn, object obj) =>
|
||||
{
|
||||
RechargeSpeed = rechargeSpeed + maxRechargeSpeed * 0.1f;
|
||||
|
||||
if (GameMain.Server != null)
|
||||
{
|
||||
item.CreateServerEvent(this);
|
||||
GameServer.Log(Character.Controlled + " set the recharge speed of " + item.Name + " to " + (int)((rechargeSpeed / maxRechargeSpeed) * 100.0f) + " %", ServerLog.MessageType.ItemInteraction);
|
||||
}
|
||||
else if (GameMain.Client != null)
|
||||
{
|
||||
item.CreateClientEvent(this);
|
||||
correctionTimer = CorrectionDelay;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing = false)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Vector2(item.DrawPosition.X - 4, -item.DrawPosition.Y),
|
||||
new Vector2(8, 22), Color.Black);
|
||||
|
||||
if (charge > 0)
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Vector2(item.DrawPosition.X - 3, -item.DrawPosition.Y + 1 + (20.0f * (1.0f - charge / capacity))),
|
||||
new Vector2(6, 20 * (charge / capacity)), Color.Green, true);
|
||||
}
|
||||
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
GuiFrame.Draw(spriteBatch);
|
||||
|
||||
int x = GuiFrame.Rect.X;
|
||||
int y = GuiFrame.Rect.Y;
|
||||
//GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black, true);
|
||||
|
||||
GUI.Font.DrawString(spriteBatch,
|
||||
"Charge: " + (int)charge + "/" + (int)capacity + " kWm (" + (int)((charge / capacity) * 100.0f) + " %)",
|
||||
new Vector2(x + 30, y + 30), Color.White);
|
||||
|
||||
GUI.Font.DrawString(spriteBatch, "Recharge rate: " + (int)((rechargeSpeed / maxRechargeSpeed) * 100.0f) + " %", new Vector2(x + 30, y + 95), Color.White);
|
||||
}
|
||||
|
||||
public override void AddToGUIUpdateList()
|
||||
{
|
||||
GuiFrame.AddToGUIUpdateList();
|
||||
}
|
||||
|
||||
public override void UpdateHUD(Character character)
|
||||
{
|
||||
GuiFrame.Update(1.0f / 60.0f);
|
||||
}
|
||||
|
||||
public void ClientWrite(NetBuffer msg, object[] extraData)
|
||||
{
|
||||
msg.WriteRangedInteger(0, 10, (int)(rechargeSpeed / MaxRechargeSpeed * 10));
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
|
||||
{
|
||||
if (correctionTimer > 0.0f)
|
||||
{
|
||||
StartDelayedCorrection(type, msg.ExtractBits(4 + 8), sendingTime);
|
||||
return;
|
||||
}
|
||||
|
||||
RechargeSpeed = msg.ReadRangedInteger(0, 10) / 10.0f * maxRechargeSpeed;
|
||||
Charge = msg.ReadRangedSingle(0.0f, 1.0f, 8) * capacity;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class PowerTransfer : Powered
|
||||
{
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
if (!canBeSelected) return;
|
||||
|
||||
int x = GuiFrame.Rect.X;
|
||||
int y = GuiFrame.Rect.Y;
|
||||
|
||||
GuiFrame.Draw(spriteBatch);
|
||||
|
||||
GUI.Font.DrawString(spriteBatch, "Power: " + (int)(-currPowerConsumption) + " kW", new Vector2(x + 30, y + 30), Color.White);
|
||||
GUI.Font.DrawString(spriteBatch, "Load: " + (int)powerLoad + " kW", new Vector2(x + 30, y + 100), Color.White);
|
||||
}
|
||||
|
||||
public override void AddToGUIUpdateList()
|
||||
{
|
||||
GuiFrame.AddToGUIUpdateList();
|
||||
}
|
||||
|
||||
public override void UpdateHUD(Character character)
|
||||
{
|
||||
GuiFrame.Update(1.0f / 60.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class Powered : ItemComponent
|
||||
{
|
||||
protected static Sound[] sparkSounds;
|
||||
|
||||
private bool powerOnSoundPlayed;
|
||||
|
||||
private static Sound powerOnSound;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class ConnectionPanel : ItemComponent, IServerSerializable, IClientSerializable
|
||||
{
|
||||
public override void UpdateHUD(Character character)
|
||||
{
|
||||
if (character != Character.Controlled || character != user) return;
|
||||
|
||||
if (Screen.Selected != GameMain.EditMapScreen &&
|
||||
character.IsKeyHit(InputType.Select) &&
|
||||
character.SelectedConstruction == this.item) character.SelectedConstruction = null;
|
||||
|
||||
if (HighlightedWire != null)
|
||||
{
|
||||
HighlightedWire.Item.IsHighlighted = true;
|
||||
if (HighlightedWire.Connections[0] != null && HighlightedWire.Connections[0].Item != null) HighlightedWire.Connections[0].Item.IsHighlighted = true;
|
||||
if (HighlightedWire.Connections[1] != null && HighlightedWire.Connections[1].Item != null) HighlightedWire.Connections[1].Item.IsHighlighted = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
if (character != Character.Controlled || character != user) return;
|
||||
|
||||
HighlightedWire = null;
|
||||
Connection.DrawConnections(spriteBatch, this, character);
|
||||
|
||||
}
|
||||
|
||||
public override XElement Save(XElement parentElement)
|
||||
{
|
||||
XElement componentElement = base.Save(parentElement);
|
||||
|
||||
foreach (Connection c in Connections)
|
||||
{
|
||||
c.Save(componentElement);
|
||||
}
|
||||
|
||||
return componentElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
using Barotrauma.Networking;
|
||||
using Lidgren.Network;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class Wire : ItemComponent, IDrawableComponent, IServerSerializable
|
||||
{
|
||||
partial class WireSection
|
||||
{
|
||||
public void Draw(SpriteBatch spriteBatch, Color color, Vector2 offset, float depth, float width = 0.3f)
|
||||
{
|
||||
spriteBatch.Draw(wireSprite.Texture,
|
||||
new Vector2(start.X + offset.X, -(start.Y + offset.Y)), null, color,
|
||||
-angle,
|
||||
new Vector2(0.0f, wireSprite.size.Y / 2.0f),
|
||||
new Vector2(length / wireSprite.Texture.Width, width),
|
||||
SpriteEffects.None,
|
||||
depth);
|
||||
}
|
||||
|
||||
public static void Draw(SpriteBatch spriteBatch, Vector2 start, Vector2 end, Color color, float depth, float width = 0.3f)
|
||||
{
|
||||
start.Y = -start.Y;
|
||||
end.Y = -end.Y;
|
||||
|
||||
spriteBatch.Draw(wireSprite.Texture,
|
||||
start, null, color,
|
||||
MathUtils.VectorToAngle(end - start),
|
||||
new Vector2(0.0f, wireSprite.size.Y / 2.0f),
|
||||
new Vector2((Vector2.Distance(start, end)) / wireSprite.Texture.Width, width),
|
||||
SpriteEffects.None,
|
||||
depth);
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing)
|
||||
{
|
||||
if (sections.Count == 0 && !IsActive)
|
||||
{
|
||||
Drawable = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 drawOffset = Vector2.Zero;
|
||||
if (item.Submarine != null)
|
||||
{
|
||||
drawOffset = item.Submarine.DrawPosition + item.Submarine.HiddenSubPosition;
|
||||
}
|
||||
|
||||
float depth = item.IsSelected ? 0.0f : wireSprite.Depth + ((item.ID % 100) * 0.00001f);
|
||||
|
||||
if (item.IsHighlighted)
|
||||
{
|
||||
foreach (WireSection section in sections)
|
||||
{
|
||||
section.Draw(spriteBatch, Color.Gold, drawOffset, depth + 0.00001f, 0.7f);
|
||||
}
|
||||
}
|
||||
else if (item.IsSelected)
|
||||
{
|
||||
foreach (WireSection section in sections)
|
||||
{
|
||||
section.Draw(spriteBatch, Color.Red, drawOffset, depth + 0.00001f, 0.7f);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (WireSection section in sections)
|
||||
{
|
||||
section.Draw(spriteBatch, item.Color, drawOffset, depth, 0.3f);
|
||||
}
|
||||
|
||||
if (IsActive && nodes.Count > 0 && Vector2.Distance(newNodePos, nodes[nodes.Count - 1]) > nodeDistance)
|
||||
{
|
||||
WireSection.Draw(
|
||||
spriteBatch,
|
||||
new Vector2(nodes[nodes.Count - 1].X, nodes[nodes.Count - 1].Y) + drawOffset,
|
||||
new Vector2(newNodePos.X, newNodePos.Y) + drawOffset,
|
||||
item.Color * 0.5f,
|
||||
depth,
|
||||
0.3f);
|
||||
}
|
||||
|
||||
if (!editing || !GameMain.EditMapScreen.WiringMode) return;
|
||||
|
||||
for (int i = 0; i < nodes.Count; i++)
|
||||
{
|
||||
Vector2 drawPos = nodes[i];
|
||||
if (item.Submarine != null) drawPos += item.Submarine.Position + item.Submarine.HiddenSubPosition;
|
||||
drawPos.Y = -drawPos.Y;
|
||||
|
||||
if (item.IsSelected)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, drawPos + new Vector2(-5, -5), new Vector2(10, 10), item.Color, true, 0.0f);
|
||||
|
||||
if (highlightedNodeIndex == i)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, drawPos + new Vector2(-10, -10), new Vector2(20, 20), Color.Red, false, 0.0f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, drawPos + new Vector2(-3, -3), new Vector2(6, 6), item.Color, true, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdateEditing(List<Wire> wires)
|
||||
{
|
||||
//dragging a node of some wire
|
||||
if (draggingWire != null)
|
||||
{
|
||||
//cancel dragging
|
||||
if (!PlayerInput.LeftButtonHeld())
|
||||
{
|
||||
draggingWire = null;
|
||||
selectedNodeIndex = null;
|
||||
}
|
||||
//update dragging
|
||||
else
|
||||
{
|
||||
MapEntity.DisableSelect = true;
|
||||
|
||||
Submarine sub = null;
|
||||
if (draggingWire.connections[0] != null && draggingWire.connections[0].Item.Submarine != null) sub = draggingWire.connections[0].Item.Submarine;
|
||||
if (draggingWire.connections[1] != null && draggingWire.connections[1].Item.Submarine != null) sub = draggingWire.connections[1].Item.Submarine;
|
||||
|
||||
Vector2 nodeWorldPos = GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition) - sub.HiddenSubPosition - sub.Position;// Nodes[(int)selectedNodeIndex];
|
||||
|
||||
nodeWorldPos.X = MathUtils.Round(nodeWorldPos.X, Submarine.GridSize.X / 2.0f);
|
||||
nodeWorldPos.Y = MathUtils.Round(nodeWorldPos.Y, Submarine.GridSize.Y / 2.0f);
|
||||
|
||||
draggingWire.nodes[(int)selectedNodeIndex] = nodeWorldPos;
|
||||
draggingWire.UpdateSections();
|
||||
|
||||
MapEntity.SelectEntity(draggingWire.item);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//a wire has been selected -> check if we should start dragging one of the nodes
|
||||
float nodeSelectDist = 10, sectionSelectDist = 5;
|
||||
highlightedNodeIndex = null;
|
||||
if (MapEntity.SelectedList.Count == 1 && MapEntity.SelectedList[0] is Item)
|
||||
{
|
||||
Wire selectedWire = ((Item)MapEntity.SelectedList[0]).GetComponent<Wire>();
|
||||
|
||||
if (selectedWire != null)
|
||||
{
|
||||
Vector2 mousePos = GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||
if (selectedWire.item.Submarine != null) mousePos -= (selectedWire.item.Submarine.Position + selectedWire.item.Submarine.HiddenSubPosition);
|
||||
|
||||
//left click while holding ctrl -> check if the cursor is on a wire section,
|
||||
//and add a new node if it is
|
||||
if (PlayerInput.KeyDown(Keys.RightControl) || PlayerInput.KeyDown(Keys.LeftControl))
|
||||
{
|
||||
if (PlayerInput.LeftButtonClicked())
|
||||
{
|
||||
float temp = 0.0f;
|
||||
int closestSectionIndex = selectedWire.GetClosestSectionIndex(mousePos, sectionSelectDist, out temp);
|
||||
|
||||
if (closestSectionIndex > -1)
|
||||
{
|
||||
selectedWire.nodes.Insert(closestSectionIndex + 1, mousePos);
|
||||
selectedWire.UpdateSections();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//check if close enough to a node
|
||||
float temp = 0.0f;
|
||||
int closestIndex = selectedWire.GetClosestNodeIndex(mousePos, nodeSelectDist, out temp);
|
||||
if (closestIndex > -1)
|
||||
{
|
||||
highlightedNodeIndex = closestIndex;
|
||||
//start dragging the node
|
||||
if (PlayerInput.LeftButtonHeld())
|
||||
{
|
||||
draggingWire = selectedWire;
|
||||
selectedNodeIndex = closestIndex;
|
||||
}
|
||||
//remove the node
|
||||
else if (PlayerInput.RightButtonClicked() && closestIndex > 0 && closestIndex < selectedWire.nodes.Count - 1)
|
||||
{
|
||||
selectedWire.nodes.RemoveAt(closestIndex);
|
||||
selectedWire.UpdateSections();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//check which wire is highlighted with the cursor
|
||||
Wire highlighted = null;
|
||||
float closestDist = 0.0f;
|
||||
foreach (Wire w in wires)
|
||||
{
|
||||
Vector2 mousePos = GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||
if (w.item.Submarine != null) mousePos -= (w.item.Submarine.Position + w.item.Submarine.HiddenSubPosition);
|
||||
|
||||
float dist = 0.0f;
|
||||
if (w.GetClosestNodeIndex(mousePos, highlighted == null ? nodeSelectDist : closestDist, out dist) > -1)
|
||||
{
|
||||
highlighted = w;
|
||||
closestDist = dist;
|
||||
}
|
||||
|
||||
if (w.GetClosestSectionIndex(mousePos, highlighted == null ? sectionSelectDist : closestDist, out dist) > -1)
|
||||
{
|
||||
highlighted = w;
|
||||
closestDist = dist;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (highlighted != null)
|
||||
{
|
||||
highlighted.item.IsHighlighted = true;
|
||||
|
||||
if (PlayerInput.LeftButtonClicked())
|
||||
{
|
||||
MapEntity.DisableSelect = true;
|
||||
MapEntity.SelectEntity(highlighted.item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override XElement Save(XElement parentElement)
|
||||
{
|
||||
XElement componentElement = base.Save(parentElement);
|
||||
|
||||
if (nodes == null || nodes.Count == 0) return componentElement;
|
||||
|
||||
string[] nodeCoords = new string[nodes.Count * 2];
|
||||
for (int i = 0; i < nodes.Count; i++)
|
||||
{
|
||||
nodeCoords[i * 2] = nodes[i].X.ToString(CultureInfo.InvariantCulture);
|
||||
nodeCoords[i * 2 + 1] = nodes[i].Y.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
componentElement.Add(new XAttribute("nodes", string.Join(";", nodeCoords)));
|
||||
|
||||
return componentElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class StatusHUD : ItemComponent
|
||||
{
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
if (character == null) return;
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight),
|
||||
Color.Green * 0.1f, true);
|
||||
|
||||
if (character.ClosestCharacter == null) return;
|
||||
|
||||
var target = character.ClosestCharacter;
|
||||
|
||||
Vector2 hudPos = GameMain.GameScreen.Cam.WorldToScreen(target.WorldPosition);
|
||||
hudPos += Vector2.UnitX * 50.0f;
|
||||
|
||||
List<string> texts = new List<string>();
|
||||
|
||||
texts.Add(target.Name);
|
||||
|
||||
if (target.IsDead)
|
||||
{
|
||||
texts.Add("Deceased");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (target.IsUnconscious) texts.Add("Unconscious");
|
||||
if (target.Stun > 0.01f) texts.Add("Stunned");
|
||||
|
||||
int healthTextIndex = target.Health > 95.0f ? 0 :
|
||||
MathHelper.Clamp((int)Math.Ceiling((1.0f - (target.Health / 200.0f + 0.5f)) * HealthTexts.Length), 0, HealthTexts.Length - 1);
|
||||
|
||||
texts.Add(HealthTexts[healthTextIndex]);
|
||||
|
||||
int oxygenTextIndex = MathHelper.Clamp((int)Math.Floor((1.0f - (target.Oxygen / 200.0f + 0.5f)) * OxygenTexts.Length), 0, OxygenTexts.Length - 1);
|
||||
texts.Add(OxygenTexts[oxygenTextIndex]);
|
||||
|
||||
if (target.Bleeding > 0.0f)
|
||||
{
|
||||
int bleedingTextIndex = MathHelper.Clamp((int)Math.Floor(target.Bleeding / 4.0f) * BleedingTexts.Length, 0, BleedingTexts.Length - 1);
|
||||
texts.Add(BleedingTexts[bleedingTextIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
foreach (string text in texts)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, hudPos, text, Color.LightGreen, Color.Black * 0.7f, 2);
|
||||
hudPos.Y += 24.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user