From 8f37e14917af287b2707a46afd5800835233259c Mon Sep 17 00:00:00 2001 From: Juan Pablo Arce Date: Sun, 18 Jun 2017 14:36:11 -0300 Subject: [PATCH] Split Machines ItemComponents There's still a lot of work to do before we can get the server to compile --- BarotraumaClient/BarotraumaClient.csproj | 40 ++ .../Source/Characters/AI/CrewCommander.cs | 0 .../Source/Characters/AICharacter.cs | 16 + .../Source/Characters/Character.cs | 3 + BarotraumaClient/Source/Characters/Limb.cs | 2 + BarotraumaClient/Source/GUI/GUI.cs | 9 - .../Source/Items/Components/Door.cs | 142 +++++ .../Source/Items/Components/ItemComponent.cs | 273 +++++++++ .../Source/Items/Components/ItemContainer.cs | 87 +++ .../Source/Items/Components/LightComponent.cs | 27 + .../Components/Machines/Deconstructor.cs | 61 ++ .../Items/Components/Machines/Engine.cs | 38 ++ .../Items/Components/Machines/Fabricator.cs | 243 ++++++++ .../Items/Components/Machines/MiniMap.cs | 129 +++++ .../Source/Items/Components/Machines/Pump.cs | 117 ++++ .../Source/Items/Components/Machines/Radar.cs | 443 +++++++++++++++ .../Items/Components/Machines/Reactor.cs | 265 +++++++++ .../Items/Components/Machines/Steering.cs | 301 ++++++++++ .../Items/Components/Power/PowerContainer.cs | 110 ++++ .../Items/Components/Power/PowerTransfer.cs | 36 ++ .../Source/Items/Components/Power/Powered.cs | 14 + .../Components/Signal/ConnectionPanel.cs | 51 ++ .../Source/Items/Components/Signal/Wire.cs | 256 +++++++++ .../Source/Items/Components/StatusHUD.cs | 64 +++ BarotraumaClient/Source/Items/ItemPrefab.cs | 53 ++ BarotraumaClient/Source/Map/Explosion.cs | 73 +++ BarotraumaClient/Source/Map/FireSource.cs | 86 +++ BarotraumaClient/Source/Map/Gap.cs | 95 ++++ BarotraumaClient/Source/Map/Hull.cs | 205 +++++++ BarotraumaClient/Source/Map/Levels/Level.cs | 59 ++ .../Source/Map/Levels/LevelRenderer.cs | 0 .../Source/Map/Levels/WaterRenderer.cs | 0 .../Source/Map/Lights/ConvexHull.cs | 0 .../Source/Map/Lights/LightManager.cs | 0 .../Source/Map/Lights/LightSource.cs | 0 .../Source/Map/LinkedSubmarine.cs | 234 ++++++++ BarotraumaClient/Source/Map/MapEntity.cs | 2 +- BarotraumaClient/Source/Map/Structure.cs | 54 ++ BarotraumaClient/Source/Networking/BanList.cs | 86 +++ .../Source/Networking/GameServer.cs | 9 + .../Source/Networking/GameServerSettings.cs | 534 +++++++++++++++++ .../Source/Networking/NetStats.cs | 0 .../Source/Networking/NetworkMember.cs | 149 +++++ .../Source/Networking/ServerLog.cs | 128 +++++ .../Source/Networking/WhiteList.cs | 112 ++++ BarotraumaClient/Source/Utils/MathUtils.cs | 22 + BarotraumaClient/Source/Utils/ToolBox.cs | 103 ++++ BarotraumaServer/BarotraumaServer.csproj | 21 +- .../Source/Items/Components/ItemComponent.cs | 31 + .../Items/Components/Machines/Fabricator.cs | 20 + .../Source/Items/Components/Machines/Pump.cs | 18 + .../Items/Components/Machines/Reactor.cs | 18 + .../Items/Components/Machines/Steering.cs | 26 + .../Items/Components/Power/PowerContainer.cs | 17 + BarotraumaServer/Source/Map/Explosion.cs | 17 + BarotraumaServer/Source/Map/FireSource.cs | 17 + BarotraumaServer/Source/Map/Hull.cs | 16 + .../Source/Networking/NetworkMember.cs | 19 + BarotraumaShared/BarotraumaShared.projitems | 7 - .../Source/Characters/AICharacter.cs | 13 +- .../Source/Characters/Character.cs | 9 +- BarotraumaShared/Source/Characters/Limb.cs | 27 +- .../Source/Items/Components/Door.cs | 151 +---- .../Items/Components/Holdable/RepairTool.cs | 4 +- .../Source/Items/Components/ItemComponent.cs | 268 +-------- .../Source/Items/Components/ItemContainer.cs | 75 +-- .../Components/Machines/Deconstructor.cs | 60 +- .../Items/Components/Machines/Engine.cs | 33 +- .../Items/Components/Machines/Fabricator.cs | 242 +------- .../Items/Components/Machines/MiniMap.cs | 119 +--- .../Source/Items/Components/Machines/Pump.cs | 105 +--- .../Source/Items/Components/Machines/Radar.cs | 439 +------------- .../Items/Components/Machines/Reactor.cs | 262 +-------- .../Items/Components/Machines/Steering.cs | 301 +--------- .../Items/Components/Power/PowerContainer.cs | 97 +--- .../Items/Components/Power/PowerTransfer.cs | 25 +- .../Source/Items/Components/Power/Powered.cs | 14 +- .../Components/Signal/ConnectionPanel.cs | 39 +- .../Items/Components/Signal/LightComponent.cs | 48 +- .../Source/Items/Components/Signal/Wire.cs | 245 +------- .../Source/Items/Components/StatusHUD.cs | 53 +- BarotraumaShared/Source/Items/ItemPrefab.cs | 41 +- BarotraumaShared/Source/Map/Explosion.cs | 58 +- BarotraumaShared/Source/Map/FireSource.cs | 104 +--- BarotraumaShared/Source/Map/Gap.cs | 94 +-- BarotraumaShared/Source/Map/Hull.cs | 206 +------ BarotraumaShared/Source/Map/Levels/Level.cs | 61 +- .../Source/Map/LinkedSubmarine.cs | 222 +------- BarotraumaShared/Source/Map/Structure.cs | 71 +-- BarotraumaShared/Source/Networking/BanList.cs | 72 +-- .../Source/Networking/GameServer.cs | 22 +- .../Source/Networking/GameServerSettings.cs | 536 +----------------- .../Source/Networking/NetworkMember.cs | 140 +---- .../Source/Networking/ServerLog.cs | 122 +--- .../Source/Networking/WhiteList.cs | 99 +--- BarotraumaShared/Source/Utils/MathUtils.cs | 24 +- BarotraumaShared/Source/Utils/ToolBox.cs | 89 +-- .../Hyper.ComponentModel.csproj | 7 +- 98 files changed, 5264 insertions(+), 4291 deletions(-) rename {BarotraumaShared => BarotraumaClient}/Source/Characters/AI/CrewCommander.cs (100%) create mode 100644 BarotraumaClient/Source/Characters/AICharacter.cs create mode 100644 BarotraumaClient/Source/Items/Components/Door.cs create mode 100644 BarotraumaClient/Source/Items/Components/ItemComponent.cs create mode 100644 BarotraumaClient/Source/Items/Components/ItemContainer.cs create mode 100644 BarotraumaClient/Source/Items/Components/LightComponent.cs create mode 100644 BarotraumaClient/Source/Items/Components/Machines/Deconstructor.cs create mode 100644 BarotraumaClient/Source/Items/Components/Machines/Engine.cs create mode 100644 BarotraumaClient/Source/Items/Components/Machines/Fabricator.cs create mode 100644 BarotraumaClient/Source/Items/Components/Machines/MiniMap.cs create mode 100644 BarotraumaClient/Source/Items/Components/Machines/Pump.cs create mode 100644 BarotraumaClient/Source/Items/Components/Machines/Radar.cs create mode 100644 BarotraumaClient/Source/Items/Components/Machines/Reactor.cs create mode 100644 BarotraumaClient/Source/Items/Components/Machines/Steering.cs create mode 100644 BarotraumaClient/Source/Items/Components/Power/PowerContainer.cs create mode 100644 BarotraumaClient/Source/Items/Components/Power/PowerTransfer.cs create mode 100644 BarotraumaClient/Source/Items/Components/Power/Powered.cs create mode 100644 BarotraumaClient/Source/Items/Components/Signal/ConnectionPanel.cs create mode 100644 BarotraumaClient/Source/Items/Components/Signal/Wire.cs create mode 100644 BarotraumaClient/Source/Items/Components/StatusHUD.cs create mode 100644 BarotraumaClient/Source/Items/ItemPrefab.cs create mode 100644 BarotraumaClient/Source/Map/Explosion.cs create mode 100644 BarotraumaClient/Source/Map/FireSource.cs create mode 100644 BarotraumaClient/Source/Map/Gap.cs create mode 100644 BarotraumaClient/Source/Map/Hull.cs create mode 100644 BarotraumaClient/Source/Map/Levels/Level.cs rename {BarotraumaShared => BarotraumaClient}/Source/Map/Levels/LevelRenderer.cs (100%) rename {BarotraumaShared => BarotraumaClient}/Source/Map/Levels/WaterRenderer.cs (100%) rename {BarotraumaShared => BarotraumaClient}/Source/Map/Lights/ConvexHull.cs (100%) rename {BarotraumaShared => BarotraumaClient}/Source/Map/Lights/LightManager.cs (100%) rename {BarotraumaShared => BarotraumaClient}/Source/Map/Lights/LightSource.cs (100%) create mode 100644 BarotraumaClient/Source/Map/LinkedSubmarine.cs create mode 100644 BarotraumaClient/Source/Networking/BanList.cs create mode 100644 BarotraumaClient/Source/Networking/GameServerSettings.cs rename {BarotraumaShared => BarotraumaClient}/Source/Networking/NetStats.cs (100%) create mode 100644 BarotraumaClient/Source/Networking/NetworkMember.cs create mode 100644 BarotraumaClient/Source/Networking/ServerLog.cs create mode 100644 BarotraumaClient/Source/Networking/WhiteList.cs create mode 100644 BarotraumaClient/Source/Utils/MathUtils.cs create mode 100644 BarotraumaClient/Source/Utils/ToolBox.cs create mode 100644 BarotraumaServer/Source/Items/Components/ItemComponent.cs create mode 100644 BarotraumaServer/Source/Items/Components/Machines/Fabricator.cs create mode 100644 BarotraumaServer/Source/Items/Components/Machines/Pump.cs create mode 100644 BarotraumaServer/Source/Items/Components/Machines/Reactor.cs create mode 100644 BarotraumaServer/Source/Items/Components/Machines/Steering.cs create mode 100644 BarotraumaServer/Source/Items/Components/Power/PowerContainer.cs create mode 100644 BarotraumaServer/Source/Map/Explosion.cs create mode 100644 BarotraumaServer/Source/Map/FireSource.cs create mode 100644 BarotraumaServer/Source/Map/Hull.cs create mode 100644 BarotraumaServer/Source/Networking/NetworkMember.cs diff --git a/BarotraumaClient/BarotraumaClient.csproj b/BarotraumaClient/BarotraumaClient.csproj index 50f7f43e8..51cad3291 100644 --- a/BarotraumaClient/BarotraumaClient.csproj +++ b/BarotraumaClient/BarotraumaClient.csproj @@ -63,6 +63,8 @@ + + @@ -107,18 +109,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -141,7 +179,9 @@ + + diff --git a/BarotraumaShared/Source/Characters/AI/CrewCommander.cs b/BarotraumaClient/Source/Characters/AI/CrewCommander.cs similarity index 100% rename from BarotraumaShared/Source/Characters/AI/CrewCommander.cs rename to BarotraumaClient/Source/Characters/AI/CrewCommander.cs diff --git a/BarotraumaClient/Source/Characters/AICharacter.cs b/BarotraumaClient/Source/Characters/AICharacter.cs new file mode 100644 index 000000000..9758b9833 --- /dev/null +++ b/BarotraumaClient/Source/Characters/AICharacter.cs @@ -0,0 +1,16 @@ +using Microsoft.Xna.Framework; +using System; + +namespace Barotrauma +{ + partial class AICharacter : Character + { + public override void DrawFront(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch, Camera cam) + { + base.DrawFront(spriteBatch, cam); + + if (GameMain.DebugDraw && !IsDead) aiController.DebugDraw(spriteBatch); + } + + } +} diff --git a/BarotraumaClient/Source/Characters/Character.cs b/BarotraumaClient/Source/Characters/Character.cs index f55956cac..51bb1e3c1 100644 --- a/BarotraumaClient/Source/Characters/Character.cs +++ b/BarotraumaClient/Source/Characters/Character.cs @@ -14,6 +14,9 @@ namespace Barotrauma { partial class Character : Entity, IDamageable, IPropertyObject, IClientSerializable, IServerSerializable { + protected float soundTimer; + protected float soundInterval; + private List sounds; //the Character that the player is currently controlling diff --git a/BarotraumaClient/Source/Characters/Limb.cs b/BarotraumaClient/Source/Characters/Limb.cs index 1e5fe7d4c..c8b86b7bd 100644 --- a/BarotraumaClient/Source/Characters/Limb.cs +++ b/BarotraumaClient/Source/Characters/Limb.cs @@ -15,6 +15,8 @@ namespace Barotrauma { partial class Limb { + public readonly LightSource LightSource; + Sound hitSound; public Sound HitSound diff --git a/BarotraumaClient/Source/GUI/GUI.cs b/BarotraumaClient/Source/GUI/GUI.cs index fca97836a..8625ad4b5 100644 --- a/BarotraumaClient/Source/GUI/GUI.cs +++ b/BarotraumaClient/Source/GUI/GUI.cs @@ -6,15 +6,6 @@ using System.Collections.Generic; namespace Barotrauma { - [Flags] - public enum Alignment - { - CenterX = 1, Left = 2, Right = 4, CenterY = 8, Top = 16, Bottom = 32, - TopLeft = (Top | Left), TopCenter = (CenterX | Top), TopRight = (Top | Right), - CenterLeft = (Left | CenterY), Center = (CenterX | CenterY), CenterRight = (Right | CenterY), - BottomLeft = (Bottom | Left), BottomCenter = (CenterX | Bottom), BottomRight = (Bottom | Right), - } - public enum GUISoundType { Message, diff --git a/BarotraumaClient/Source/Items/Components/Door.cs b/BarotraumaClient/Source/Items/Components/Door.cs new file mode 100644 index 000000000..7f3c8c79a --- /dev/null +++ b/BarotraumaClient/Source/Items/Components/Door.cs @@ -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); + } + + } + } +} diff --git a/BarotraumaClient/Source/Items/Components/ItemComponent.cs b/BarotraumaClient/Source/Items/Components/ItemComponent.cs new file mode 100644 index 000000000..72140c4ba --- /dev/null +++ b/BarotraumaClient/Source/Items/Components/ItemComponent.cs @@ -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> 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 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 soundList = null; + if (!sounds.TryGetValue(itemSound.Type, out soundList)) + { + soundList = new List(); + 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 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; + } + } +} diff --git a/BarotraumaClient/Source/Items/Components/ItemContainer.cs b/BarotraumaClient/Source/Items/Components/ItemContainer.cs new file mode 100644 index 000000000..1c8136e49 --- /dev/null +++ b/BarotraumaClient/Source/Items/Components/ItemContainer.cs @@ -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; + } + } +} diff --git a/BarotraumaClient/Source/Items/Components/LightComponent.cs b/BarotraumaClient/Source/Items/Components/LightComponent.cs new file mode 100644 index 000000000..31e077742 --- /dev/null +++ b/BarotraumaClient/Source/Items/Components/LightComponent.cs @@ -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(); + } + } +} diff --git a/BarotraumaClient/Source/Items/Components/Machines/Deconstructor.cs b/BarotraumaClient/Source/Items/Components/Machines/Deconstructor.cs new file mode 100644 index 000000000..9571bfa23 --- /dev/null +++ b/BarotraumaClient/Source/Items/Components/Machines/Deconstructor.cs @@ -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()); + } + } +} diff --git a/BarotraumaClient/Source/Items/Components/Machines/Engine.cs b/BarotraumaClient/Source/Items/Components/Machines/Engine.cs new file mode 100644 index 000000000..33eac0bce --- /dev/null +++ b/BarotraumaClient/Source/Items/Components/Machines/Engine.cs @@ -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); + } + } +} diff --git a/BarotraumaClient/Source/Items/Components/Machines/Fabricator.cs b/BarotraumaClient/Source/Items/Components/Machines/Fabricator.cs new file mode 100644 index 000000000..13b712125 --- /dev/null +++ b/BarotraumaClient/Source/Items/Components/Machines/Fabricator.cs @@ -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 inadequateSkills = new List(); + + 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 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(); + 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]); + } + } + } +} \ No newline at end of file diff --git a/BarotraumaClient/Source/Items/Components/Machines/MiniMap.cs b/BarotraumaClient/Source/Items/Components/Machines/MiniMap.cs new file mode 100644 index 000000000..06934b0a0 --- /dev/null +++ b/BarotraumaClient/Source/Items/Components/Machines/MiniMap.cs @@ -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); + } + } + } +} diff --git a/BarotraumaClient/Source/Items/Components/Machines/Pump.cs b/BarotraumaClient/Source/Items/Components/Machines/Pump.cs new file mode 100644 index 000000000..18c8b59fa --- /dev/null +++ b/BarotraumaClient/Source/Items/Components/Machines/Pump.cs @@ -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(); + } + } +} diff --git a/BarotraumaClient/Source/Items/Components/Machines/Radar.cs b/BarotraumaClient/Source/Items/Components/Machines/Radar.cs new file mode 100644 index 000000000..3539b545c --- /dev/null +++ b/BarotraumaClient/Source/Items/Components/Machines/Radar.cs @@ -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 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(); + 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 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); + } + } +} diff --git a/BarotraumaClient/Source/Items/Components/Machines/Reactor.cs b/BarotraumaClient/Source/Items/Components/Machines/Reactor.cs new file mode 100644 index 000000000..8c97ad85e --- /dev/null +++ b/BarotraumaClient/Source/Items/Components/Machines/Reactor.cs @@ -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(IList graph, T newValue) + { + for (int i = graph.Count - 1; i > 0; i--) + { + graph[i] = graph[i - 1]; + } + graph[0] = newValue; + } + + static void DrawGraph(IList 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); + } + } +} diff --git a/BarotraumaClient/Source/Items/Components/Machines/Steering.cs b/BarotraumaClient/Source/Items/Components/Machines/Steering.cs new file mode 100644 index 000000000..ef47d035a --- /dev/null +++ b/BarotraumaClient/Source/Items/Components/Machines/Steering.cs @@ -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; + } + } + } + } +} diff --git a/BarotraumaClient/Source/Items/Components/Power/PowerContainer.cs b/BarotraumaClient/Source/Items/Components/Power/PowerContainer.cs new file mode 100644 index 000000000..e7dfcf9fe --- /dev/null +++ b/BarotraumaClient/Source/Items/Components/Power/PowerContainer.cs @@ -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; + } + } +} diff --git a/BarotraumaClient/Source/Items/Components/Power/PowerTransfer.cs b/BarotraumaClient/Source/Items/Components/Power/PowerTransfer.cs new file mode 100644 index 000000000..977762f01 --- /dev/null +++ b/BarotraumaClient/Source/Items/Components/Power/PowerTransfer.cs @@ -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); + } + } +} diff --git a/BarotraumaClient/Source/Items/Components/Power/Powered.cs b/BarotraumaClient/Source/Items/Components/Power/Powered.cs new file mode 100644 index 000000000..7ccebf862 --- /dev/null +++ b/BarotraumaClient/Source/Items/Components/Power/Powered.cs @@ -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; + } +} diff --git a/BarotraumaClient/Source/Items/Components/Signal/ConnectionPanel.cs b/BarotraumaClient/Source/Items/Components/Signal/ConnectionPanel.cs new file mode 100644 index 000000000..0f8382f2c --- /dev/null +++ b/BarotraumaClient/Source/Items/Components/Signal/ConnectionPanel.cs @@ -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; + } + } +} diff --git a/BarotraumaClient/Source/Items/Components/Signal/Wire.cs b/BarotraumaClient/Source/Items/Components/Signal/Wire.cs new file mode 100644 index 000000000..34af1192a --- /dev/null +++ b/BarotraumaClient/Source/Items/Components/Signal/Wire.cs @@ -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 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(); + + 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; + } + } +} diff --git a/BarotraumaClient/Source/Items/Components/StatusHUD.cs b/BarotraumaClient/Source/Items/Components/StatusHUD.cs new file mode 100644 index 000000000..9d4c274e5 --- /dev/null +++ b/BarotraumaClient/Source/Items/Components/StatusHUD.cs @@ -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 texts = new List(); + + 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; + } + } + } +} diff --git a/BarotraumaClient/Source/Items/ItemPrefab.cs b/BarotraumaClient/Source/Items/ItemPrefab.cs new file mode 100644 index 000000000..16142e255 --- /dev/null +++ b/BarotraumaClient/Source/Items/ItemPrefab.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Xml.Linq; +using FarseerPhysics; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; + +namespace Barotrauma +{ + partial class ItemPrefab : MapEntityPrefab + { + public override void DrawPlacing(SpriteBatch spriteBatch, Camera cam) + { + Vector2 position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub); + + if (PlayerInput.RightButtonClicked()) + { + selected = null; + return; + } + + if (!resizeHorizontal && !resizeVertical) + { + sprite.Draw(spriteBatch, new Vector2(position.X + sprite.size.X / 2.0f, -position.Y + sprite.size.Y / 2.0f), SpriteColor); + } + else + { + Vector2 placeSize = size; + + if (placePosition == Vector2.Zero) + { + if (PlayerInput.LeftButtonHeld()) placePosition = position; + } + else + { + if (resizeHorizontal) + placeSize.X = Math.Max(position.X - placePosition.X, size.X); + if (resizeVertical) + placeSize.Y = Math.Max(placePosition.Y - position.Y, size.Y); + + position = placePosition; + } + + if (sprite != null) sprite.DrawTiled(spriteBatch, new Vector2(position.X, -position.Y), placeSize, SpriteColor); + } + + //if (PlayerInput.GetMouseState.RightButton == ButtonState.Pressed) selected = null; + + } + } +} diff --git a/BarotraumaClient/Source/Map/Explosion.cs b/BarotraumaClient/Source/Map/Explosion.cs new file mode 100644 index 000000000..66c14c608 --- /dev/null +++ b/BarotraumaClient/Source/Map/Explosion.cs @@ -0,0 +1,73 @@ +using Microsoft.Xna.Framework; +using Barotrauma.Lights; +using System; +using System.Collections.Generic; +using System.Xml.Linq; +using Barotrauma.Networking; +using FarseerPhysics; + +namespace Barotrauma +{ + partial class Explosion + { + private void ExplodeProjSpecific(Vector2 worldPosition,Hull hull) + { + + if (shockwave) + { + GameMain.ParticleManager.CreateParticle("shockwave", worldPosition, + Vector2.Zero, 0.0f, hull); + } + + for (int i = 0; i < attack.Range * 0.1f; i++) + { + Vector2 bubblePos = Rand.Vector(attack.Range * 0.5f); + GameMain.ParticleManager.CreateParticle("bubbles", worldPosition + bubblePos, + bubblePos, 0.0f, hull); + + if (sparks) + { + GameMain.ParticleManager.CreateParticle("spark", worldPosition, + Rand.Vector(Rand.Range(500.0f, 800.0f)), 0.0f, hull); + } + if (flames) + { + GameMain.ParticleManager.CreateParticle("explosionfire", ClampParticlePos(worldPosition + Rand.Vector(50f), hull), + Rand.Vector(Rand.Range(50.0f, 100.0f)), 0.0f, hull); + } + if (smoke) + { + GameMain.ParticleManager.CreateParticle("smoke", ClampParticlePos(worldPosition + Rand.Vector(50f), hull), + Rand.Vector(Rand.Range(1.0f, 10.0f)), 0.0f, hull); + } + } + + float displayRange = attack.Range; + if (displayRange < 0.1f) return; + + var light = new LightSource(worldPosition, displayRange, Color.LightYellow, null); + CoroutineManager.StartCoroutine(DimLight(light)); + + } + + private IEnumerable DimLight(LightSource light) + { + float currBrightness = 1.0f; + float startRange = light.Range; + + while (light.Color.A > 0.0f) + { + light.Color = new Color(light.Color.R, light.Color.G, light.Color.B, currBrightness); + light.Range = startRange * currBrightness; + + currBrightness -= CoroutineManager.DeltaTime * 20.0f; + + yield return CoroutineStatus.Running; + } + + light.Remove(); + + yield return CoroutineStatus.Success; + } + } +} diff --git a/BarotraumaClient/Source/Map/FireSource.cs b/BarotraumaClient/Source/Map/FireSource.cs new file mode 100644 index 000000000..3e9f8568d --- /dev/null +++ b/BarotraumaClient/Source/Map/FireSource.cs @@ -0,0 +1,86 @@ +using Barotrauma.Lights; +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Barotrauma.Networking; + +namespace Barotrauma +{ + partial class FireSource + { + static Sound fireSoundBasic, fireSoundLarge; + + private LightSource lightSource; + + private void UpdateProjSpecific(float growModifier) + { + if (hull.FireSources.Any(fs => fs != this && fs.size.X > size.X)) + { + if (basicSoundIndex > 0) + { + Sounds.SoundManager.Stop(basicSoundIndex); + basicSoundIndex = -1; + } + if (largeSoundIndex > 0) + { + Sounds.SoundManager.Stop(largeSoundIndex); + largeSoundIndex = -1; + } + } + else + { + if (fireSoundBasic != null) + { + basicSoundIndex = fireSoundBasic.Loop(basicSoundIndex, + Math.Min(size.X / 100.0f, 1.0f), WorldPosition + size / 2.0f, 1000.0f); + + } + if (fireSoundLarge != null) + { + largeSoundIndex = fireSoundLarge.Loop(largeSoundIndex, + MathHelper.Clamp((size.X - 200.0f) / 100.0f, 0.0f, 1.0f), WorldPosition + size / 2.0f, 1000.0f); + } + } + + float count = Rand.Range(0.0f, size.X / 50.0f); + + for (int i = 0; i < count; i++) + { + Vector2 particlePos = new Vector2( + WorldPosition.X + Rand.Range(0.0f, size.X), + Rand.Range(WorldPosition.Y - size.Y, WorldPosition.Y + 20.0f)); + + Vector2 particleVel = new Vector2( + (particlePos.X - (WorldPosition.X + size.X / 2.0f)), + (float)Math.Sqrt(size.X) * Rand.Range(0.0f, 15.0f) * growModifier); + + var particle = GameMain.ParticleManager.CreateParticle("flame", + particlePos, particleVel, 0.0f, hull); + + if (particle == null) continue; + + //make some of the particles create another firesource when they enter another hull + if (Rand.Int(20) == 1) particle.OnChangeHull = OnChangeHull; + + particle.Size *= MathHelper.Clamp(size.X / 60.0f * Math.Max(hull.Oxygen / hull.FullVolume, 0.4f), 0.5f, 1.0f); + + if (Rand.Int(5) == 1) + { + var smokeParticle = GameMain.ParticleManager.CreateParticle("smoke", + particlePos, new Vector2(particleVel.X, particleVel.Y * 0.1f), 0.0f, hull); + + if (smokeParticle != null) + { + smokeParticle.Size *= MathHelper.Clamp(size.X / 100.0f * Math.Max(hull.Oxygen / hull.FullVolume, 0.4f), 0.5f, 1.0f); + } + } + } + + lightSource.Range = Math.Max(size.X, size.Y) * 10.0f / 2.0f; + lightSource.Color = new Color(1.0f, 0.45f, 0.3f) * Rand.Range(0.8f, 1.0f); + lightSource.Position = position + Vector2.UnitY * 30.0f; + } + } +} diff --git a/BarotraumaClient/Source/Map/Gap.cs b/BarotraumaClient/Source/Map/Gap.cs new file mode 100644 index 000000000..5bc347cdc --- /dev/null +++ b/BarotraumaClient/Source/Map/Gap.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Xml.Linq; +using FarseerPhysics; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System.Collections.ObjectModel; +using Barotrauma.Items.Components; + +namespace Barotrauma +{ + partial class Gap : MapEntity + { + public override void Draw(SpriteBatch sb, bool editing, bool back = true) + { + if (GameMain.DebugDraw) + { + Vector2 center = new Vector2(WorldRect.X + rect.Width / 2.0f, -(WorldRect.Y - rect.Height / 2.0f)); + + GUI.DrawLine(sb, center, center + new Vector2(flowForce.X, -flowForce.Y) / 10.0f, Color.Red); + + GUI.DrawLine(sb, center + Vector2.One * 5.0f, center + new Vector2(lerpedFlowForce.X, -lerpedFlowForce.Y) / 10.0f + Vector2.One * 5.0f, Color.Orange); + } + + if (!editing || !ShowGaps) return; + + Color clr = (open == 0.0f) ? Color.Red : Color.Cyan; + if (isHighlighted) clr = Color.Gold; + + float depth = (ID % 255) * 0.000001f; + + GUI.DrawRectangle( + sb, new Rectangle(WorldRect.X, -WorldRect.Y, rect.Width, rect.Height), + clr * 0.5f, true, + depth, + (int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f)); + + for (int i = 0; i < linkedTo.Count; i++) + { + Vector2 dir = isHorizontal ? + new Vector2(Math.Sign(linkedTo[i].Rect.Center.X - rect.Center.X), 0.0f) + : new Vector2(0.0f, Math.Sign((linkedTo[i].Rect.Y - linkedTo[i].Rect.Height / 2.0f) - (rect.Y - rect.Height / 2.0f))); + + Vector2 arrowPos = new Vector2(WorldRect.Center.X, -(WorldRect.Y - WorldRect.Height / 2)); + arrowPos += new Vector2(dir.X * (WorldRect.Width / 2 + 10), dir.Y * (WorldRect.Height / 2 + 10)); + + GUI.Arrow.Draw(sb, + arrowPos, clr * 0.8f, + GUI.Arrow.Origin, MathUtils.VectorToAngle(dir) + MathHelper.PiOver2, + isHorizontal ? new Vector2(rect.Height / 16.0f, 1.0f) : new Vector2(rect.Width / 16.0f, 1.0f), + SpriteEffects.None, depth); + } + + if (IsSelected) + { + GUI.DrawRectangle(sb, + new Vector2(WorldRect.X - 5, -WorldRect.Y - 5), + new Vector2(rect.Width + 10, rect.Height + 10), + Color.Red, + false, + depth, + (int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f)); + } + } + + public override XElement Save(XElement parentElement) + { + XElement element = new XElement("Gap"); + + element.Add( + new XAttribute("ID", ID), + new XAttribute("horizontal", isHorizontal ? "true" : "false")); + + element.Add(new XAttribute("rect", + (int)(rect.X - Submarine.HiddenSubPosition.X) + "," + + (int)(rect.Y - Submarine.HiddenSubPosition.Y) + "," + + rect.Width + "," + rect.Height)); + + //if (linkedTo != null) + //{ + // int i = 0; + // foreach (Entity e in linkedTo) + // { + // if (e == null) continue; + // element.Add(new XAttribute("linkedto" + i, e.ID)); + // i += 1; + // } + //} + + parentElement.Add(element); + + return element; + } + } +} diff --git a/BarotraumaClient/Source/Map/Hull.cs b/BarotraumaClient/Source/Map/Hull.cs new file mode 100644 index 000000000..79814ac16 --- /dev/null +++ b/BarotraumaClient/Source/Map/Hull.cs @@ -0,0 +1,205 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Xml.Linq; +using FarseerPhysics; +using FarseerPhysics.Dynamics; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Lidgren.Network; +using Barotrauma.Networking; + +namespace Barotrauma +{ + partial class Hull : MapEntity, IPropertyObject, IServerSerializable + { + public static WaterRenderer renderer; + + private Sound currentFlowSound; + private int soundIndex; + private float soundVolume; + + public override bool IsMouseOn(Vector2 position) + { + if (!GameMain.DebugDraw && !ShowHulls) return false; + + return (Submarine.RectContains(WorldRect, position) && + !Submarine.RectContains(MathUtils.ExpandRect(WorldRect, -8), position)); + } + + public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true) + { + //if (back) return; + Rectangle drawRect; + if (!Visible) + { + drawRect = + Submarine == null ? rect : new Rectangle((int)(Submarine.DrawPosition.X + rect.X), (int)(Submarine.DrawPosition.Y + rect.Y), rect.Width, rect.Height); + + GUI.DrawRectangle(spriteBatch, + new Vector2(drawRect.X, -drawRect.Y), + new Vector2(rect.Width, rect.Height), + Color.Black, true, + 0, (int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f)); + } + + if (!ShowHulls && !GameMain.DebugDraw) return; + + if (!editing && !GameMain.DebugDraw) return; + + if (aiTarget != null) aiTarget.Draw(spriteBatch); + + drawRect = + Submarine == null ? rect : new Rectangle((int)(Submarine.DrawPosition.X + rect.X), (int)(Submarine.DrawPosition.Y + rect.Y), rect.Width, rect.Height); + + GUI.DrawRectangle(spriteBatch, + new Vector2(drawRect.X, -drawRect.Y), + new Vector2(rect.Width, rect.Height), + Color.Blue, false, (ID % 255) * 0.000001f, (int)Math.Max((1.5f / Screen.Selected.Cam.Zoom), 1.0f)); + + GUI.DrawRectangle(spriteBatch, + new Rectangle(drawRect.X, -drawRect.Y, rect.Width, rect.Height), + Color.Red * ((100.0f - OxygenPercentage) / 400.0f), true, 0, (int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f)); + + if (GameMain.DebugDraw) + { + GUI.SmallFont.DrawString(spriteBatch, "Pressure: " + ((int)pressure - rect.Y).ToString() + + " - Oxygen: " + ((int)OxygenPercentage), new Vector2(drawRect.X + 5, -drawRect.Y + 5), Color.White); + GUI.SmallFont.DrawString(spriteBatch, volume + " / " + FullVolume, new Vector2(drawRect.X + 5, -drawRect.Y + 20), Color.White); + + foreach (FireSource fs in fireSources) + { + GUI.DrawRectangle(spriteBatch, new Rectangle((int)fs.WorldPosition.X, (int)-fs.WorldPosition.Y, (int)fs.Size.X, (int)fs.Size.Y), Color.Orange, false); + } + } + + if ((IsSelected || isHighlighted) && editing) + { + GUI.DrawRectangle(spriteBatch, + new Vector2(drawRect.X + 5, -drawRect.Y + 5), + new Vector2(rect.Width - 10, rect.Height - 10), + isHighlighted ? Color.LightBlue * 0.5f : Color.Red * 0.5f, true, 0, (int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f)); + } + } + + public void Render(GraphicsDevice graphicsDevice, Camera cam) + { + if (renderer.PositionInBuffer > renderer.vertices.Length - 6) return; + + Vector2 submarinePos = Submarine == null ? Vector2.Zero : Submarine.DrawPosition; + + //calculate where the surface should be based on the water volume + float top = rect.Y + submarinePos.Y; + float bottom = top - rect.Height; + + float drawSurface = surface + submarinePos.Y; + + Matrix transform = cam.Transform * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f; + + if (bottom > cam.WorldView.Y || top < cam.WorldView.Y - cam.WorldView.Height) return; + + if (!update) + { + // create the four corners of our triangle. + + Vector3[] corners = new Vector3[4]; + + corners[0] = new Vector3(rect.X, rect.Y, 0.0f); + corners[1] = new Vector3(rect.X + rect.Width, rect.Y, 0.0f); + + corners[2] = new Vector3(corners[1].X, rect.Y - rect.Height, 0.0f); + corners[3] = new Vector3(corners[0].X, corners[2].Y, 0.0f); + + Vector2[] uvCoords = new Vector2[4]; + for (int i = 0; i < 4; i++) + { + corners[i] += new Vector3(submarinePos, 0.0f); + uvCoords[i] = Vector2.Transform(new Vector2(corners[i].X, -corners[i].Y), transform); + } + + renderer.vertices[renderer.PositionInBuffer] = new VertexPositionTexture(corners[0], uvCoords[0]); + renderer.vertices[renderer.PositionInBuffer + 1] = new VertexPositionTexture(corners[1], uvCoords[1]); + renderer.vertices[renderer.PositionInBuffer + 2] = new VertexPositionTexture(corners[2], uvCoords[2]); + + renderer.vertices[renderer.PositionInBuffer + 3] = new VertexPositionTexture(corners[0], uvCoords[0]); + renderer.vertices[renderer.PositionInBuffer + 4] = new VertexPositionTexture(corners[2], uvCoords[2]); + renderer.vertices[renderer.PositionInBuffer + 5] = new VertexPositionTexture(corners[3], uvCoords[3]); + + renderer.PositionInBuffer += 6; + + return; + } + + float x = rect.X + Submarine.DrawPosition.X; + int start = (int)Math.Floor((cam.WorldView.X - x) / WaveWidth); + start = Math.Max(start, 0); + + int end = (waveY.Length - 1) + - (int)Math.Floor((float)((x + rect.Width) - (cam.WorldView.X + cam.WorldView.Width)) / WaveWidth); + end = Math.Min(end, waveY.Length - 1); + + x += start * WaveWidth; + + for (int i = start; i < end; i++) + { + if (renderer.PositionInBuffer > renderer.vertices.Length - 6) return; + + Vector3[] corners = new Vector3[4]; + + corners[0] = new Vector3(x, top, 0.0f); + corners[3] = new Vector3(corners[0].X, drawSurface + waveY[i], 0.0f); + + //skip adjacent "water rects" if the surface of the water is roughly at the same position + int width = WaveWidth; + while (i < end - 1 && Math.Abs(waveY[i + 1] - waveY[i]) < 1.0f) + { + width += WaveWidth; + i++; + } + + corners[1] = new Vector3(x + width, top, 0.0f); + corners[2] = new Vector3(corners[1].X, drawSurface + waveY[i + 1], 0.0f); + + Vector2[] uvCoords = new Vector2[4]; + for (int n = 0; n < 4; n++) + { + uvCoords[n] = Vector2.Transform(new Vector2(corners[n].X, -corners[n].Y), transform); + } + + renderer.vertices[renderer.PositionInBuffer] = new VertexPositionTexture(corners[0], uvCoords[0]); + renderer.vertices[renderer.PositionInBuffer + 1] = new VertexPositionTexture(corners[1], uvCoords[1]); + renderer.vertices[renderer.PositionInBuffer + 2] = new VertexPositionTexture(corners[2], uvCoords[2]); + + renderer.vertices[renderer.PositionInBuffer + 3] = new VertexPositionTexture(corners[0], uvCoords[0]); + renderer.vertices[renderer.PositionInBuffer + 4] = new VertexPositionTexture(corners[2], uvCoords[2]); + renderer.vertices[renderer.PositionInBuffer + 5] = new VertexPositionTexture(corners[3], uvCoords[3]); + + renderer.PositionInBuffer += 6; + + x += width; + } + + } + + + public override XElement Save(XElement parentElement) + { + XElement element = new XElement("Hull"); + + element.Add + ( + new XAttribute("ID", ID), + new XAttribute("rect", + (int)(rect.X - Submarine.HiddenSubPosition.X) + "," + + (int)(rect.Y - Submarine.HiddenSubPosition.Y) + "," + + rect.Width + "," + rect.Height), + new XAttribute("water", volume) + ); + + parentElement.Add(element); + + return element; + } + } +} diff --git a/BarotraumaClient/Source/Map/Levels/Level.cs b/BarotraumaClient/Source/Map/Levels/Level.cs new file mode 100644 index 000000000..a3cd883fb --- /dev/null +++ b/BarotraumaClient/Source/Map/Levels/Level.cs @@ -0,0 +1,59 @@ +using FarseerPhysics; +using FarseerPhysics.Common; +using FarseerPhysics.Dynamics; +using FarseerPhysics.Factories; +using Lidgren.Network; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Linq; +using System.Collections.Generic; +using System.Diagnostics; +using Voronoi2; +using Barotrauma.RuinGeneration; + +namespace Barotrauma +{ + partial class Level + { + private LevelRenderer renderer; + + public void DrawFront(SpriteBatch spriteBatch) + { + if (renderer == null) return; + renderer.Draw(spriteBatch); + + if (GameMain.DebugDraw) + { + foreach (InterestingPosition pos in positionsOfInterest) + { + Color color = Color.Yellow; + if (pos.PositionType == PositionType.Cave) + { + color = Color.DarkOrange; + } + else if (pos.PositionType == PositionType.Ruin) + { + color = Color.LightGray; + } + + + GUI.DrawRectangle(spriteBatch, new Vector2(pos.Position.X - 15.0f, -pos.Position.Y - 15.0f), new Vector2(30.0f, 30.0f), color, true); + } + } + } + + public void DrawBack(GraphicsDevice graphics, SpriteBatch spriteBatch, Camera cam, BackgroundCreatureManager backgroundSpriteManager = null) + { + float brightness = MathHelper.Clamp(50.0f + (cam.Position.Y - Size.Y) / 2000.0f, 10.0f, 40.0f); + + float avgValue = (backgroundColor.R + backgroundColor.G + backgroundColor.G) / 3; + GameMain.LightManager.AmbientLight = new Color(backgroundColor * (brightness / avgValue), 1.0f); + + graphics.Clear(backgroundColor); + + if (renderer == null) return; + renderer.DrawBackground(spriteBatch, cam, backgroundSpriteManager); + } + } +} diff --git a/BarotraumaShared/Source/Map/Levels/LevelRenderer.cs b/BarotraumaClient/Source/Map/Levels/LevelRenderer.cs similarity index 100% rename from BarotraumaShared/Source/Map/Levels/LevelRenderer.cs rename to BarotraumaClient/Source/Map/Levels/LevelRenderer.cs diff --git a/BarotraumaShared/Source/Map/Levels/WaterRenderer.cs b/BarotraumaClient/Source/Map/Levels/WaterRenderer.cs similarity index 100% rename from BarotraumaShared/Source/Map/Levels/WaterRenderer.cs rename to BarotraumaClient/Source/Map/Levels/WaterRenderer.cs diff --git a/BarotraumaShared/Source/Map/Lights/ConvexHull.cs b/BarotraumaClient/Source/Map/Lights/ConvexHull.cs similarity index 100% rename from BarotraumaShared/Source/Map/Lights/ConvexHull.cs rename to BarotraumaClient/Source/Map/Lights/ConvexHull.cs diff --git a/BarotraumaShared/Source/Map/Lights/LightManager.cs b/BarotraumaClient/Source/Map/Lights/LightManager.cs similarity index 100% rename from BarotraumaShared/Source/Map/Lights/LightManager.cs rename to BarotraumaClient/Source/Map/Lights/LightManager.cs diff --git a/BarotraumaShared/Source/Map/Lights/LightSource.cs b/BarotraumaClient/Source/Map/Lights/LightSource.cs similarity index 100% rename from BarotraumaShared/Source/Map/Lights/LightSource.cs rename to BarotraumaClient/Source/Map/Lights/LightSource.cs diff --git a/BarotraumaClient/Source/Map/LinkedSubmarine.cs b/BarotraumaClient/Source/Map/LinkedSubmarine.cs new file mode 100644 index 000000000..1a42db8dc --- /dev/null +++ b/BarotraumaClient/Source/Map/LinkedSubmarine.cs @@ -0,0 +1,234 @@ +using Barotrauma.Items.Components; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace Barotrauma +{ + partial class LinkedSubmarine : MapEntity + { + public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true) + { + if (!editing || wallVertices == null) return; + + Color color = (isHighlighted) ? Color.Orange : Color.Green; + if (IsSelected) color = Color.Red; + + Vector2 pos = Position; + + for (int i = 0; i < wallVertices.Count; i++) + { + Vector2 startPos = wallVertices[i] + pos; + startPos.Y = -startPos.Y; + + Vector2 endPos = wallVertices[(i + 1) % wallVertices.Count] + pos; + endPos.Y = -endPos.Y; + + GUI.DrawLine(spriteBatch, + startPos, + endPos, + color, 0.0f, 5); + } + + pos.Y = -pos.Y; + GUI.DrawLine(spriteBatch, pos + Vector2.UnitY * 50.0f, pos - Vector2.UnitY * 50.0f, color, 0.0f, 5); + GUI.DrawLine(spriteBatch, pos + Vector2.UnitX * 50.0f, pos - Vector2.UnitX * 50.0f, color, 0.0f, 5); + + Rectangle drawRect = rect; + drawRect.Y = -rect.Y; + GUI.DrawRectangle(spriteBatch, drawRect, Color.Red, true); + + foreach (MapEntity e in linkedTo) + { + GUI.DrawLine(spriteBatch, + new Vector2(WorldPosition.X, -WorldPosition.Y), + new Vector2(e.WorldPosition.X, -e.WorldPosition.Y), + Color.Red * 0.3f); + } + } + + public override void UpdateEditing(Camera cam) + { + if (editingHUD == null || editingHUD.UserData as LinkedSubmarine != this) + { + editingHUD = CreateEditingHUD(); + } + + editingHUD.Update((float)Timing.Step); + + if (!PlayerInput.LeftButtonClicked() || !PlayerInput.KeyDown(Keys.Space)) return; + + Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition); + + foreach (MapEntity entity in mapEntityList) + { + if (entity == this || !entity.IsHighlighted || !(entity is Item) || !entity.IsMouseOn(position)) continue; + if (((Item)entity).GetComponent() == null) continue; + if (linkedTo.Contains(entity)) + { + linkedTo.Remove(entity); + } + else + { + linkedTo.Add(entity); + } + } + } + + public override void DrawEditing(SpriteBatch spriteBatch, Camera cam) + { + if (editingHUD == null) return; + + editingHUD.Draw(spriteBatch); + } + + + private GUIComponent CreateEditingHUD(bool inGame = false) + { + int width = 450; + int x = GameMain.GraphicsWidth / 2 - width / 2, y = 10; + + editingHUD = new GUIFrame(new Rectangle(x, y, width, 100), ""); + editingHUD.Padding = new Vector4(10, 10, 0, 0); + editingHUD.UserData = this; + + new GUITextBlock(new Rectangle(0, 0, 100, 20), "Linked submarine", "", + Alignment.TopLeft, Alignment.TopLeft, editingHUD, false, GUI.LargeFont); + + var pathBox = new GUITextBox(new Rectangle(10, 30, 300, 20), "", editingHUD); + pathBox.Font = GUI.SmallFont; + pathBox.Text = filePath; + + var reloadButton = new GUIButton(new Rectangle(320, 30, 80, 20), "Refresh", "", editingHUD); + reloadButton.OnClicked = Reload; + reloadButton.UserData = pathBox; + + reloadButton.ToolTip = "Reload the linked submarine from the specified file"; + + y += 20; + + if (!inGame) + { + new GUITextBlock(new Rectangle(0, 0, 0, 20), "Hold space to link to a docking port", + "", Alignment.TopRight, Alignment.TopRight, editingHUD, false, GUI.SmallFont); + y += 25; + + } + return editingHUD; + } + + private bool Reload(GUIButton button, object obj) + { + var pathBox = obj as GUITextBox; + + if (!File.Exists(pathBox.Text)) + { + new GUIMessageBox("Error", "Submarine file \"" + pathBox.Text + "\" not found!"); + pathBox.Flash(Color.Red); + pathBox.Text = filePath; + return false; + } + + XDocument doc = Submarine.OpenFile(pathBox.Text); + if (doc == null || doc.Root == null) return false; + + pathBox.Flash(Color.Green); + + GenerateWallVertices(doc.Root); + saveElement = doc.Root; + saveElement.Name = "LinkedSubmarine"; + + filePath = pathBox.Text; + + return true; + } + + public override XElement Save(XElement parentElement) + { + XElement saveElement = null; + + if (sub == null) + { + if (this.saveElement == null) + { + var doc = Submarine.OpenFile(filePath); + saveElement = doc.Root; + + saveElement.Name = "LinkedSubmarine"; + + saveElement.Add(new XAttribute("filepath", filePath)); + } + else + { + saveElement = this.saveElement; + } + + if (saveElement.Attribute("pos") != null) saveElement.Attribute("pos").Remove(); + saveElement.Add(new XAttribute("pos", ToolBox.Vector2ToString(Position - Submarine.HiddenSubPosition))); + + + + var linkedPort = linkedTo.FirstOrDefault(lt => (lt is Item) && ((Item)lt).GetComponent() != null); + if (linkedPort != null) + { + if (saveElement.Attribute("linkedto") != null) saveElement.Attribute("linkedto").Remove(); + + saveElement.Add(new XAttribute("linkedto", linkedPort.ID)); + } + } + else + { + + saveElement = new XElement("LinkedSubmarine"); + + + sub.SaveToXElement(saveElement); + } + + if (sub != null) + { + bool leaveBehind = false; + if (!sub.DockedTo.Contains(Submarine.MainSub)) + { + System.Diagnostics.Debug.Assert(Submarine.MainSub.AtEndPosition || Submarine.MainSub.AtStartPosition); + if (Submarine.MainSub.AtEndPosition) + { + leaveBehind = sub.AtEndPosition != Submarine.MainSub.AtEndPosition; + } + else + { + leaveBehind = sub.AtStartPosition != Submarine.MainSub.AtStartPosition; + } + } + + + if (leaveBehind) + { + saveElement.SetAttributeValue("location", Level.Loaded.Seed); + saveElement.SetAttributeValue("worldpos", ToolBox.Vector2ToString(sub.SubBody.Position)); + + } + else + { + if (saveElement.Attribute("location") != null) saveElement.Attribute("location").Remove(); + if (saveElement.Attribute("worldpos") != null) saveElement.Attribute("worldpos").Remove(); + } + + saveElement.SetAttributeValue("pos", ToolBox.Vector2ToString(Position - Submarine.HiddenSubPosition)); + } + + + + parentElement.Add(saveElement); + + return saveElement; + } + } +} diff --git a/BarotraumaClient/Source/Map/MapEntity.cs b/BarotraumaClient/Source/Map/MapEntity.cs index 28a7f85cc..3a4b59fff 100644 --- a/BarotraumaClient/Source/Map/MapEntity.cs +++ b/BarotraumaClient/Source/Map/MapEntity.cs @@ -12,7 +12,7 @@ using Barotrauma.Items.Components; namespace Barotrauma { - abstract partial class MapEntity + abstract partial class MapEntity : Entity { protected static Vector2 selectionPos = Vector2.Zero; protected static Vector2 selectionSize = Vector2.Zero; diff --git a/BarotraumaClient/Source/Map/Structure.cs b/BarotraumaClient/Source/Map/Structure.cs index 354ef7e73..2e44d22dc 100644 --- a/BarotraumaClient/Source/Map/Structure.cs +++ b/BarotraumaClient/Source/Map/Structure.cs @@ -14,8 +14,62 @@ using Barotrauma.Lights; namespace Barotrauma { + partial class WallSection + { + public ConvexHull hull; + } + partial class Structure : MapEntity, IDamageable, IServerSerializable { + List convexHulls; + + private void GenerateConvexHull() + { + // If not null and not empty , remove the hulls from the system + if (convexHulls != null && convexHulls.Any()) + convexHulls.ForEach(x => x.Remove()); + + // list all of hulls for this structure + convexHulls = new List(); + + var mergedSections = new List(); + foreach (var section in sections) + { + if (mergedSections.Count > 5) + { + mergedSections.Add(section); + GenerateMergedHull(mergedSections); + continue; + } + + // if there is a gap and we have sections to merge, do it. + if (section.gap != null) + { + GenerateMergedHull(mergedSections); + } + else + { + mergedSections.Add(section); + } + } + + // take care of any leftover pieces + if (mergedSections.Count > 0) + { + GenerateMergedHull(mergedSections); + } + } + + private void GenerateMergedHull(List mergedSections) + { + if (!mergedSections.Any()) return; + Rectangle mergedRect = GenerateMergedRect(mergedSections); + + var h = new ConvexHull(CalculateExtremes(mergedRect), Color.Black, this); + mergedSections.ForEach(x => x.hull = h); + convexHulls.Add(h); + mergedSections.Clear(); + } public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true) { diff --git a/BarotraumaClient/Source/Networking/BanList.cs b/BarotraumaClient/Source/Networking/BanList.cs new file mode 100644 index 000000000..fc43b01bc --- /dev/null +++ b/BarotraumaClient/Source/Networking/BanList.cs @@ -0,0 +1,86 @@ +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace Barotrauma.Networking +{ + partial class BanList + { + private GUIComponent banFrame; + + public GUIComponent BanFrame + { + get { return banFrame; } + } + + public GUIComponent CreateBanFrame(GUIComponent parent) + { + banFrame = new GUIListBox(new Rectangle(0, 0, 0, 0), "", parent); + + foreach (BannedPlayer bannedPlayer in bannedPlayers) + { + GUITextBlock textBlock = new GUITextBlock( + new Rectangle(0, 0, 0, 25), + bannedPlayer.IP + " (" + bannedPlayer.Name + ")", + "", + Alignment.Left, Alignment.Left, banFrame); + textBlock.Padding = new Vector4(10.0f, 10.0f, 0.0f, 0.0f); + textBlock.UserData = banFrame; + + var removeButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Remove", Alignment.Right | Alignment.CenterY, "", textBlock); + removeButton.UserData = bannedPlayer; + removeButton.OnClicked = RemoveBan; + if (bannedPlayer.IP.IndexOf(".x") <= -1) + { + var rangeBanButton = new GUIButton(new Rectangle(-100, 0, 100, 20), "Ban range", Alignment.Right | Alignment.CenterY, "", textBlock); + rangeBanButton.UserData = bannedPlayer; + rangeBanButton.OnClicked = RangeBan; + } + } + + return banFrame; + } + + private bool RemoveBan(GUIButton button, object obj) + { + BannedPlayer banned = obj as BannedPlayer; + if (banned == null) return false; + + RemoveBan(banned); + + if (banFrame != null) + { + banFrame.Parent.RemoveChild(banFrame); + CreateBanFrame(banFrame.Parent); + } + + return true; + } + + private bool RangeBan(GUIButton button, object obj) + { + BannedPlayer banned = obj as BannedPlayer; + if (banned == null) return false; + + RangeBan(banned); + + if (banFrame != null) + { + banFrame.Parent.RemoveChild(banFrame); + CreateBanFrame(banFrame.Parent); + } + + return true; + } + + private bool CloseFrame(GUIButton button, object obj) + { + banFrame = null; + + return true; + } + } +} diff --git a/BarotraumaClient/Source/Networking/GameServer.cs b/BarotraumaClient/Source/Networking/GameServer.cs index 7d6ac3bd8..e804fc660 100644 --- a/BarotraumaClient/Source/Networking/GameServer.cs +++ b/BarotraumaClient/Source/Networking/GameServer.cs @@ -12,6 +12,8 @@ namespace Barotrauma.Networking { partial class GameServer : NetworkMember { + private NetStats netStats; + private GUIButton showLogButton; private GUIScrollBar clientListScrollBar; @@ -54,6 +56,13 @@ namespace Barotrauma.Networking //---------------------------------------- } + public override void AddToGUIUpdateList() + { + if (started) base.AddToGUIUpdateList(); + + if (settingsFrame != null) settingsFrame.AddToGUIUpdateList(); + if (log.LogFrame != null) log.LogFrame.AddToGUIUpdateList(); + } public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch) { diff --git a/BarotraumaClient/Source/Networking/GameServerSettings.cs b/BarotraumaClient/Source/Networking/GameServerSettings.cs new file mode 100644 index 000000000..e6bab34d4 --- /dev/null +++ b/BarotraumaClient/Source/Networking/GameServerSettings.cs @@ -0,0 +1,534 @@ +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Xml; +using System.Xml.Linq; + +namespace Barotrauma.Networking +{ + partial class GameServer : NetworkMember, IPropertyObject + { + private GUIFrame settingsFrame; + private GUIFrame[] settingsTabs; + private int settingsTabIndex; + + + private void CreateSettingsFrame() + { + settingsFrame = new GUIFrame(new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.Black * 0.5f, null); + + GUIFrame innerFrame = new GUIFrame(new Rectangle(0, 0, 400, 430), null, Alignment.Center, "", settingsFrame); + innerFrame.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f); + + new GUITextBlock(new Rectangle(0, -5, 0, 20), "Settings", "", innerFrame, GUI.LargeFont); + + string[] tabNames = { "Rounds", "Server", "Banlist", "Whitelist" }; + settingsTabs = new GUIFrame[tabNames.Length]; + for (int i = 0; i < tabNames.Length; i++) + { + settingsTabs[i] = new GUIFrame(new Rectangle(0, 15, 0, innerFrame.Rect.Height - 120), null, Alignment.Center, "InnerFrame", innerFrame); + settingsTabs[i].Padding = new Vector4(40.0f, 20.0f, 40.0f, 40.0f); + + var tabButton = new GUIButton(new Rectangle(85 * i, 35, 80, 20), tabNames[i], "", innerFrame); + tabButton.UserData = i; + tabButton.OnClicked = SelectSettingsTab; + } + + settingsTabs[2].Padding = Vector4.Zero; + + SelectSettingsTab(null, 0); + + var closeButton = new GUIButton(new Rectangle(10, 0, 100, 20), "Close", Alignment.BottomRight, "", innerFrame); + closeButton.OnClicked = ToggleSettingsFrame; + + //-------------------------------------------------------------------------------- + // game settings + //-------------------------------------------------------------------------------- + + int y = 0; + + settingsTabs[0].Padding = new Vector4(40.0f, 5.0f, 40.0f, 40.0f); + + new GUITextBlock(new Rectangle(0, y, 100, 20), "Submarine selection:", "", settingsTabs[0]); + var selectionFrame = new GUIFrame(new Rectangle(0, y + 20, 300, 20), null, settingsTabs[0]); + for (int i = 0; i < 3; i++) + { + var selectionTick = new GUITickBox(new Rectangle(i * 100, 0, 20, 20), ((SelectionMode)i).ToString(), Alignment.Left, selectionFrame); + selectionTick.Selected = i == (int)subSelectionMode; + selectionTick.OnSelected = SwitchSubSelection; + selectionTick.UserData = (SelectionMode)i; + } + + y += 45; + + new GUITextBlock(new Rectangle(0, y, 100, 20), "Mode selection:", "", settingsTabs[0]); + selectionFrame = new GUIFrame(new Rectangle(0, y + 20, 300, 20), null, settingsTabs[0]); + for (int i = 0; i < 3; i++) + { + var selectionTick = new GUITickBox(new Rectangle(i * 100, 0, 20, 20), ((SelectionMode)i).ToString(), Alignment.Left, selectionFrame); + selectionTick.Selected = i == (int)modeSelectionMode; + selectionTick.OnSelected = SwitchModeSelection; + selectionTick.UserData = (SelectionMode)i; + } + + y += 60; + + var endBox = new GUITickBox(new Rectangle(0, y, 20, 20), "End round when destination reached", Alignment.Left, settingsTabs[0]); + endBox.Selected = EndRoundAtLevelEnd; + endBox.OnSelected = (GUITickBox) => { EndRoundAtLevelEnd = GUITickBox.Selected; return true; }; + + y += 25; + + var endVoteBox = new GUITickBox(new Rectangle(0, y, 20, 20), "End round by voting", Alignment.Left, settingsTabs[0]); + endVoteBox.Selected = Voting.AllowEndVoting; + endVoteBox.OnSelected = (GUITickBox) => + { + Voting.AllowEndVoting = !Voting.AllowEndVoting; + GameMain.Server.UpdateVoteStatus(); + return true; + }; + + + var votesRequiredText = new GUITextBlock(new Rectangle(20, y + 15, 20, 20), "Votes required: 50 %", "", settingsTabs[0], GUI.SmallFont); + + var votesRequiredSlider = new GUIScrollBar(new Rectangle(150, y + 22, 100, 15), "", 0.1f, settingsTabs[0]); + votesRequiredSlider.UserData = votesRequiredText; + votesRequiredSlider.Step = 0.2f; + votesRequiredSlider.BarScroll = (EndVoteRequiredRatio - 0.5f) * 2.0f; + votesRequiredSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) => + { + GUITextBlock voteText = scrollBar.UserData as GUITextBlock; + + EndVoteRequiredRatio = barScroll / 2.0f + 0.5f; + voteText.Text = "Votes required: " + (int)MathUtils.Round(EndVoteRequiredRatio * 100.0f, 10.0f) + " %"; + return true; + }; + votesRequiredSlider.OnMoved(votesRequiredSlider, votesRequiredSlider.BarScroll); + + y += 35; + + var respawnBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Allow respawning", Alignment.Left, settingsTabs[0]); + respawnBox.Selected = AllowRespawn; + respawnBox.OnSelected = (GUITickBox) => + { + AllowRespawn = !AllowRespawn; + return true; + }; + + + var respawnIntervalText = new GUITextBlock(new Rectangle(20, y + 13, 20, 20), "Respawn interval", "", settingsTabs[0], GUI.SmallFont); + + var respawnIntervalSlider = new GUIScrollBar(new Rectangle(150, y + 20, 100, 15), "", 0.1f, settingsTabs[0]); + respawnIntervalSlider.UserData = respawnIntervalText; + respawnIntervalSlider.Step = 0.05f; + respawnIntervalSlider.BarScroll = RespawnInterval / 600.0f; + respawnIntervalSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) => + { + GUITextBlock text = scrollBar.UserData as GUITextBlock; + + RespawnInterval = Math.Max(barScroll * 600.0f, 10.0f); + text.Text = "Interval: " + ToolBox.SecondsToReadableTime(RespawnInterval); + return true; + }; + respawnIntervalSlider.OnMoved(respawnIntervalSlider, respawnIntervalSlider.BarScroll); + + y += 35; + + var minRespawnText = new GUITextBlock(new Rectangle(0, y, 200, 20), "Minimum players to respawn", "", settingsTabs[0]); + minRespawnText.ToolTip = "What percentage of players has to be dead/spectating until a respawn shuttle is dispatched"; + + var minRespawnSlider = new GUIScrollBar(new Rectangle(150, y + 20, 100, 15), "", 0.1f, settingsTabs[0]); + minRespawnSlider.ToolTip = minRespawnText.ToolTip; + minRespawnSlider.UserData = minRespawnText; + minRespawnSlider.Step = 0.1f; + minRespawnSlider.BarScroll = MinRespawnRatio; + minRespawnSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) => + { + GUITextBlock txt = scrollBar.UserData as GUITextBlock; + + MinRespawnRatio = barScroll; + txt.Text = "Minimum players to respawn: " + (int)MathUtils.Round(MinRespawnRatio * 100.0f, 10.0f) + " %"; + return true; + }; + minRespawnSlider.OnMoved(minRespawnSlider, MinRespawnRatio); + + y += 30; + + var respawnDurationText = new GUITextBlock(new Rectangle(0, y, 200, 20), "Duration of respawn transport", "", settingsTabs[0]); + respawnDurationText.ToolTip = "The amount of time respawned players have to navigate the respawn shuttle to the main submarine. " + + "After the duration expires, the shuttle will automatically head back out of the level."; + + var respawnDurationSlider = new GUIScrollBar(new Rectangle(150, y + 20, 100, 15), "", 0.1f, settingsTabs[0]); + respawnDurationSlider.ToolTip = minRespawnText.ToolTip; + respawnDurationSlider.UserData = respawnDurationText; + respawnDurationSlider.Step = 0.1f; + respawnDurationSlider.BarScroll = MaxTransportTime <= 0.0f ? 1.0f : (MaxTransportTime - 60.0f) / 600.0f; + respawnDurationSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) => + { + GUITextBlock txt = scrollBar.UserData as GUITextBlock; + + if (barScroll == 1.0f) + { + MaxTransportTime = 0; + txt.Text = "Duration of respawn transport: unlimited"; + } + else + { + MaxTransportTime = barScroll * 600.0f + 60.0f; + txt.Text = "Duration of respawn transport: " + ToolBox.SecondsToReadableTime(MaxTransportTime); + } + + return true; + }; + respawnDurationSlider.OnMoved(respawnDurationSlider, respawnDurationSlider.BarScroll); + + y += 35; + + var monsterButton = new GUIButton(new Rectangle(0, y, 130, 20), "Monster Spawns", "", settingsTabs[0]); + monsterButton.Enabled = !GameStarted; + var monsterFrame = new GUIListBox(new Rectangle(-290, 60, 280, 250), "", settingsTabs[0]); + monsterFrame.Visible = false; + monsterButton.UserData = monsterFrame; + monsterButton.OnClicked = (button, obj) => + { + if (gameStarted) + { + ((GUIComponent)obj).Visible = false; + button.Enabled = false; + return true; + } + ((GUIComponent)obj).Visible = !((GUIComponent)obj).Visible; + return true; + }; + List monsterNames = monsterEnabled.Keys.ToList(); + foreach (string s in monsterNames) + { + GUITextBlock textBlock = new GUITextBlock( + new Rectangle(0, 0, 260, 25), + s, + "", + Alignment.Left, Alignment.Left, monsterFrame); + textBlock.Padding = new Vector4(35.0f, 3.0f, 0.0f, 0.0f); + textBlock.UserData = monsterFrame; + textBlock.CanBeFocused = false; + + var monsterEnabledBox = new GUITickBox(new Rectangle(-25, 0, 20, 20), "", Alignment.Left, textBlock); + monsterEnabledBox.Selected = monsterEnabled[s]; + monsterEnabledBox.OnSelected = (GUITickBox) => + { + if (gameStarted) + { + monsterFrame.Visible = false; + monsterButton.Enabled = false; + return true; + } + monsterEnabled[s] = !monsterEnabled[s]; + return true; + }; + } + + var cargoButton = new GUIButton(new Rectangle(160, y, 130, 20), "Additional Cargo", "", settingsTabs[0]); + cargoButton.Enabled = !GameStarted; + + var cargoFrame = new GUIListBox(new Rectangle(300, 60, 280, 250), "", settingsTabs[0]); + cargoFrame.Visible = false; + cargoButton.UserData = cargoFrame; + cargoButton.OnClicked = (button, obj) => + { + if (gameStarted) + { + ((GUIComponent)obj).Visible = false; + button.Enabled = false; + return true; + } + ((GUIComponent)obj).Visible = !((GUIComponent)obj).Visible; + return true; + }; + + + foreach (MapEntityPrefab pf in MapEntityPrefab.list) + { + if (!(pf is ItemPrefab) || (pf.Price <= 0.0f && !pf.tags.Contains("smallitem"))) continue; + + GUITextBlock textBlock = new GUITextBlock( + new Rectangle(0, 0, 260, 25), + pf.Name, "", + Alignment.Left, Alignment.CenterLeft, cargoFrame, false, GUI.SmallFont); + textBlock.Padding = new Vector4(40.0f, 3.0f, 0.0f, 0.0f); + textBlock.UserData = cargoFrame; + textBlock.CanBeFocused = false; + + if (pf.sprite != null) + { + float scale = Math.Min(Math.Min(30.0f / pf.sprite.SourceRect.Width, 30.0f / pf.sprite.SourceRect.Height), 1.0f); + GUIImage img = new GUIImage(new Rectangle(-20 - (int)(pf.sprite.SourceRect.Width * scale * 0.5f), 12 - (int)(pf.sprite.SourceRect.Height * scale * 0.5f), 40, 40), pf.sprite, Alignment.Left, textBlock); + img.Color = pf.SpriteColor; + img.Scale = scale; + } + + int cargoVal = 0; + extraCargo.TryGetValue(pf.Name, out cargoVal); + var countText = new GUITextBlock( + new Rectangle(160, 0, 55, 25), + cargoVal.ToString(), + "", + Alignment.Left, Alignment.Center, textBlock); + + var incButton = new GUIButton(new Rectangle(200, 5, 15, 15), ">", "", textBlock); + incButton.UserData = countText; + incButton.OnClicked = (button, obj) => + { + int val; + if (extraCargo.TryGetValue(pf.Name, out val)) + { + extraCargo[pf.Name]++; val = extraCargo[pf.Name]; + } + else + { + extraCargo.Add(pf.Name, 1); val = 1; + } + ((GUITextBlock)obj).Text = val.ToString(); + ((GUITextBlock)obj).SetTextPos(); + return true; + }; + + var decButton = new GUIButton(new Rectangle(160, 5, 15, 15), "<", "", textBlock); + decButton.UserData = countText; + decButton.OnClicked = (button, obj) => + { + int val; + if (extraCargo.TryGetValue(pf.Name, out val)) + { + extraCargo[pf.Name]--; + val = extraCargo[pf.Name]; + if (val <= 0) + { + extraCargo.Remove(pf.Name); + val = 0; + } + ((GUITextBlock)obj).Text = val.ToString(); + ((GUITextBlock)obj).SetTextPos(); + } + + return true; + }; + } + + + //-------------------------------------------------------------------------------- + // server settings + //-------------------------------------------------------------------------------- + + y = 0; + + + var startIntervalText = new GUITextBlock(new Rectangle(-10, y, 100, 20), "Autorestart delay", "", settingsTabs[1]); + var startIntervalSlider = new GUIScrollBar(new Rectangle(10, y + 22, 100, 15), "", 0.1f, settingsTabs[1]); + startIntervalSlider.UserData = startIntervalText; + startIntervalSlider.Step = 0.05f; + startIntervalSlider.BarScroll = AutoRestartInterval / 300.0f; + startIntervalSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) => + { + GUITextBlock text = scrollBar.UserData as GUITextBlock; + + AutoRestartInterval = Math.Max(barScroll * 300.0f, 10.0f); + + text.Text = "Autorestart delay: " + ToolBox.SecondsToReadableTime(AutoRestartInterval); + return true; + }; + startIntervalSlider.OnMoved(startIntervalSlider, startIntervalSlider.BarScroll); + + y += 45; + + var allowSpecBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Allow spectating", Alignment.Left, settingsTabs[1]); + allowSpecBox.Selected = AllowSpectating; + allowSpecBox.OnSelected = (GUITickBox) => + { + AllowSpectating = GUITickBox.Selected; + return true; + }; + + y += 40; + + var voteKickBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Allow vote kicking", Alignment.Left, settingsTabs[1]); + voteKickBox.Selected = Voting.AllowVoteKick; + voteKickBox.OnSelected = (GUITickBox) => + { + Voting.AllowVoteKick = !Voting.AllowVoteKick; + GameMain.Server.UpdateVoteStatus(); + return true; + }; + + var kickVotesRequiredText = new GUITextBlock(new Rectangle(20, y + 20, 20, 20), "Votes required: 50 %", "", settingsTabs[1], GUI.SmallFont); + + var kickVoteSlider = new GUIScrollBar(new Rectangle(150, y + 22, 100, 15), "", 0.1f, settingsTabs[1]); + kickVoteSlider.UserData = kickVotesRequiredText; + kickVoteSlider.Step = 0.2f; + kickVoteSlider.BarScroll = (KickVoteRequiredRatio - 0.5f) * 2.0f; + kickVoteSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) => + { + GUITextBlock voteText = scrollBar.UserData as GUITextBlock; + + KickVoteRequiredRatio = barScroll / 2.0f + 0.5f; + voteText.Text = "Votes required: " + (int)MathUtils.Round(KickVoteRequiredRatio * 100.0f, 10.0f) + " %"; + return true; + }; + kickVoteSlider.OnMoved(kickVoteSlider, kickVoteSlider.BarScroll); + + y += 45; + + var shareSubsBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Share submarine files with players", Alignment.Left, settingsTabs[1]); + shareSubsBox.Selected = AllowFileTransfers; + shareSubsBox.OnSelected = (GUITickBox) => + { + AllowFileTransfers = GUITickBox.Selected; + return true; + }; + + y += 40; + + var randomizeLevelBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Randomize level seed between rounds", Alignment.Left, settingsTabs[1]); + randomizeLevelBox.Selected = RandomizeSeed; + randomizeLevelBox.OnSelected = (GUITickBox) => + { + RandomizeSeed = GUITickBox.Selected; + return true; + }; + + y += 40; + + var saveLogsBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Save server logs", Alignment.Left, settingsTabs[1]); + saveLogsBox.Selected = SaveServerLogs; + saveLogsBox.OnSelected = (GUITickBox) => + { + SaveServerLogs = GUITickBox.Selected; + showLogButton.Visible = SaveServerLogs; + return true; + }; + + + //-------------------------------------------------------------------------------- + // banlist + //-------------------------------------------------------------------------------- + + + banList.CreateBanFrame(settingsTabs[2]); + + //-------------------------------------------------------------------------------- + // whitelist + //-------------------------------------------------------------------------------- + + whitelist.CreateWhiteListFrame(settingsTabs[3]); + + } + + + private bool SwitchSubSelection(GUITickBox tickBox) + { + subSelectionMode = (SelectionMode)tickBox.UserData; + + foreach (GUIComponent otherTickBox in tickBox.Parent.children) + { + if (otherTickBox == tickBox) continue; + ((GUITickBox)otherTickBox).Selected = false; + } + + Voting.AllowSubVoting = subSelectionMode == SelectionMode.Vote; + + if (subSelectionMode == SelectionMode.Random) + { + GameMain.NetLobbyScreen.SubList.Select(Rand.Range(0, GameMain.NetLobbyScreen.SubList.CountChildren)); + } + + return true; + } + + private bool SelectSettingsTab(GUIButton button, object obj) + { + settingsTabIndex = (int)obj; + + for (int i = 0; i < settingsTabs.Length; i++) + { + settingsTabs[i].Visible = i == settingsTabIndex; + } + + return true; + } + + private bool SwitchModeSelection(GUITickBox tickBox) + { + modeSelectionMode = (SelectionMode)tickBox.UserData; + + foreach (GUIComponent otherTickBox in tickBox.Parent.children) + { + if (otherTickBox == tickBox) continue; + ((GUITickBox)otherTickBox).Selected = false; + } + + Voting.AllowModeVoting = modeSelectionMode == SelectionMode.Vote; + + if (modeSelectionMode == SelectionMode.Random) + { + GameMain.NetLobbyScreen.ModeList.Select(Rand.Range(0, GameMain.NetLobbyScreen.ModeList.CountChildren)); + } + + return true; + } + + + public bool ToggleSettingsFrame(GUIButton button, object obj) + { + if (settingsFrame == null) + { + CreateSettingsFrame(); + } + else + { + settingsFrame = null; + SaveSettings(); + } + + return false; + } + + public void ManagePlayersFrame(GUIFrame infoFrame) + { + GUIListBox cList = new GUIListBox(new Rectangle(0, 0, 0, 300), Color.White * 0.7f, "", infoFrame); + cList.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f); + //crewList.OnSelected = SelectCrewCharacter; + + foreach (Client c in ConnectedClients) + { + GUIFrame frame = new GUIFrame(new Rectangle(0, 0, 0, 40), Color.Transparent, null, cList); + frame.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f); + frame.Color = (c.inGame && c.Character != null && !c.Character.IsDead) ? Color.Gold * 0.2f : Color.Transparent; + frame.HoverColor = Color.LightGray * 0.5f; + frame.SelectedColor = Color.Gold * 0.5f; + + GUITextBlock textBlock = new GUITextBlock( + new Rectangle(40, 0, 0, 25), + c.name + " (" + c.Connection.RemoteEndPoint.Address.ToString() + ")", + Color.Transparent, Color.White, + Alignment.Left, Alignment.Left, + null, frame); + + var banButton = new GUIButton(new Rectangle(-110, 0, 100, 20), "Ban", Alignment.Right | Alignment.CenterY, "", frame); + banButton.UserData = c.name; + banButton.OnClicked = GameMain.NetLobbyScreen.BanPlayer; + + var rangebanButton = new GUIButton(new Rectangle(-220, 0, 100, 20), "Ban range", Alignment.Right | Alignment.CenterY, "", frame); + rangebanButton.UserData = c.name; + rangebanButton.OnClicked = GameMain.NetLobbyScreen.BanPlayerRange; + + var kickButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Kick", Alignment.Right | Alignment.CenterY, "", frame); + kickButton.UserData = c.name; + kickButton.OnClicked = GameMain.NetLobbyScreen.KickPlayer; + + textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f); + } + } + } +} diff --git a/BarotraumaShared/Source/Networking/NetStats.cs b/BarotraumaClient/Source/Networking/NetStats.cs similarity index 100% rename from BarotraumaShared/Source/Networking/NetStats.cs rename to BarotraumaClient/Source/Networking/NetStats.cs diff --git a/BarotraumaClient/Source/Networking/NetworkMember.cs b/BarotraumaClient/Source/Networking/NetworkMember.cs new file mode 100644 index 000000000..df6c5da68 --- /dev/null +++ b/BarotraumaClient/Source/Networking/NetworkMember.cs @@ -0,0 +1,149 @@ +using System; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using System.Collections.Generic; +using Lidgren.Network; +using Barotrauma.Items.Components; + +namespace Barotrauma.Networking +{ + abstract partial class NetworkMember + { + protected GUIFrame inGameHUD; + protected GUIListBox chatBox; + protected GUITextBox chatMsgBox; + + public GUIFrame InGameHUD + { + get { return inGameHUD; } + } + + private void InitProjSpecific() + { + inGameHUD = new GUIFrame(new Rectangle(0, 0, 0, 0), null, null); + inGameHUD.CanBeFocused = false; + + int width = (int)MathHelper.Clamp(GameMain.GraphicsWidth * 0.35f, 350, 500); + int height = (int)MathHelper.Clamp(GameMain.GraphicsHeight * 0.15f, 100, 200); + chatBox = new GUIListBox(new Rectangle( + GameMain.GraphicsWidth - 20 - width, + GameMain.GraphicsHeight - 40 - 25 - height, + width, height), + Color.White * 0.5f, "", inGameHUD); + chatBox.Padding = Vector4.Zero; + + chatMsgBox = new GUITextBox( + new Rectangle(chatBox.Rect.X, chatBox.Rect.Y + chatBox.Rect.Height + 20, chatBox.Rect.Width, 25), + Color.White * 0.5f, Color.Black, Alignment.TopLeft, Alignment.Left, "", inGameHUD); + chatMsgBox.Font = GUI.SmallFont; + chatMsgBox.MaxTextLength = ChatMessage.MaxLength; + chatMsgBox.Padding = Vector4.Zero; + chatMsgBox.OnEnterPressed = EnterChatMessage; + chatMsgBox.OnTextChanged = TypingChatMessage; + } + + public bool TypingChatMessage(GUITextBox textBox, string text) + { + string tempStr; + string command = ChatMessage.GetChatMessageCommand(text, out tempStr); + switch (command) + { + case "r": + case "radio": + textBox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Radio]; + break; + case "d": + case "dead": + textBox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Dead]; + break; + default: + textBox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Default]; + break; + } + + return true; + } + + public bool EnterChatMessage(GUITextBox textBox, string message) + { + textBox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Default]; + + if (string.IsNullOrWhiteSpace(message)) return false; + + if (this == GameMain.Server) + { + GameMain.Server.SendChatMessage(message, null, null); + } + else if (this == GameMain.Client) + { + GameMain.Client.SendChatMessage(message); + } + + if (textBox == chatMsgBox) textBox.Deselect(); + + return true; + } + + public virtual void AddToGUIUpdateList() + { + if (gameStarted && Screen.Selected == GameMain.GameScreen) + { + inGameHUD.AddToGUIUpdateList(); + } + } + + public virtual void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch) + { + if (!gameStarted || Screen.Selected != GameMain.GameScreen) return; + + GameMain.GameSession.CrewManager.Draw(spriteBatch); + + inGameHUD.Draw(spriteBatch); + + if (EndVoteCount > 0) + { + if (GameMain.NetworkMember.myCharacter == null) + { + GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - 180.0f, 40), + "Votes to end the round (y/n): " + EndVoteCount + "/" + (EndVoteMax - EndVoteCount), Color.White, null, 0, GUI.SmallFont); + } + else + { + GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - 140.0f, 40), + "Votes (y/n): " + EndVoteCount + "/" + (EndVoteMax - EndVoteCount), Color.White, null, 0, GUI.SmallFont); + } + } + + if (respawnManager != null) + { + string respawnInfo = ""; + + if (respawnManager.CurrentState == RespawnManager.State.Waiting && + respawnManager.CountdownStarted) + { + respawnInfo = respawnManager.RespawnTimer <= 0.0f ? "" : "Respawn Shuttle dispatching in " + ToolBox.SecondsToReadableTime(respawnManager.RespawnTimer); + + } + else if (respawnManager.CurrentState == RespawnManager.State.Transporting) + { + respawnInfo = respawnManager.TransportTimer <= 0.0f ? "" : "Shuttle leaving in " + ToolBox.SecondsToReadableTime(respawnManager.TransportTimer); + } + + if (!string.IsNullOrEmpty(respawnInfo)) + { + GUI.DrawString(spriteBatch, + new Vector2(120.0f, 10), + respawnInfo, Color.White, null, 0, GUI.SmallFont); + } + + } + } + + public virtual bool SelectCrewCharacter(Character character, GUIComponent crewFrame) + { + return false; + } + } +} diff --git a/BarotraumaClient/Source/Networking/ServerLog.cs b/BarotraumaClient/Source/Networking/ServerLog.cs new file mode 100644 index 000000000..d461ce03a --- /dev/null +++ b/BarotraumaClient/Source/Networking/ServerLog.cs @@ -0,0 +1,128 @@ +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Barotrauma.Networking +{ + partial class ServerLog + { + public GUIFrame LogFrame; + + private GUIListBox listBox; + + public void CreateLogFrame() + { + LogFrame = new GUIFrame(new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.Black * 0.5f); + + GUIFrame innerFrame = new GUIFrame(new Rectangle(0, 0, 600, 420), null, Alignment.Center, "", LogFrame); + innerFrame.Padding = new Vector4(10.0f, 20.0f, 10.0f, 20.0f); + + new GUITextBlock(new Rectangle(-200, 0, 100, 15), "Filter", "", Alignment.TopRight, Alignment.CenterRight, innerFrame, false, GUI.SmallFont); + + GUITextBox searchBox = new GUITextBox(new Rectangle(-20, 0, 180, 15), Alignment.TopRight, "", innerFrame); + searchBox.Font = GUI.SmallFont; + searchBox.OnTextChanged = (textBox, text) => + { + msgFilter = text; + FilterMessages(); + return true; + }; + GUIComponent.KeyboardDispatcher.Subscriber = searchBox; + + var clearButton = new GUIButton(new Rectangle(0, 0, 15, 15), "x", Alignment.TopRight, "", innerFrame); + clearButton.OnClicked = ClearFilter; + clearButton.UserData = searchBox; + + listBox = new GUIListBox(new Rectangle(0, 30, 450, 340), "", Alignment.TopRight, innerFrame); + + int y = 30; + foreach (MessageType msgType in Enum.GetValues(typeof(MessageType))) + { + var tickBox = new GUITickBox(new Rectangle(0, y, 20, 20), messageTypeName[(int)msgType], Alignment.TopLeft, GUI.SmallFont, innerFrame); + tickBox.Selected = true; + tickBox.TextColor = messageColor[(int)msgType]; + + tickBox.OnSelected += (GUITickBox tb) => + { + msgTypeHidden[(int)msgType] = !tb.Selected; + FilterMessages(); + return true; + }; + + y += 20; + } + + var currLines = lines.ToList(); + + foreach (LogMessage line in currLines) + { + AddLine(line); + } + + listBox.UpdateScrollBarSize(); + + if (listBox.BarScroll == 0.0f || listBox.BarScroll == 1.0f) listBox.BarScroll = 1.0f; + + GUIButton closeButton = new GUIButton(new Rectangle(-100, 10, 100, 15), "Close", Alignment.BottomRight, "", innerFrame); + closeButton.OnClicked = (button, userData) => + { + LogFrame = null; + return true; + }; + + msgFilter = ""; + } + + private void AddLine(LogMessage line) + { + float prevSize = listBox.BarSize; + + var textBlock = new GUITextBlock(new Rectangle(0, 0, 0, 0), line.Text, "", Alignment.TopLeft, Alignment.TopLeft, listBox, true, GUI.SmallFont); + textBlock.Rect = new Rectangle(textBlock.Rect.X, textBlock.Rect.Y, textBlock.Rect.Width, Math.Max(13, textBlock.Rect.Height)); + textBlock.TextColor = messageColor[(int)line.Type]; + textBlock.CanBeFocused = false; + textBlock.UserData = line; + + if ((prevSize == 1.0f && listBox.BarScroll == 0.0f) || (prevSize < 1.0f && listBox.BarScroll == 1.0f)) listBox.BarScroll = 1.0f; + } + + private bool FilterMessages() + { + string filter = msgFilter == null ? "" : msgFilter.ToLower(); + + foreach (GUIComponent child in listBox.children) + { + var textBlock = child as GUITextBlock; + if (textBlock == null) continue; + + child.Visible = true; + + if (msgTypeHidden[(int)((LogMessage)child.UserData).Type]) + { + child.Visible = false; + continue; + } + + textBlock.Visible = string.IsNullOrEmpty(filter) || textBlock.Text.ToLower().Contains(filter); + } + + listBox.BarScroll = 0.0f; + + return true; + } + + public bool ClearFilter(GUIComponent button, object obj) + { + var searchBox = button.UserData as GUITextBox; + if (searchBox != null) searchBox.Text = ""; + + msgFilter = ""; + FilterMessages(); + + return true; + } + + } +} diff --git a/BarotraumaClient/Source/Networking/WhiteList.cs b/BarotraumaClient/Source/Networking/WhiteList.cs new file mode 100644 index 000000000..6dffa40ee --- /dev/null +++ b/BarotraumaClient/Source/Networking/WhiteList.cs @@ -0,0 +1,112 @@ +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace Barotrauma.Networking +{ + partial class WhiteList + { + private GUIComponent whitelistFrame; + + private GUITextBox nameBox; + private GUITextBox ipBox; + + public GUIComponent CreateWhiteListFrame(GUIComponent parent) + { + if (whitelistFrame != null) + { + whitelistFrame.Parent.ClearChildren(); + whitelistFrame = null; + } + + parent.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f); + + var enabledTick = new GUITickBox(new Rectangle(0, 0, 20, 20), "Enabled", Alignment.TopLeft, parent); + enabledTick.Selected = Enabled; + enabledTick.OnSelected = (GUITickBox box) => + { + Enabled = !Enabled; + + if (Enabled) + { + foreach (Client c in GameMain.Server.ConnectedClients) + { + if (!IsWhiteListed(c.name, c.Connection.RemoteEndPoint.Address.ToString())) + { + whitelistedPlayers.Add(new WhiteListedPlayer(c.name, c.Connection.RemoteEndPoint.Address.ToString())); + if (whitelistFrame != null) CreateWhiteListFrame(whitelistFrame.Parent); + } + } + } + + Save(); + return true; + }; + + new GUITextBlock(new Rectangle(0, -35, 90, 20), "Name:", "", Alignment.BottomLeft, Alignment.CenterLeft, parent, false, GUI.Font); + nameBox = new GUITextBox(new Rectangle(100, -35, 170, 20), Alignment.BottomLeft, "", parent); + nameBox.Font = GUI.Font; + + new GUITextBlock(new Rectangle(0, 0, 90, 20), "IP Address:", "", Alignment.BottomLeft, Alignment.CenterLeft, parent, false, GUI.Font); + ipBox = new GUITextBox(new Rectangle(100, 0, 170, 20), Alignment.BottomLeft, "", parent); + ipBox.Font = GUI.Font; + + var addnewButton = new GUIButton(new Rectangle(0, 35, 150, 20), "Add to whitelist", Alignment.BottomLeft, "", parent); + addnewButton.OnClicked = AddToWhiteList; + + whitelistFrame = new GUIListBox(new Rectangle(0, 30, 0, parent.Rect.Height - 110), "", parent); + + foreach (WhiteListedPlayer wlp in whitelistedPlayers) + { + string blockText = wlp.Name; + if (!string.IsNullOrWhiteSpace(wlp.IP)) blockText += " (" + wlp.IP + ")"; + GUITextBlock textBlock = new GUITextBlock( + new Rectangle(0, 0, 0, 25), + blockText, + "", + Alignment.Left, Alignment.Left, whitelistFrame); + textBlock.Padding = new Vector4(10.0f, 10.0f, 0.0f, 0.0f); + textBlock.UserData = wlp; + + var removeButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Remove", Alignment.Right | Alignment.CenterY, "", textBlock); + removeButton.UserData = wlp; + removeButton.OnClicked = RemoveFromWhiteList; + } + + return parent; + } + + private bool RemoveFromWhiteList(GUIButton button, object obj) + { + WhiteListedPlayer wlp = obj as WhiteListedPlayer; + if (wlp == null) return false; + + RemoveFromWhiteList(wlp); + + if (whitelistFrame != null) + { + whitelistFrame.Parent.ClearChildren(); + CreateWhiteListFrame(whitelistFrame.Parent); + } + + return true; + } + + private bool AddToWhiteList(GUIButton button, object obj) + { + if (string.IsNullOrWhiteSpace(nameBox.Text)) return false; + if (whitelistedPlayers.Any(x => x.Name.ToLower() == nameBox.Text.ToLower() && x.IP == ipBox.Text)) return false; + + AddToWhiteList(nameBox.Text, ipBox.Text); + + if (whitelistFrame != null) + { + CreateWhiteListFrame(whitelistFrame.Parent); + } + return true; + } + } +} diff --git a/BarotraumaClient/Source/Utils/MathUtils.cs b/BarotraumaClient/Source/Utils/MathUtils.cs new file mode 100644 index 000000000..fbf1e9e30 --- /dev/null +++ b/BarotraumaClient/Source/Utils/MathUtils.cs @@ -0,0 +1,22 @@ +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Barotrauma +{ + class CompareSegmentPointCW : IComparer + { + private Vector2 center; + + public CompareSegmentPointCW(Vector2 center) + { + this.center = center; + } + public int Compare(Lights.SegmentPoint a, Lights.SegmentPoint b) + { + return -CompareCCW.Compare(a.WorldPos, b.WorldPos, center); + } + } +} diff --git a/BarotraumaClient/Source/Utils/ToolBox.cs b/BarotraumaClient/Source/Utils/ToolBox.cs new file mode 100644 index 000000000..0937240c9 --- /dev/null +++ b/BarotraumaClient/Source/Utils/ToolBox.cs @@ -0,0 +1,103 @@ +using Lidgren.Network; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Xml; +using System.Xml.Linq; + +namespace Barotrauma +{ + public static partial class ToolBox + { + public static string LimitString(string str, ScalableFont font, int maxWidth) + { + if (maxWidth <= 0 || string.IsNullOrWhiteSpace(str)) return ""; + + float currWidth = font.MeasureString("...").X; + for (int i = 0; i < str.Length; i++) + { + currWidth += font.MeasureString(str[i].ToString()).X; + + if (currWidth > maxWidth) + { + return str.Substring(0, Math.Max(i - 2, 1)) + "..."; + } + } + + return str; + } + + public static string WrapText(string text, float lineLength, ScalableFont font, float textScale = 1.0f) //TODO: could integrate this into the ScalableFont class directly + { + if (font.MeasureString(text).X < lineLength) return text; + + text = text.Replace("\n", " \n "); + + string[] words = text.Split(' '); + + StringBuilder wrappedText = new StringBuilder(); + float linePos = 0f; + float spaceWidth = font.MeasureString(" ").X * textScale; + for (int i = 0; i < words.Length; ++i) + { + if (string.IsNullOrWhiteSpace(words[i]) && words[i] != "\n") continue; + + Vector2 size = font.MeasureString(words[i]) * textScale; + if (size.X > lineLength) + { + if (linePos == 0.0f) + { + wrappedText.AppendLine(words[i]); + } + else + { + do + { + if (words[i].Length == 0) break; + + wrappedText.Append(words[i][0]); + words[i] = words[i].Remove(0, 1); + + linePos += size.X; + } while (words[i].Length > 0 && (size = font.MeasureString((words[i][0]).ToString()) * textScale).X + linePos < lineLength); + + wrappedText.Append("\n"); + linePos = 0.0f; + i--; + } + + continue; + } + + if (linePos + size.X < lineLength) + { + wrappedText.Append(words[i]); + if (words[i] == "\n") + { + linePos = 0.0f; + } + else + { + + linePos += size.X + spaceWidth; + } + } + else + { + wrappedText.Append("\n"); + wrappedText.Append(words[i]); + + linePos = size.X + spaceWidth; + } + + if (i < words.Length - 1) wrappedText.Append(" "); + } + + return wrappedText.ToString(); + } + } +} diff --git a/BarotraumaServer/BarotraumaServer.csproj b/BarotraumaServer/BarotraumaServer.csproj index 6d9fb2068..45b1cb6a0 100644 --- a/BarotraumaServer/BarotraumaServer.csproj +++ b/BarotraumaServer/BarotraumaServer.csproj @@ -34,18 +34,15 @@ 4 - + + False + ..\..\..\..\..\..\Program Files (x86)\MonoGame\v3.0\Assemblies\Windows\MonoGame.Framework.dll + ..\packages\RestSharp.105.2.3\lib\net45\RestSharp.dll - - - - - - @@ -56,9 +53,19 @@ + + + + + + + + + + diff --git a/BarotraumaServer/Source/Items/Components/ItemComponent.cs b/BarotraumaServer/Source/Items/Components/ItemComponent.cs new file mode 100644 index 000000000..87844a6c6 --- /dev/null +++ b/BarotraumaServer/Source/Items/Components/ItemComponent.cs @@ -0,0 +1,31 @@ +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 +{ + partial class ItemComponent : IPropertyObject + { + private bool LoadElemProjSpecific(XElement subElement) + { + switch (subElement.Name.ToString().ToLowerInvariant()) + { + case "guiframe": + break; + case "sound": + break; + default: + return false; //unknown element + } + return true; //element processed + } + } + +} diff --git a/BarotraumaServer/Source/Items/Components/Machines/Fabricator.cs b/BarotraumaServer/Source/Items/Components/Machines/Fabricator.cs new file mode 100644 index 000000000..3bf123d06 --- /dev/null +++ b/BarotraumaServer/Source/Items/Components/Machines/Fabricator.cs @@ -0,0 +1,20 @@ +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 void InitProjSpecific() + { + //do nothing + } + } +} diff --git a/BarotraumaServer/Source/Items/Components/Machines/Pump.cs b/BarotraumaServer/Source/Items/Components/Machines/Pump.cs new file mode 100644 index 000000000..ed6d63ef8 --- /dev/null +++ b/BarotraumaServer/Source/Items/Components/Machines/Pump.cs @@ -0,0 +1,18 @@ +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 void InitProjSpecific() + { + //do nothing + } + } +} diff --git a/BarotraumaServer/Source/Items/Components/Machines/Reactor.cs b/BarotraumaServer/Source/Items/Components/Machines/Reactor.cs new file mode 100644 index 000000000..967fe573d --- /dev/null +++ b/BarotraumaServer/Source/Items/Components/Machines/Reactor.cs @@ -0,0 +1,18 @@ +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 void InitProjSpecific() + { + //do nothing + } + } +} diff --git a/BarotraumaServer/Source/Items/Components/Machines/Steering.cs b/BarotraumaServer/Source/Items/Components/Machines/Steering.cs new file mode 100644 index 000000000..919340b15 --- /dev/null +++ b/BarotraumaServer/Source/Items/Components/Machines/Steering.cs @@ -0,0 +1,26 @@ +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 + { + public bool MaintainPos; + public bool LevelStartSelected; + public bool LevelEndSelected; + + private void InitProjSpecific() + { + //do nothing + } + } +} diff --git a/BarotraumaServer/Source/Items/Components/Power/PowerContainer.cs b/BarotraumaServer/Source/Items/Components/Power/PowerContainer.cs new file mode 100644 index 000000000..ade106b5e --- /dev/null +++ b/BarotraumaServer/Source/Items/Components/Power/PowerContainer.cs @@ -0,0 +1,17 @@ +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() + { + //do nothing + } + } +} diff --git a/BarotraumaServer/Source/Map/Explosion.cs b/BarotraumaServer/Source/Map/Explosion.cs new file mode 100644 index 000000000..c7b7d5768 --- /dev/null +++ b/BarotraumaServer/Source/Map/Explosion.cs @@ -0,0 +1,17 @@ +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.Xml.Linq; +using Barotrauma.Networking; +using FarseerPhysics; + +namespace Barotrauma +{ + partial class Explosion + { + private void ExplodeProjSpecific(Vector2 worldPosition,Hull hull) + { + //do nothing + } + } +} diff --git a/BarotraumaServer/Source/Map/FireSource.cs b/BarotraumaServer/Source/Map/FireSource.cs new file mode 100644 index 000000000..ded4402ae --- /dev/null +++ b/BarotraumaServer/Source/Map/FireSource.cs @@ -0,0 +1,17 @@ +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Barotrauma.Networking; + +namespace Barotrauma +{ + partial class FireSource + { + private void UpdateProjSpecific(float growModifier) + { + //do nothing + } + } +} diff --git a/BarotraumaServer/Source/Map/Hull.cs b/BarotraumaServer/Source/Map/Hull.cs new file mode 100644 index 000000000..b8e392291 --- /dev/null +++ b/BarotraumaServer/Source/Map/Hull.cs @@ -0,0 +1,16 @@ +using FarseerPhysics.Dynamics; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Lidgren.Network; +using Barotrauma.Networking; + +namespace Barotrauma +{ + partial class Hull : MapEntity, IPropertyObject, IServerSerializable + { + public override bool IsMouseOn(Vector2 position) + { + return false; + } + } +} diff --git a/BarotraumaServer/Source/Networking/NetworkMember.cs b/BarotraumaServer/Source/Networking/NetworkMember.cs new file mode 100644 index 000000000..e778ce634 --- /dev/null +++ b/BarotraumaServer/Source/Networking/NetworkMember.cs @@ -0,0 +1,19 @@ +using System; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using System.Collections.Generic; +using Lidgren.Network; +using Barotrauma.Items.Components; + +namespace Barotrauma.Networking +{ + abstract partial class NetworkMember + { + private void InitProjSpecific() + { + //do nothing + } + } +} diff --git a/BarotraumaShared/BarotraumaShared.projitems b/BarotraumaShared/BarotraumaShared.projitems index ea08fc73a..ad444b94b 100644 --- a/BarotraumaShared/BarotraumaShared.projitems +++ b/BarotraumaShared/BarotraumaShared.projitems @@ -1279,7 +1279,6 @@ - @@ -1409,18 +1408,13 @@ - - - - - @@ -1451,7 +1445,6 @@ - diff --git a/BarotraumaShared/Source/Characters/AICharacter.cs b/BarotraumaShared/Source/Characters/AICharacter.cs index 7a32bd5b6..d8940593c 100644 --- a/BarotraumaShared/Source/Characters/AICharacter.cs +++ b/BarotraumaShared/Source/Characters/AICharacter.cs @@ -3,7 +3,7 @@ using System; namespace Barotrauma { - class AICharacter : Character + partial class AICharacter : Character { private AIController aiController; @@ -15,7 +15,9 @@ namespace Barotrauma public AICharacter(string file, Vector2 position, CharacterInfo characterInfo = null, bool isNetworkPlayer = false) : base(file, position, characterInfo, isNetworkPlayer) { +#if CLIENT soundTimer = Rand.Range(0.0f, soundInterval); +#endif } public void SetAI(AIController aiController) @@ -43,6 +45,7 @@ namespace Barotrauma if (Controlled == this || !aiController.Enabled) return; +#if CLIENT if (soundTimer > 0) { soundTimer -= deltaTime; @@ -60,17 +63,11 @@ namespace Barotrauma } soundTimer = soundInterval; } +#endif aiController.Update(deltaTime); } - public override void DrawFront(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch,Camera cam) - { - base.DrawFront(spriteBatch,cam); - - if (GameMain.DebugDraw && !IsDead) aiController.DebugDraw(spriteBatch); - } - public override void AddDamage(CauseOfDeath causeOfDeath, float amount, IDamageable attacker) { base.AddDamage(causeOfDeath, amount, attacker); diff --git a/BarotraumaShared/Source/Characters/Character.cs b/BarotraumaShared/Source/Characters/Character.cs index 03bbb99c1..69b8db155 100644 --- a/BarotraumaShared/Source/Characters/Character.cs +++ b/BarotraumaShared/Source/Characters/Character.cs @@ -84,9 +84,6 @@ namespace Barotrauma //the name of the species (e.q. human) public readonly string SpeciesName; - protected float soundTimer; - protected float soundInterval; - private float bleeding; private float attackCoolDown; @@ -562,7 +559,9 @@ namespace Barotrauma needsAir = ToolBox.GetAttributeBool(doc.Root, "needsair", false); drowningTime = ToolBox.GetAttributeFloat(doc.Root, "drowningtime", 10.0f); +#if CLIENT soundInterval = ToolBox.GetAttributeFloat(doc.Root, "soundinterval", 10.0f); +#endif if (file == humanConfigFile) { @@ -1138,6 +1137,7 @@ namespace Barotrauma Vector2 mouseSimPos = ConvertUnits.ToSimUnits(cursorPosition); +#if CLIENT if (Lights.LightManager.ViewTarget == this && Vector2.DistanceSquared(AnimController.Limbs[0].SimPosition, mouseSimPos) > 1.0f) { Body body = Submarine.PickBody(AnimController.Limbs[0].SimPosition, mouseSimPos); @@ -1151,6 +1151,7 @@ namespace Barotrauma } } } +#endif if (!LockHands) { @@ -1733,7 +1734,9 @@ namespace Barotrauma if (AnimController != null) AnimController.Remove(); +#if CLIENT if (Lights.LightManager.ViewTarget == this) Lights.LightManager.ViewTarget = null; +#endif if (selectedItems[0] != null) selectedItems[0].Drop(this); if (selectedItems[1] != null) selectedItems[1].Drop(this); diff --git a/BarotraumaShared/Source/Characters/Limb.cs b/BarotraumaShared/Source/Characters/Limb.cs index 854e7a188..81e61f87a 100644 --- a/BarotraumaShared/Source/Characters/Limb.cs +++ b/BarotraumaShared/Source/Characters/Limb.cs @@ -7,9 +7,11 @@ using Microsoft.Xna.Framework; //using Microsoft.Xna.Framework.Graphics; using Barotrauma.Items.Components; using System.Collections.Generic; -using Barotrauma.Lights; using System.Linq; using System.IO; +#if CLIENT +using Barotrauma.Lights; +#endif namespace Barotrauma { @@ -43,8 +45,6 @@ namespace Barotrauma public FixedMouseJoint pullJoint; - public readonly Lights.LightSource LightSource; - public readonly LimbType type; public readonly bool ignoreCollisions; @@ -299,15 +299,15 @@ namespace Barotrauma } damagedSprite = new Sprite(subElement, "", damagedSpritePath); - break; - case "lightsource": - LightSource = new LightSource(subElement); - break; case "attack": attack = new Attack(subElement); break; #if CLIENT + case "lightsource": + LightSource = new LightSource(subElement); + + break; case "sound": hitSound = Sound.Load(ToolBox.GetAttributeString(subElement, "file", "")); break; @@ -411,10 +411,12 @@ namespace Barotrauma public void Update(float deltaTime) { +#if CLIENT if (LightSource != null) { LightSource.ParentSub = body.Submarine; } +#endif if (!character.IsDead) damage = Math.Max(0.0f, damage-deltaTime*0.1f); @@ -483,11 +485,7 @@ namespace Barotrauma sprite.Remove(); sprite = null; } - - if (LightSource != null) - { - LightSource.Remove(); - } + if (damagedSprite != null) { damagedSprite.Remove(); @@ -506,6 +504,11 @@ namespace Barotrauma hitSound.Remove(); hitSound = null; } + + if (LightSource != null) + { + LightSource.Remove(); + } #endif } } diff --git a/BarotraumaShared/Source/Items/Components/Door.cs b/BarotraumaShared/Source/Items/Components/Door.cs index 173b37f4c..c1b64fdc3 100644 --- a/BarotraumaShared/Source/Items/Components/Door.cs +++ b/BarotraumaShared/Source/Items/Components/Door.cs @@ -1,5 +1,4 @@ -using Barotrauma.Lights; -using Barotrauma.Networking; +using Barotrauma.Networking; using FarseerPhysics; using FarseerPhysics.Dynamics; using Microsoft.Xna.Framework; @@ -9,19 +8,18 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Xml.Linq; - +#if CLIENT +using Barotrauma.Lights; +#endif namespace Barotrauma.Items.Components { - class Door : ItemComponent, IDrawableComponent, IServerSerializable + partial class Door : ItemComponent, IDrawableComponent, IServerSerializable { private Gap linkedGap; private Rectangle window; - private ConvexHull convexHull; - private ConvexHull convexHull2; - private bool isOpen; private float openState; @@ -133,7 +131,9 @@ namespace Barotrauma.Items.Components openState = MathHelper.Clamp(value, 0.0f, 1.0f); if (openState == prevValue) return; +#if CLIENT UpdateConvexHulls(); +#endif } } @@ -185,78 +185,6 @@ namespace Barotrauma.Items.Components IsActive = true; } - 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)); - } - } - - 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; - } - public override void Move(Vector2 amount) { base.Move(amount); @@ -265,7 +193,9 @@ namespace Barotrauma.Items.Components body.SetTransform(body.SimPosition + ConvertUnits.ToSimUnits(amount), 0.0f); +#if CLIENT UpdateConvexHulls(); +#endif //convexHull.Move(amount); //if (convexHull2 != null) convexHull2.Move(amount); @@ -331,66 +261,19 @@ namespace Barotrauma.Items.Components linkedGap.Open = 1.0f; } - 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); - } - - } - public override void OnMapLoaded() { LinkedGap.ConnectedDoor = this; LinkedGap.Open = openState; +#if CLIENT Vector2[] corners = GetConvexHullCorners(Rectangle.Empty); convexHull = new ConvexHull(corners, Color.Black, item); if (window != Rectangle.Empty) convexHull2 = new ConvexHull(corners, Color.Black, item); UpdateConvexHulls(); +#endif } protected override void RemoveComponentSpecific() @@ -409,8 +292,10 @@ namespace Barotrauma.Items.Components doorSprite.Remove(); if (weldedSprite != null) weldedSprite.Remove(); +#if CLIENT if (convexHull!=null) convexHull.Remove(); if (convexHull2 != null) convexHull2.Remove(); +#endif } private void PushCharactersAway() @@ -450,7 +335,9 @@ namespace Barotrauma.Items.Components if (Math.Sign(diff) != dir) { +#if CLIENT SoundPlayer.PlayDamageSound(DamageSoundType.LimbBlunt, 1.0f, body); +#endif if (isHorizontal) { @@ -512,10 +399,12 @@ namespace Barotrauma.Items.Components { //clients can "predict" that the door opens/closes when a signal is received - //the prediction will be reset after 1 second, setting the door to a state - //sent by the server, or reverting it back to its old state if no msg from server was received +//the prediction will be reset after 1 second, setting the door to a state +//sent by the server, or reverting it back to its old state if no msg from server was received +#if CLIENT if (open != predictedState) PlaySound(ActionType.OnUse, item.WorldPosition); +#endif predictedState = open; resetPredictionTimer = CorrectionDelay; @@ -523,7 +412,9 @@ namespace Barotrauma.Items.Components } else { +#if CLIENT if (!isNetworkMessage || open != predictedState) PlaySound(ActionType.OnUse, item.WorldPosition); +#endif isOpen = open; } diff --git a/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs b/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs index 491378aea..072a2abef 100644 --- a/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs +++ b/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs @@ -165,10 +165,10 @@ namespace Barotrauma.Items.Components Hull hull = Hull.FindHull(displayPos, item.CurrentHull); if (hull != null) { - hull.Extinquish(deltaTime, ExtinquishAmount, displayPos); + hull.Extinguish(deltaTime, ExtinquishAmount, displayPos); if (hull != item.CurrentHull) { - item.CurrentHull.Extinquish(deltaTime, ExtinquishAmount, displayPos); + item.CurrentHull.Extinguish(deltaTime, ExtinquishAmount, displayPos); } } diff --git a/BarotraumaShared/Source/Items/Components/ItemComponent.cs b/BarotraumaShared/Source/Items/Components/ItemComponent.cs index 993f73485..722d23fd6 100644 --- a/BarotraumaShared/Source/Items/Components/ItemComponent.cs +++ b/BarotraumaShared/Source/Items/Components/ItemComponent.cs @@ -17,34 +17,11 @@ namespace Barotrauma.Items.Components void Draw(SpriteBatch spriteBatch, bool editing); #endif } - - 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; - } - } - + /// /// The base class for components holding the different functionalities of the item /// - class ItemComponent : IPropertyObject + partial class ItemComponent : IPropertyObject { protected Item item; @@ -65,10 +42,6 @@ namespace Barotrauma.Items.Components public List requiredSkills; - private Dictionary> sounds; - - private GUIFrame guiFrame; - public ItemComponent Parent; protected const float CorrectionDelay = 1.0f; @@ -95,10 +68,12 @@ namespace Barotrauma.Items.Components get { return isActive; } set { +#if CLIENT if (!value && isActive) { StopSounds(ActionType.OnActive); } +#endif isActive = value; } @@ -181,19 +156,6 @@ namespace Barotrauma.Items.Components get { return name; } } - 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; - } - } - [HasDefaultValue("", false)] public string Msg { @@ -216,7 +178,9 @@ namespace Barotrauma.Items.Components requiredSkills = new List(); +#if CLIENT sounds = new Dictionary>(); +#endif SelectKey = InputType.Select; @@ -275,86 +239,9 @@ namespace Barotrauma.Items.Components effectList.Add(statusEffect); - break; - case "guiframe": - string rectStr = ToolBox.GetAttributeString(subElement, "rect", "0.0,0.0,0.5,0.5"); - - string[] components = rectStr.Split(','); - if (components.Length < 4) continue; - - 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 " + element + "! \"" + element.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"); - continue; - } - - 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 soundList = null; - if (!sounds.TryGetValue(itemSound.Type, out soundList)) - { - soundList = new List(); - sounds.Add(itemSound.Type, soundList); - } - - soundList.Add(itemSound); break; default: + if (LoadElemProjSpecific(subElement)) break; ItemComponent ic = Load(subElement, item, item.ConfigFile, false); if (ic == null) break; @@ -366,83 +253,6 @@ namespace Barotrauma.Items.Components } } - 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 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 Move(Vector2 amount) { } /// a Character has picked the item @@ -459,17 +269,6 @@ namespace Barotrauma.Items.Components /// a Character has dropped the item public virtual void Drop(Character dropper) { } - //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) { } - /// true if the operation was completed public virtual bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective) { @@ -482,7 +281,9 @@ namespace Barotrauma.Items.Components //called when isActive is true and condition == 0.0f public virtual void UpdateBroken(float deltaTime, Camera cam) { - StopSounds(ActionType.OnActive); +#if CLIENT + StopSounds(ActionType.OnActive); +#endif } //called when the item is equipped and left mouse button is pressed @@ -527,10 +328,12 @@ namespace Barotrauma.Items.Components public void Remove() { +#if CLIENT if (loopingSound != null) { Sounds.SoundManager.Stop(loopingSoundIndex); } +#endif if (delayedCorrectionCoroutine != null) { @@ -547,10 +350,12 @@ namespace Barotrauma.Items.Components /// public void ShallowRemove() { +#if CLIENT if (loopingSound != null) { Sounds.SoundManager.Stop(loopingSoundIndex); } +#endif ShallowRemoveComponentSpecific(); } @@ -622,7 +427,9 @@ namespace Barotrauma.Items.Components Item containedItem = Array.Find(containedItems, x => x != null && x.Condition > 0.0f && ri.MatchesItem(x)); if (containedItem == null) { +#if CLIENT if (addMessage && !string.IsNullOrEmpty(ri.Msg)) GUI.AddMessage(ri.Msg, Color.Red); +#endif return false; } } @@ -649,7 +456,9 @@ namespace Barotrauma.Items.Components } if (!hasItem) { +#if CLIENT if (addMessage && !string.IsNullOrEmpty(ri.Msg)) GUI.AddMessage(ri.Msg, Color.Red); +#endif return false; } } @@ -683,47 +492,6 @@ namespace Barotrauma.Items.Components } } - //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 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; - } - public virtual void Load(XElement componentElement) { if (componentElement == null) return; diff --git a/BarotraumaShared/Source/Items/Components/ItemContainer.cs b/BarotraumaShared/Source/Items/Components/ItemContainer.cs index db295927a..d883a1d1f 100644 --- a/BarotraumaShared/Source/Items/Components/ItemContainer.cs +++ b/BarotraumaShared/Source/Items/Components/ItemContainer.cs @@ -8,7 +8,7 @@ using Microsoft.Xna.Framework.Graphics; namespace Barotrauma.Items.Components { - class ItemContainer : ItemComponent, IDrawableComponent + partial class ItemContainer : ItemComponent, IDrawableComponent { public const int MaxInventoryCount = 4; @@ -175,64 +175,6 @@ namespace Barotrauma.Items.Components } } - 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 bool Pick(Character picker) { return (picker != null); @@ -301,20 +243,5 @@ namespace Barotrauma.Items.Components } ushort[] itemIds; - - 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; - } } } diff --git a/BarotraumaShared/Source/Items/Components/Machines/Deconstructor.cs b/BarotraumaShared/Source/Items/Components/Machines/Deconstructor.cs index dee384eec..ee547ad24 100644 --- a/BarotraumaShared/Source/Items/Components/Machines/Deconstructor.cs +++ b/BarotraumaShared/Source/Items/Components/Machines/Deconstructor.cs @@ -10,11 +10,8 @@ using System.Xml.Linq; namespace Barotrauma.Items.Components { - class Deconstructor : Powered, IServerSerializable, IClientSerializable + partial class Deconstructor : Powered, IServerSerializable, IClientSerializable { - GUIProgressBar progressBar; - GUIButton activateButton; - float progressTimer; ItemContainer container; @@ -22,10 +19,12 @@ namespace Barotrauma.Items.Components public Deconstructor(Item item, XElement element) : base(item, element) { +#if CLIENT progressBar = new GUIProgressBar(new Rectangle(0,0,200,20), Color.Green, "", 0.0f, Alignment.BottomCenter, GuiFrame); activateButton = new GUIButton(new Rectangle(0, 0, 200, 20), "Deconstruct", Alignment.TopCenter, "", GuiFrame); activateButton.OnClicked = ToggleActive; +#endif } public override void Update(float deltaTime, Camera cam) @@ -44,7 +43,9 @@ namespace Barotrauma.Items.Components Voltage -= deltaTime * 10.0f; var targetItem = container.Inventory.Items.FirstOrDefault(i => i != null); +#if CLIENT progressBar.BarSize = Math.Min(progressTimer / targetItem.Prefab.DeconstructTime, 1.0f); +#endif if (progressTimer>targetItem.Prefab.DeconstructTime) { var containers = item.GetComponents(); @@ -83,44 +84,13 @@ namespace Barotrauma.Items.Components if (container.Inventory.Items.Any(i => i != null)) { progressTimer = 0.0f; +#if CLIENT progressBar.BarSize = 0.0f; +#endif } } } - 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; - } - private void SetActive(bool active, Character user = null) { container = item.GetComponent(); @@ -139,6 +109,7 @@ namespace Barotrauma.Items.Components GameServer.Log(user.Name + (IsActive ? " activated " : " deactivated ") + item.Name, ServerLog.MessageType.ItemInteraction); } +#if CLIENT if (!IsActive) { progressBar.BarSize = 0.0f; @@ -151,16 +122,11 @@ namespace Barotrauma.Items.Components activateButton.Text = "Cancel"; } +#endif container.Inventory.Locked = IsActive; } - - - public void ClientWrite(NetBuffer msg, object[] extraData = null) - { - msg.Write(IsActive); - } - + public void ServerRead(ClientNetObject type, NetBuffer msg, Client c) { bool active = msg.ReadBoolean(); @@ -177,11 +143,5 @@ namespace Barotrauma.Items.Components { msg.Write(IsActive); } - - public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime) - { - SetActive(msg.ReadBoolean()); - } - } } diff --git a/BarotraumaShared/Source/Items/Components/Machines/Engine.cs b/BarotraumaShared/Source/Items/Components/Machines/Engine.cs index bb91914fb..d56d74af5 100644 --- a/BarotraumaShared/Source/Items/Components/Machines/Engine.cs +++ b/BarotraumaShared/Source/Items/Components/Machines/Engine.cs @@ -9,9 +9,8 @@ using System.Xml.Linq; namespace Barotrauma.Items.Components { - class Engine : Powered + partial class Engine : Powered { - private float force; private float targetForce; @@ -49,6 +48,7 @@ namespace Barotrauma.Items.Components { IsActive = true; +#if CLIENT var button = new GUIButton(new Rectangle(160, 50, 30, 30), "-", "", GuiFrame); button.OnClicked = (GUIButton btn, object obj) => { @@ -63,7 +63,8 @@ namespace Barotrauma.Items.Components targetForce += 1.0f; return true; - }; + }; +#endif } public float CurrentVolume @@ -91,41 +92,19 @@ namespace Barotrauma.Items.Components item.CurrentHull.AiTarget.SoundRange = Math.Max(currForce.Length(), item.CurrentHull.AiTarget.SoundRange); } +#if CLIENT for (int i = 0; i < 5; i++) { GameMain.ParticleManager.CreateParticle("bubbles", item.WorldPosition - (Vector2.UnitX * item.Rect.Width/2), -currForce / 5.0f + new Vector2(Rand.Range(-100.0f, 100.0f), Rand.Range(-50f, 50f)), 0.0f, item.CurrentHull); } +#endif } voltage = 0.0f; } - 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); - } - public override void UpdateBroken(float deltaTime, Camera cam) { force = MathHelper.Lerp(force, 0.0f, 0.1f); diff --git a/BarotraumaShared/Source/Items/Components/Machines/Fabricator.cs b/BarotraumaShared/Source/Items/Components/Machines/Fabricator.cs index 649edcc45..bacacb0fe 100644 --- a/BarotraumaShared/Source/Items/Components/Machines/Fabricator.cs +++ b/BarotraumaShared/Source/Items/Components/Machines/Fabricator.cs @@ -79,17 +79,10 @@ namespace Barotrauma.Items.Components } } - class Fabricator : Powered, IServerSerializable, IClientSerializable + partial class Fabricator : Powered, IServerSerializable, IClientSerializable { private List fabricableItems; - private GUIListBox itemList; - - private GUIFrame selectedItemFrame; - - private GUIProgressBar progressBar; - private GUIButton activateButton; - private FabricableItem fabricatedItem; private float timeUntilReady; @@ -110,140 +103,18 @@ namespace Barotrauma.Items.Components if (fabricableItem.TargetItem != null) fabricableItems.Add(fabricableItem); } - 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 inadequateSkills = new List(); - - 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 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; + InitProjSpecific(); } public override bool Select(Character character) { CheckFabricableItems(character); +#if CLIENT if (itemList.Selected != null) { SelectItem(itemList.Selected, itemList.Selected.UserData); } +#endif return base.Select(character); @@ -260,6 +131,7 @@ namespace Barotrauma.Items.Components /// private void CheckFabricableItems(Character character) { +#if CLIENT foreach (GUIComponent child in itemList.children) { var itemPrefab = child.UserData as FabricableItem; @@ -272,35 +144,13 @@ namespace Barotrauma.Items.Components child.GetChild().Color = itemPrefab.TargetItem.SpriteColor * (canBeFabricated ? 1.0f : 0.5f); } +#endif var itemContainer = item.GetComponent(); prevContainedItems = new Item[itemContainer.Inventory.Items.Length]; itemContainer.Inventory.Items.CopyTo(prevContainedItems, 0); } - 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; - } - private void StartFabricating(FabricableItem selectedItem, Character user = null) { if (selectedItem == null) return; @@ -310,9 +160,11 @@ namespace Barotrauma.Items.Components GameServer.Log(user.Name + " started fabricating " + selectedItem.TargetItem.Name + " in " + item.Name, ServerLog.MessageType.ItemInteraction); } +#if CLIENT itemList.Enabled = false; activateButton.Text = "Cancel"; +#endif fabricatedItem = selectedItem; IsActive = true; @@ -333,17 +185,19 @@ namespace Barotrauma.Items.Components GameServer.Log(user.Name + " cancelled the fabrication of " + fabricatedItem.TargetItem.Name + " in " + item.Name, ServerLog.MessageType.ItemInteraction); } - itemList.Enabled = true; IsActive = false; fabricatedItem = null; currPowerConsumption = 0.0f; +#if CLIENT + itemList.Enabled = true; if (activateButton != null) { activateButton.Text = "Create"; } if (progressBar != null) progressBar.BarSize = 0.0f; +#endif timeUntilReady = 0.0f; @@ -354,10 +208,12 @@ namespace Barotrauma.Items.Components public override void Update(float deltaTime, Camera cam) { +#if CLIENT if (progressBar!=null) { progressBar.BarSize = fabricatedItem == null ? 0.0f : (fabricatedItem.RequiredTime - timeUntilReady) / fabricatedItem.RequiredTime; } +#endif if (voltage < minVoltage) return; @@ -400,51 +256,6 @@ namespace Barotrauma.Items.Components CancelFabricating(null); } - 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(); - 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); - } - private bool CanBeFabricated(FabricableItem fabricableItem, Character user) { if (fabricableItem == null) return false; @@ -464,12 +275,6 @@ namespace Barotrauma.Items.Components return true; } - 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 ServerRead(ClientNetObject type, NetBuffer msg, Client c) { int itemIndex = msg.ReadRangedInteger(-1, fabricableItems.Count - 1); @@ -488,7 +293,9 @@ namespace Barotrauma.Items.Components if (fabricatedItem != null && fabricableItems.IndexOf(fabricatedItem) == itemIndex) return; if (itemIndex < 0 || itemIndex >= fabricableItems.Count) return; +#if CLIENT SelectItem(null, fabricableItems[itemIndex]); +#endif StartFabricating(fabricableItems[itemIndex], c.Character); } } @@ -499,24 +306,5 @@ namespace Barotrauma.Items.Components 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]); - } - } - } } diff --git a/BarotraumaShared/Source/Items/Components/Machines/MiniMap.cs b/BarotraumaShared/Source/Items/Components/Machines/MiniMap.cs index 8f583d995..820fa590c 100644 --- a/BarotraumaShared/Source/Items/Components/Machines/MiniMap.cs +++ b/BarotraumaShared/Source/Items/Components/Machines/MiniMap.cs @@ -7,7 +7,7 @@ using System.Linq; namespace Barotrauma.Items.Components { - class MiniMap : Powered + partial class MiniMap : Powered { class HullData { @@ -77,123 +77,6 @@ namespace Barotrauma.Items.Components return true; } - 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); - } - } - public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0) { base.ReceiveSignal(stepsTaken, signal, connection, source, sender, power); diff --git a/BarotraumaShared/Source/Items/Components/Machines/Pump.cs b/BarotraumaShared/Source/Items/Components/Machines/Pump.cs index 12c824990..49a03d417 100644 --- a/BarotraumaShared/Source/Items/Components/Machines/Pump.cs +++ b/BarotraumaShared/Source/Items/Components/Machines/Pump.cs @@ -8,7 +8,7 @@ using System.Xml.Linq; namespace Barotrauma.Items.Components { - class Pump : Powered, IServerSerializable, IClientSerializable + partial class Pump : Powered, IServerSerializable, IClientSerializable { private float flowPercentage; private float maxFlow; @@ -17,8 +17,6 @@ namespace Barotrauma.Items.Components public Hull hull1; - private GUITickBox isActiveTickBox; - [HasDefaultValue(0.0f, true)] public float FlowPercentage { @@ -58,7 +56,9 @@ namespace Barotrauma.Items.Components { base.IsActive = value; +#if CLIENT if (isActiveTickBox != null) isActiveTickBox.Selected = value; +#endif } } @@ -67,64 +67,7 @@ namespace Barotrauma.Items.Components { GetHull(); - 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; - }; + InitProjSpecific(); } public override void Move(Vector2 amount) @@ -180,27 +123,6 @@ namespace Barotrauma.Items.Components hull1 = Hull.FindHull(item.WorldPosition, item.CurrentHull); } - 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 override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power=0.0f) { base.ReceiveSignal(stepsTaken, signal, connection, source, sender, power); @@ -233,13 +155,6 @@ namespace Barotrauma.Items.Components if (!IsActive) currPowerConsumption = 0.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 ServerRead(ClientNetObject type, Lidgren.Network.NetBuffer msg, Client c) { float newFlowPercentage = msg.ReadRangedInteger(-10, 10) * 10.0f; @@ -271,17 +186,5 @@ namespace Barotrauma.Items.Components 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(); - } - } } diff --git a/BarotraumaShared/Source/Items/Components/Machines/Radar.cs b/BarotraumaShared/Source/Items/Components/Machines/Radar.cs index 361d80136..4e5f7a81e 100644 --- a/BarotraumaShared/Source/Items/Components/Machines/Radar.cs +++ b/BarotraumaShared/Source/Items/Components/Machines/Radar.cs @@ -9,7 +9,7 @@ using Voronoi2; namespace Barotrauma.Items.Components { - class Radar : Powered, IServerSerializable, IClientSerializable + partial class Radar : Powered, IServerSerializable, IClientSerializable { private float range; @@ -19,9 +19,6 @@ namespace Barotrauma.Items.Components private readonly Sprite radarBlip; - private GUITickBox isActiveTickBox; - - private List radarBlips; private float prevPingRadius; float prevPassivePingRadius; @@ -56,14 +53,18 @@ namespace Barotrauma.Items.Components set { base.IsActive = value; +#if CLIENT if (isActiveTickBox != null) isActiveTickBox.Selected = value; +#endif } } public Radar(Item item, XElement element) : base(item, element) { +#if CLIENT radarBlips = new List(); +#endif displayBorderSize = ToolBox.GetAttributeFloat(element, "displaybordersize", 0.0f); @@ -82,7 +83,8 @@ namespace Barotrauma.Items.Components break; } } - + +#if CLIENT isActiveTickBox = new GUITickBox(new Rectangle(0, 0, 20, 20), "Active Sonar", Alignment.TopLeft, GuiFrame); isActiveTickBox.OnSelected = (GUITickBox box) => { @@ -101,6 +103,7 @@ namespace Barotrauma.Items.Components }; GuiFrame.CanBeFocused = false; +#endif IsActive = false; } @@ -133,413 +136,13 @@ namespace Barotrauma.Items.Components { return pingState > 1.0f; } - - 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(); - 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 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); - } - protected override void RemoveComponentSpecific() { if (pingCircle!=null) pingCircle.Remove(); if (screenOverlay != null) screenOverlay.Remove(); } - public void ClientWrite(Lidgren.Network.NetBuffer msg, object[] extraData = null) - { - msg.Write(IsActive); - } - public void ServerRead(ClientNetObject type, Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c) { bool isActive = msg.ReadBoolean(); @@ -547,7 +150,9 @@ namespace Barotrauma.Items.Components if (!item.CanClientAccess(c)) return; IsActive = isActive; +#if CLIENT isActiveTickBox.Selected = IsActive; +#endif item.CreateServerEvent(this); } @@ -556,29 +161,5 @@ namespace Barotrauma.Items.Components { 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); - } } } diff --git a/BarotraumaShared/Source/Items/Components/Machines/Reactor.cs b/BarotraumaShared/Source/Items/Components/Machines/Reactor.cs index ed7ecb063..dca857bd9 100644 --- a/BarotraumaShared/Source/Items/Components/Machines/Reactor.cs +++ b/BarotraumaShared/Source/Items/Components/Machines/Reactor.cs @@ -8,7 +8,7 @@ using Barotrauma.Networking; namespace Barotrauma.Items.Components { - class Reactor : Powered, IDrawableComponent, IServerSerializable, IClientSerializable + partial class Reactor : Powered, IDrawableComponent, IServerSerializable, IClientSerializable { const float NetworkUpdateInterval = 0.5f; @@ -50,8 +50,6 @@ namespace Barotrauma.Items.Components private PropertyTask powerUpTask; - private GUITickBox autoTempTickBox; - private bool unsentChanges; private float sendUpdateTimer; @@ -134,7 +132,9 @@ namespace Barotrauma.Items.Components set { autoTemp = value; +#if CLIENT if (autoTempTickBox!=null) autoTempTickBox.Selected = value; +#endif } } @@ -163,92 +163,7 @@ namespace Barotrauma.Items.Components IsActive = true; - 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; - }; + InitProjSpecific(); } public override void Update(float deltaTime, Camera cam) @@ -283,6 +198,7 @@ namespace Barotrauma.Items.Components if (temperature>fireTemp && temperature-deltaTemp updateGraphInterval) - { - UpdateGraph(fissionRateGraph, fissionRate); - UpdateGraph(coolingRateGraph, coolingRate); - UpdateGraph(tempGraph, temperature); - - UpdateGraph(loadGraph, load); - - graphTimer = 0.0f; - } - } - private void MeltDown() { if (item.Condition <= 0.0f) return; @@ -435,18 +342,6 @@ namespace Barotrauma.Items.Components return picker != null; } - 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 bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective) { switch (objective.Option.ToLowerInvariant()) @@ -480,110 +375,6 @@ namespace Barotrauma.Items.Components return false; } - 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(IList graph, T newValue) - { - for (int i = graph.Count - 1; i > 0; i--) - { - graph[i] = graph[i - 1]; - } - graph[0] = newValue; - } - - static void DrawGraph(IList 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 override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power) { switch (connection.Name) @@ -598,17 +389,6 @@ namespace Barotrauma.Items.Components } } - 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 ServerRead(ClientNetObject type, NetBuffer msg, Client c) { bool autoTemp = msg.ReadBoolean(); @@ -644,23 +424,5 @@ namespace Barotrauma.Items.Components msg.WriteRangedSingle(coolingRate, 0.0f, 100.0f, 8); msg.WriteRangedSingle(fissionRate, 0.0f, 100.0f, 8); } - - 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); - } - } } diff --git a/BarotraumaShared/Source/Items/Components/Machines/Steering.cs b/BarotraumaShared/Source/Items/Components/Machines/Steering.cs index 7e584935a..be0094b65 100644 --- a/BarotraumaShared/Source/Items/Components/Machines/Steering.cs +++ b/BarotraumaShared/Source/Items/Components/Machines/Steering.cs @@ -12,16 +12,13 @@ using Voronoi2; namespace Barotrauma.Items.Components { - class Steering : Powered, IServerSerializable, IClientSerializable + partial class Steering : Powered, IServerSerializable, IClientSerializable { private const float AutopilotRayCastInterval = 0.5f; private Vector2 currVelocity; private Vector2 targetVelocity; - private GUITickBox autopilotTickBox, maintainPosTickBox; - private GUITickBox levelEndTickBox, levelStartTickBox; - private bool autoPilot; private Vector2? posToMaintain; @@ -47,17 +44,21 @@ namespace Barotrauma.Items.Components if (value == autoPilot) return; autoPilot = value; +#if CLIENT autopilotTickBox.Selected = value; maintainPosTickBox.Enabled = autoPilot; levelEndTickBox.Enabled = autoPilot; levelStartTickBox.Enabled = autoPilot; - +#endif if (autoPilot) { if (pathFinder == null) pathFinder = new PathFinder(WayPoint.WayPointList, false); +#if CLIENT ToggleMaintainPosition(maintainPosTickBox); +#endif } +#if CLIENT else { maintainPosTickBox.Selected = false; @@ -66,16 +67,10 @@ namespace Barotrauma.Items.Components posToMaintain = null; } +#endif } } - - public bool MaintainPos - { - get { return maintainPosTickBox.Selected; } - set { maintainPosTickBox.Selected = value; } - } - - + [Editable, HasDefaultValue(0.5f, true)] public float NeutralBallastLevel { @@ -107,33 +102,7 @@ namespace Barotrauma.Items.Components { IsActive = true; - 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; - + InitProjSpecific(); } public override void Update(float deltaTime, Camera cam) @@ -143,12 +112,15 @@ namespace Barotrauma.Items.Components networkUpdateTimer -= deltaTime; if (networkUpdateTimer <= 0.0f) { +#if CLIENT if (GameMain.Client != null) { item.CreateClientEvent(this); correctionTimer = CorrectionDelay; } - else if (GameMain.Server != null) + else +#endif + if (GameMain.Server != null) { item.CreateServerEvent(this); } @@ -177,75 +149,6 @@ namespace Barotrauma.Items.Components voltage -= deltaTime; } - 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; - } - } - } - private void UpdateAutoPilot(float deltaTime) { if (posToMaintain != null) @@ -369,7 +272,7 @@ namespace Barotrauma.Items.Components if (pathFinder == null) pathFinder = new PathFinder(WayPoint.WayPointList, false); Vector2 target; - if (levelEndTickBox.Selected) + if (LevelEndSelected) { target = ConvertUnits.ToSimUnits(Level.Loaded.EndPosition); } @@ -400,82 +303,6 @@ namespace Barotrauma.Items.Components } } - 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 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 override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power=0.0f) { if (connection.Name == "velocity_in") @@ -488,31 +315,6 @@ namespace Barotrauma.Items.Components } } - 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(levelStartTickBox.Selected); - } - } - } - public void ServerRead(ClientNetObject type, Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c) { bool autoPilot = msg.ReadBoolean(); @@ -551,19 +353,19 @@ namespace Barotrauma.Items.Components else { - maintainPosTickBox.Selected = newPosToMaintain != null; + MaintainPos = newPosToMaintain != null; posToMaintain = newPosToMaintain; if (posToMaintain == null) { - levelStartTickBox.Selected = headingToStart; - levelEndTickBox.Selected = !headingToStart; + LevelStartSelected = headingToStart; + LevelEndSelected = !headingToStart; UpdatePath(); } else { - levelStartTickBox.Selected = false; - levelEndTickBox.Selected = false; + LevelStartSelected = false; + LevelEndSelected = false; } } @@ -591,70 +393,7 @@ namespace Barotrauma.Items.Components } else { - msg.Write(levelStartTickBox.Selected); - } - } - } - - 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 - { - - maintainPosTickBox.Selected = newPosToMaintain != null; - posToMaintain = newPosToMaintain; - - if (posToMaintain == null) - { - levelStartTickBox.Selected = headingToStart; - levelEndTickBox.Selected = !headingToStart; - UpdatePath(); - } - else - { - levelStartTickBox.Selected = false; - levelEndTickBox.Selected = false; + msg.Write(LevelStartSelected); } } } diff --git a/BarotraumaShared/Source/Items/Components/Power/PowerContainer.cs b/BarotraumaShared/Source/Items/Components/Power/PowerContainer.cs index fb617d08c..b5f375a89 100644 --- a/BarotraumaShared/Source/Items/Components/Power/PowerContainer.cs +++ b/BarotraumaShared/Source/Items/Components/Power/PowerContainer.cs @@ -7,7 +7,7 @@ using Lidgren.Network; namespace Barotrauma.Items.Components { - class PowerContainer : Powered, IDrawableComponent, IServerSerializable, IClientSerializable + partial class PowerContainer : Powered, IDrawableComponent, IServerSerializable, IClientSerializable { //[power/min] private float capacity; @@ -92,46 +92,7 @@ namespace Barotrauma.Items.Components IsActive = true; - 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; - }; - } + InitProjSpecific(); } public override bool Pick(Character picker) @@ -240,48 +201,6 @@ namespace Barotrauma.Items.Components } } - 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 ServerRead(ClientNetObject type, NetBuffer msg, Client c) { float newRechargeSpeed = msg.ReadRangedInteger(0,10) / 10.0f * maxRechargeSpeed; @@ -302,17 +221,5 @@ namespace Barotrauma.Items.Components float chargeRatio = MathHelper.Clamp(charge / capacity, 0.0f, 1.0f); msg.WriteRangedSingle(chargeRatio, 0.0f, 1.0f, 8); } - - 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; - } } } diff --git a/BarotraumaShared/Source/Items/Components/Power/PowerTransfer.cs b/BarotraumaShared/Source/Items/Components/Power/PowerTransfer.cs index 26a424436..ddfc5b536 100644 --- a/BarotraumaShared/Source/Items/Components/Power/PowerTransfer.cs +++ b/BarotraumaShared/Source/Items/Components/Power/PowerTransfer.cs @@ -8,7 +8,7 @@ using System.Linq; namespace Barotrauma.Items.Components { - class PowerTransfer : Powered + partial class PowerTransfer : Powered { static float fullPower; static float fullLoad; @@ -173,29 +173,6 @@ namespace Barotrauma.Items.Components } } - 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); - } - public override void OnMapLoaded() { var connections = item.Connections; diff --git a/BarotraumaShared/Source/Items/Components/Power/Powered.cs b/BarotraumaShared/Source/Items/Components/Power/Powered.cs index 3f5f8aeba..9ba4f1f55 100644 --- a/BarotraumaShared/Source/Items/Components/Power/Powered.cs +++ b/BarotraumaShared/Source/Items/Components/Power/Powered.cs @@ -3,11 +3,8 @@ using System.Xml.Linq; namespace Barotrauma.Items.Components { - class Powered : ItemComponent + partial class Powered : ItemComponent { - - protected static Sound[] sparkSounds; - //the amount of power CURRENTLY consumed by the item //negative values mean that the item is providing power to connected items protected float currPowerConsumption; @@ -21,10 +18,6 @@ namespace Barotrauma.Items.Components //the maximum amount of power the item can draw from connected items protected float powerConsumption; - private bool powerOnSoundPlayed; - - private static Sound powerOnSound; - [Editable, HasDefaultValue(0.5f, true)] public float MinVoltage { @@ -68,6 +61,7 @@ namespace Barotrauma.Items.Components public Powered(Item item, XElement element) : base(item, element) { +#if CLIENT if (powerOnSound == null) { powerOnSound = Sound.Load("Content/Items/Electricity/powerOn.ogg", false); @@ -81,6 +75,7 @@ namespace Barotrauma.Items.Components sparkSounds[i] = Sound.Load("Content/Items/Electricity/zap" + (i + 1) + ".ogg", false); } } +#endif } public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0) @@ -92,6 +87,8 @@ namespace Barotrauma.Items.Components public override void Update(float deltaTime, Camera cam) { if (currPowerConsumption == 0.0f) return; + +#if CLIENT if (voltage > minVoltage) { if (!powerOnSoundPlayed) @@ -104,6 +101,7 @@ namespace Barotrauma.Items.Components { powerOnSoundPlayed = false; } +#endif } diff --git a/BarotraumaShared/Source/Items/Components/Signal/ConnectionPanel.cs b/BarotraumaShared/Source/Items/Components/Signal/ConnectionPanel.cs index 6451c3c4a..e12ebfeb4 100644 --- a/BarotraumaShared/Source/Items/Components/Signal/ConnectionPanel.cs +++ b/BarotraumaShared/Source/Items/Components/Signal/ConnectionPanel.cs @@ -9,7 +9,7 @@ using Lidgren.Network; namespace Barotrauma.Items.Components { - class ConnectionPanel : ItemComponent, IServerSerializable, IClientSerializable + partial class ConnectionPanel : ItemComponent, IServerSerializable, IClientSerializable { public static Wire HighlightedWire; @@ -38,43 +38,6 @@ namespace Barotrauma.Items.Components IsActive = true; } - 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; - } - public override void OnMapLoaded() { foreach (Connection c in Connections) diff --git a/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs b/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs index 72a50d086..2ec42e2e4 100644 --- a/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs +++ b/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs @@ -1,19 +1,18 @@ using Microsoft.Xna.Framework; -using Barotrauma.Lights; using System; using System.Xml.Linq; using Barotrauma.Networking; using Lidgren.Network; +#if CLIENT +using Barotrauma.Lights; +#endif namespace Barotrauma.Items.Components { - class LightComponent : Powered, IServerSerializable, IDrawableComponent + partial class LightComponent : Powered, IServerSerializable, IDrawableComponent { - private Color lightColor; - private LightSource light; - private float range; private float lightBrightness; @@ -39,7 +38,9 @@ namespace Barotrauma.Items.Components set { castShadows = value; +#if CLIENT if (light != null) light.CastShadows = value; +#endif } } @@ -83,7 +84,9 @@ namespace Barotrauma.Items.Components public override void Move(Vector2 amount) { +#if CLIENT light.Position += amount; +#endif } public override bool IsActive @@ -96,20 +99,23 @@ namespace Barotrauma.Items.Components set { base.IsActive = value; - +#if CLIENT if (light == null) return; light.Color = value ? lightColor : Color.Transparent; if (!value) lightBrightness = 0.0f; +#endif } } public LightComponent(Item item, XElement element) : base (item, element) { +#if CLIENT light = new LightSource(element); light.ParentSub = item.CurrentHull == null ? null : item.CurrentHull.Submarine; light.Position = item.Position; light.CastShadows = castShadows; +#endif IsActive = IsOn; @@ -125,25 +131,32 @@ namespace Barotrauma.Items.Components public override void Update(float deltaTime, Camera cam) { base.Update(deltaTime, cam); - + +#if CLIENT light.ParentSub = item.Submarine; +#endif ApplyStatusEffects(ActionType.OnActive, deltaTime); +#if CLIENT if (item.Container != null) { light.Color = Color.Transparent; return; } +#endif if (item.body != null) { +#if CLIENT light.Position = item.Position; light.Rotation = item.body.Dir > 0.0f ? item.body.Rotation : item.body.Rotation - MathHelper.Pi; - +#endif if (!item.body.Enabled) { +#if CLIENT light.Color = Color.Transparent; +#endif return; } } @@ -159,7 +172,9 @@ namespace Barotrauma.Items.Components if (Rand.Range(0.0f, 1.0f) < 0.05f && voltage < Rand.Range(0.0f, minVoltage)) { +#if CLIENT if (voltage > 0.1f) sparkSounds[Rand.Int(sparkSounds.Length)].Play(1.0f, 400.0f, item.WorldPosition); +#endif lightBrightness = 0.0f; } else @@ -167,8 +182,10 @@ namespace Barotrauma.Items.Components lightBrightness = MathHelper.Lerp(lightBrightness, Math.Min(voltage, 1.0f), 0.1f); } +#if CLIENT light.Color = lightColor * lightBrightness * (1.0f-Rand.Range(0.0f,Flicker)); light.Range = range * (float)Math.Sqrt(lightBrightness); +#endif voltage = 0.0f; } @@ -178,19 +195,13 @@ namespace Barotrauma.Items.Components return true; } - 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); - } - } - protected override void RemoveComponentSpecific() { base.RemoveComponentSpecific(); +#if CLIENT light.Remove(); +#endif } public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power=0.0f) @@ -215,10 +226,5 @@ namespace Barotrauma.Items.Components { msg.Write(IsOn); } - - public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime) - { - IsOn = msg.ReadBoolean(); - } } } diff --git a/BarotraumaShared/Source/Items/Components/Signal/Wire.cs b/BarotraumaShared/Source/Items/Components/Signal/Wire.cs index a92b9aba8..ea38d0d63 100644 --- a/BarotraumaShared/Source/Items/Components/Signal/Wire.cs +++ b/BarotraumaShared/Source/Items/Components/Signal/Wire.cs @@ -1,8 +1,6 @@ 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; @@ -11,9 +9,9 @@ using System.Xml.Linq; namespace Barotrauma.Items.Components { - class Wire : ItemComponent, IDrawableComponent, IServerSerializable + partial class Wire : ItemComponent, IDrawableComponent, IServerSerializable { - class WireSection + partial class WireSection { private Vector2 start; @@ -27,31 +25,6 @@ namespace Barotrauma.Items.Components angle = MathUtils.VectorToAngle(end - start); length = Vector2.Distance(start, end); } - - 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); - } } const float nodeDistance = 32.0f; @@ -286,7 +259,9 @@ namespace Barotrauma.Items.Components public override void Move(Vector2 amount) { +#if CLIENT if (item.IsSelected) MoveNodes(amount); +#endif } public List GetNodes() @@ -396,200 +371,6 @@ namespace Barotrauma.Items.Components } - 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 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(); - - 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); - } - } - } - private int GetClosestNodeIndex(Vector2 pos, float maxDist, out float closestDist) { closestDist = 0.0f; @@ -643,24 +424,6 @@ namespace Barotrauma.Items.Components UpdateSections(); } - 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; - } - public override void Load(XElement componentElement) { base.Load(componentElement); diff --git a/BarotraumaShared/Source/Items/Components/StatusHUD.cs b/BarotraumaShared/Source/Items/Components/StatusHUD.cs index d4f2de7da..28cf6ceb2 100644 --- a/BarotraumaShared/Source/Items/Components/StatusHUD.cs +++ b/BarotraumaShared/Source/Items/Components/StatusHUD.cs @@ -8,7 +8,7 @@ using Microsoft.Xna.Framework; namespace Barotrauma.Items.Components { - class StatusHUD : ItemComponent + partial class StatusHUD : ItemComponent { private static readonly string[] BleedingTexts = {"Minor bleeding", "Bleeding", "Bleeding heavily", "Catastrophic Bleeding"}; @@ -20,56 +20,5 @@ namespace Barotrauma.Items.Components : base(item, element) { } - - 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 texts = new List(); - - 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; - } - } } } diff --git a/BarotraumaShared/Source/Items/ItemPrefab.cs b/BarotraumaShared/Source/Items/ItemPrefab.cs index 8a154b5aa..d29c7de0f 100644 --- a/BarotraumaShared/Source/Items/ItemPrefab.cs +++ b/BarotraumaShared/Source/Items/ItemPrefab.cs @@ -21,7 +21,7 @@ namespace Barotrauma } } - class ItemPrefab : MapEntityPrefab + partial class ItemPrefab : MapEntityPrefab { //static string contentFolder = "Content/Items/"; @@ -190,45 +190,6 @@ namespace Barotrauma } - public override void DrawPlacing(SpriteBatch spriteBatch,Camera cam) - { - Vector2 position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub); - - if (PlayerInput.RightButtonClicked()) - { - selected = null; - return; - } - - if (!resizeHorizontal && !resizeVertical) - { - sprite.Draw(spriteBatch, new Vector2(position.X + sprite.size.X / 2.0f, -position.Y + sprite.size.Y / 2.0f), SpriteColor); - } - else - { - Vector2 placeSize = size; - - if (placePosition == Vector2.Zero) - { - if (PlayerInput.LeftButtonHeld()) placePosition = position; - } - else - { - if (resizeHorizontal) - placeSize.X = Math.Max(position.X - placePosition.X, size.X); - if (resizeVertical) - placeSize.Y = Math.Max(placePosition.Y - position.Y, size.Y); - - position = placePosition; - } - - if (sprite != null) sprite.DrawTiled(spriteBatch, new Vector2(position.X, -position.Y), placeSize, SpriteColor); - } - - //if (PlayerInput.GetMouseState.RightButton == ButtonState.Pressed) selected = null; - - } - public static void LoadAll(List filePaths) { DebugConsole.Log("Loading item prefabs: "); diff --git a/BarotraumaShared/Source/Map/Explosion.cs b/BarotraumaShared/Source/Map/Explosion.cs index 975dbd521..49f22dff7 100644 --- a/BarotraumaShared/Source/Map/Explosion.cs +++ b/BarotraumaShared/Source/Map/Explosion.cs @@ -1,5 +1,4 @@ using Microsoft.Xna.Framework; -using Barotrauma.Lights; using System; using System.Collections.Generic; using System.Xml.Linq; @@ -8,7 +7,7 @@ using FarseerPhysics; namespace Barotrauma { - class Explosion + partial class Explosion { private Attack attack; @@ -36,41 +35,11 @@ namespace Barotrauma { Hull hull = Hull.FindHull(worldPosition); - if (shockwave) - { - GameMain.ParticleManager.CreateParticle("shockwave", worldPosition, - Vector2.Zero, 0.0f, hull); - } - - for (int i = 0; i < attack.Range * 0.1f; i++) - { - Vector2 bubblePos = Rand.Vector(attack.Range * 0.5f); - GameMain.ParticleManager.CreateParticle("bubbles", worldPosition+bubblePos, - bubblePos, 0.0f, hull); - - if (sparks) - { - GameMain.ParticleManager.CreateParticle("spark", worldPosition, - Rand.Vector(Rand.Range(500.0f, 800.0f)), 0.0f, hull); - } - if (flames) - { - GameMain.ParticleManager.CreateParticle("explosionfire", ClampParticlePos(worldPosition + Rand.Vector(50f), hull), - Rand.Vector(Rand.Range(50.0f, 100.0f)), 0.0f, hull); - } - if (smoke) - { - GameMain.ParticleManager.CreateParticle("smoke", ClampParticlePos(worldPosition + Rand.Vector(50f), hull), - Rand.Vector(Rand.Range(1.0f, 10.0f)), 0.0f, hull); - } - } + ExplodeProjSpecific(worldPosition, hull); float displayRange = attack.Range; if (displayRange < 0.1f) return; - var light = new LightSource(worldPosition, displayRange, Color.LightYellow, null); - CoroutineManager.StartCoroutine(DimLight(light)); - float cameraDist = Vector2.Distance(GameMain.GameScreen.Cam.Position, worldPosition)/2.0f; GameMain.GameScreen.Cam.Shake = CameraShake * Math.Max((displayRange - cameraDist) / displayRange, 0.0f); @@ -110,28 +79,7 @@ namespace Barotrauma MathHelper.Clamp(particlePos.X, hull.WorldRect.X, hull.WorldRect.Right), MathHelper.Clamp(particlePos.Y, hull.WorldRect.Y - hull.WorldRect.Height, hull.WorldRect.Y)); } - - - private IEnumerable DimLight(LightSource light) - { - float currBrightness = 1.0f; - float startRange = light.Range; - - while (light.Color.A > 0.0f) - { - light.Color = new Color(light.Color.R, light.Color.G, light.Color.B, currBrightness); - light.Range = startRange * currBrightness; - - currBrightness -= CoroutineManager.DeltaTime * 20.0f; - - yield return CoroutineStatus.Running; - } - - light.Remove(); - - yield return CoroutineStatus.Success; - } - + public static void ApplyExplosionForces(Vector2 worldPosition, float range, float force, float damage = 0.0f, float stun = 0.0f) { if (range <= 0.0f) return; diff --git a/BarotraumaShared/Source/Map/FireSource.cs b/BarotraumaShared/Source/Map/FireSource.cs index 977355bed..b614e6045 100644 --- a/BarotraumaShared/Source/Map/FireSource.cs +++ b/BarotraumaShared/Source/Map/FireSource.cs @@ -1,17 +1,17 @@ -using Barotrauma.Lights; -using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework; using System; using System.Collections.Generic; using System.Linq; using System.Text; using Barotrauma.Networking; +#if CLIENT +using Barotrauma.Lights; +#endif namespace Barotrauma { - class FireSource + partial class FireSource { - static Sound fireSoundBasic, fireSoundLarge; - const float OxygenConsumption = 50.0f; const float GrowSpeed = 5.0f; @@ -19,8 +19,6 @@ namespace Barotrauma private Hull hull; - private LightSource lightSource; - private Vector2 position; private Vector2 size; @@ -73,21 +71,23 @@ namespace Barotrauma if (hull == null) return; if (!isNetworkMessage && GameMain.Client != null) return; - - if (fireSoundBasic == null) - { - fireSoundBasic = Sound.Load("Content/Sounds/fire.ogg", false); - fireSoundLarge = Sound.Load("Content/Sounds/firelarge.ogg", false); - } - + hull.AddFireSource(this); Submarine = hull.Submarine; this.position = worldPosition - new Vector2(-5.0f, 5.0f) - Submarine.Position; +#if CLIENT + if (fireSoundBasic == null) + { + fireSoundBasic = Sound.Load("Content/Sounds/fire.ogg", false); + fireSoundLarge = Sound.Load("Content/Sounds/firelarge.ogg", false); + } + lightSource = new LightSource(this.position, 50.0f, new Color(1.0f, 0.9f, 0.7f), hull == null ? null : hull.Submarine); - +#endif + size = new Vector2(10.0f, 10.0f); } @@ -140,71 +140,9 @@ namespace Barotrauma public void Update(float deltaTime) { - float count = Rand.Range(0.0f, size.X/50.0f); - - if (hull.FireSources.Any(fs => fs != this && fs.size.X > size.X)) - { - if (basicSoundIndex > 0) - { - Sounds.SoundManager.Stop(basicSoundIndex); - basicSoundIndex = -1; - } - if (largeSoundIndex > 0) - { - Sounds.SoundManager.Stop(largeSoundIndex); - largeSoundIndex = -1; - } - } - else - { - if (fireSoundBasic != null) - { - basicSoundIndex = fireSoundBasic.Loop(basicSoundIndex, - Math.Min(size.X / 100.0f, 1.0f), WorldPosition + size / 2.0f, 1000.0f); - - } - if (fireSoundLarge != null) - { - largeSoundIndex = fireSoundLarge.Loop(largeSoundIndex, - MathHelper.Clamp((size.X - 200.0f) / 100.0f, 0.0f, 1.0f), WorldPosition + size / 2.0f, 1000.0f); - } - } - //the firesource will start to shrink if oxygen percentage is below 10 float growModifier = Math.Min((hull.OxygenPercentage / 10.0f) - 1.0f, 1.0f); - for (int i = 0; i < count; i++) - { - Vector2 particlePos = new Vector2( - WorldPosition.X + Rand.Range(0.0f, size.X), - Rand.Range(WorldPosition.Y - size.Y, WorldPosition.Y + 20.0f)); - - Vector2 particleVel = new Vector2( - (particlePos.X - (WorldPosition.X + size.X / 2.0f)), - (float)Math.Sqrt(size.X) * Rand.Range(0.0f, 15.0f) * growModifier); - - var particle = GameMain.ParticleManager.CreateParticle("flame", - particlePos, particleVel, 0.0f, hull); - - if (particle == null) continue; - - //make some of the particles create another firesource when they enter another hull - if (Rand.Int(20) == 1) particle.OnChangeHull = OnChangeHull; - - particle.Size *= MathHelper.Clamp(size.X / 60.0f * Math.Max(hull.Oxygen / hull.FullVolume, 0.4f), 0.5f, 1.0f); - - if (Rand.Int(5) == 1) - { - var smokeParticle = GameMain.ParticleManager.CreateParticle("smoke", - particlePos, new Vector2(particleVel.X, particleVel.Y * 0.1f), 0.0f, hull); - - if (smokeParticle != null) - { - smokeParticle.Size *= MathHelper.Clamp(size.X / 100.0f * Math.Max(hull.Oxygen / hull.FullVolume, 0.4f), 0.5f, 1.0f); - } - } - } - DamageCharacters(deltaTime); DamageItems(deltaTime); @@ -224,9 +162,7 @@ namespace Barotrauma LimitSize(); - lightSource.Range = Math.Max(size.X, size.Y) * 10.0f / 2.0f; - lightSource.Color = new Color(1.0f, 0.45f, 0.3f) * Rand.Range(0.8f, 1.0f); - lightSource.Position = position + Vector2.UnitY * 30.0f; + UpdateProjSpecific(growModifier); if (GameMain.Client != null) return; @@ -294,6 +230,7 @@ namespace Barotrauma if (extinquishAmount < 0.0f) return; +#if CLIENT float steamCount = Rand.Range(-5.0f, Math.Min(extinquishAmount * 100.0f, 10)); for (int i = 0; i < steamCount; i++) { @@ -310,6 +247,7 @@ namespace Barotrauma particle.Size *= MathHelper.Clamp(size.X / 10.0f, 0.5f, 3.0f); } +#endif position.X += extinquishAmount / 2.0f; size.X -= extinquishAmount; @@ -322,7 +260,7 @@ namespace Barotrauma if (size.X < 1.0f) Remove(); } - public void Extinquish(float deltaTime, float amount, Vector2 pos) + public void Extinguish(float deltaTime, float amount, Vector2 pos) { float range = 100.0f; @@ -331,6 +269,7 @@ namespace Barotrauma float extinquishAmount = amount * deltaTime; +#if CLIENT float steamCount = Rand.Range(-5.0f, (float)Math.Sqrt(amount)); for (int i = 0; i < steamCount; i++) { @@ -345,6 +284,7 @@ namespace Barotrauma particle.Size *= MathHelper.Clamp(size.X / 10.0f, 0.5f, 3.0f); } +#endif position.X += extinquishAmount / 2.0f; size.X -= extinquishAmount; @@ -358,6 +298,7 @@ namespace Barotrauma public void Remove() { +#if CLIENT lightSource.Remove(); if (basicSoundIndex > 0) @@ -370,6 +311,7 @@ namespace Barotrauma Sounds.SoundManager.Stop(largeSoundIndex); largeSoundIndex = -1; } +#endif hull.RemoveFire(this); } diff --git a/BarotraumaShared/Source/Map/Gap.cs b/BarotraumaShared/Source/Map/Gap.cs index f91af9527..792705dc9 100644 --- a/BarotraumaShared/Source/Map/Gap.cs +++ b/BarotraumaShared/Source/Map/Gap.cs @@ -9,7 +9,7 @@ using Barotrauma.Items.Components; namespace Barotrauma { - class Gap : MapEntity + partial class Gap : MapEntity { public static List GapList = new List(); @@ -189,58 +189,6 @@ namespace Barotrauma } } - public override void Draw(SpriteBatch sb, bool editing, bool back = true) - { - if (GameMain.DebugDraw) - { - Vector2 center = new Vector2(WorldRect.X + rect.Width / 2.0f, -(WorldRect.Y - rect.Height/ 2.0f)); - - GUI.DrawLine(sb, center, center + new Vector2(flowForce.X, -flowForce.Y)/10.0f, Color.Red); - - GUI.DrawLine(sb, center + Vector2.One * 5.0f, center + new Vector2(lerpedFlowForce.X, -lerpedFlowForce.Y) / 10.0f + Vector2.One * 5.0f, Color.Orange); - } - - if (!editing || !ShowGaps) return; - - Color clr = (open == 0.0f) ? Color.Red : Color.Cyan; - if (isHighlighted) clr = Color.Gold; - - float depth = (ID % 255) * 0.000001f; - - GUI.DrawRectangle( - sb, new Rectangle(WorldRect.X, -WorldRect.Y, rect.Width, rect.Height), - clr * 0.5f, true, - depth, - (int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f)); - - for (int i = 0; i < linkedTo.Count; i++) - { - Vector2 dir = isHorizontal ? - new Vector2(Math.Sign(linkedTo[i].Rect.Center.X - rect.Center.X), 0.0f) - : new Vector2(0.0f, Math.Sign((linkedTo[i].Rect.Y - linkedTo[i].Rect.Height / 2.0f) - (rect.Y - rect.Height / 2.0f))); - - Vector2 arrowPos = new Vector2(WorldRect.Center.X, -(WorldRect.Y - WorldRect.Height / 2)); - arrowPos += new Vector2(dir.X * (WorldRect.Width / 2 + 10), dir.Y * (WorldRect.Height / 2 + 10)); - - GUI.Arrow.Draw(sb, - arrowPos, clr * 0.8f, - GUI.Arrow.Origin, MathUtils.VectorToAngle(dir) + MathHelper.PiOver2, - isHorizontal ? new Vector2(rect.Height / 16.0f, 1.0f) : new Vector2(rect.Width / 16.0f, 1.0f), - SpriteEffects.None, depth); - } - - if (IsSelected) - { - GUI.DrawRectangle(sb, - new Vector2(WorldRect.X - 5, -WorldRect.Y - 5), - new Vector2(rect.Width + 10, rect.Height + 10), - Color.Red, - false, - depth, - (int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f)); - } - } - public override void Update(Camera cam, float deltaTime) { flowForce = Vector2.Zero; @@ -275,11 +223,12 @@ namespace Barotrauma { pos.X += Math.Sign(flowForce.X); pos.Y = MathHelper.Clamp((higherSurface + lowerSurface) / 2.0f, rect.Y - rect.Height, rect.Y) + 10; - + Vector2 velocity = new Vector2( MathHelper.Clamp(flowForce.X, -5000.0f, 5000.0f) * Rand.Range(0.5f, 0.7f), flowForce.Y * Rand.Range(0.5f, 0.7f)); +#if CLIENT var particle = GameMain.ParticleManager.CreateParticle( "watersplash", (Submarine == null ? pos : pos + Submarine.Position) - Vector2.UnitY * Rand.Range(0.0f, 10.0f), @@ -289,16 +238,19 @@ namespace Barotrauma { particle.Size = particle.Size * Math.Min(Math.Abs(flowForce.X / 1000.0f), 5.0f); } +#endif if (Math.Abs(flowForce.X) > 300.0f) { pos.X += Math.Sign(flowForce.X) * 10.0f; pos.Y = Rand.Range(lowerSurface, rect.Y - rect.Height); +#if CLIENT GameMain.ParticleManager.CreateParticle( "bubbles", Submarine == null ? pos : pos + Submarine.Position, flowForce / 10.0f, 0, flowTargetHull); +#endif } } else @@ -314,6 +266,7 @@ namespace Barotrauma lerpedFlowForce.X * Rand.Range(0.5f, 0.7f), Math.Max(lerpedFlowForce.Y, -100.0f) * Rand.Range(0.5f, 0.7f)); +#if CLIENT var splash = GameMain.ParticleManager.CreateParticle( "watersplash", Submarine == null ? pos : pos + Submarine.Position, @@ -325,6 +278,7 @@ namespace Barotrauma "bubbles", Submarine == null ? pos : pos + Submarine.Position, flowForce / 2.0f, 0, FlowTargetHull); +#endif } } @@ -696,37 +650,7 @@ namespace Barotrauma { FindHulls(); } - - public override XElement Save(XElement parentElement) - { - XElement element = new XElement("Gap"); - - element.Add( - new XAttribute("ID", ID), - new XAttribute("horizontal", isHorizontal ? "true" : "false")); - - element.Add(new XAttribute("rect", - (int)(rect.X - Submarine.HiddenSubPosition.X) + "," + - (int)(rect.Y - Submarine.HiddenSubPosition.Y) + "," + - rect.Width + "," + rect.Height)); - - //if (linkedTo != null) - //{ - // int i = 0; - // foreach (Entity e in linkedTo) - // { - // if (e == null) continue; - // element.Add(new XAttribute("linkedto" + i, e.ID)); - // i += 1; - // } - //} - - parentElement.Add(element); - - return element; - } - - + public static void Load(XElement element, Submarine submarine) { Rectangle rect = Rectangle.Empty; diff --git a/BarotraumaShared/Source/Map/Hull.cs b/BarotraumaShared/Source/Map/Hull.cs index e92b77ad6..c1e0c31a2 100644 --- a/BarotraumaShared/Source/Map/Hull.cs +++ b/BarotraumaShared/Source/Map/Hull.cs @@ -12,8 +12,7 @@ using Barotrauma.Networking; namespace Barotrauma { - - class Hull : MapEntity, IPropertyObject, IServerSerializable + partial class Hull : MapEntity, IPropertyObject, IServerSerializable { const float NetworkUpdateInterval = 0.5f; @@ -31,8 +30,6 @@ namespace Barotrauma public static bool EditWater, EditFire; - public static WaterRenderer renderer; - private List fireSources; public const float OxygenDistributionSpeed = 500.0f; @@ -64,11 +61,7 @@ namespace Barotrauma private bool update; public bool Visible = true; - - private Sound currentFlowSound; - private int soundIndex; - private float soundVolume; - + float[] waveY; //displacement from the surface of the water float[] waveVel; //velocity of the point @@ -297,14 +290,6 @@ namespace Barotrauma } } - public override bool IsMouseOn(Vector2 position) - { - if (!GameMain.DebugDraw && !ShowHulls) return false; - - return (Submarine.RectContains(WorldRect, position) && - !Submarine.RectContains(MathUtils.ExpandRect(WorldRect, -8), position)); - } - public int GetWaveIndex(Vector2 position) { return GetWaveIndex(position.X); @@ -350,11 +335,13 @@ namespace Barotrauma } fireSources.Clear(); +#if CLIENT if (soundIndex > -1) { Sounds.SoundManager.Stop(soundIndex); soundIndex = -1; } +#endif if (entityGrids != null) { @@ -383,11 +370,13 @@ namespace Barotrauma } fireSources.Clear(); +#if CLIENT if (soundIndex > -1) { Sounds.SoundManager.Stop(soundIndex); soundIndex = -1; } +#endif if (entityGrids != null) { @@ -458,7 +447,8 @@ namespace Barotrauma strongestFlow = gapFlow; } } - + +#if CLIENT if (strongestFlow > 1.0f) { soundVolume = soundVolume + ((strongestFlow < 100.0f) ? -deltaTime * 0.5f : deltaTime * 0.5f); @@ -487,6 +477,7 @@ namespace Barotrauma soundIndex = -1; } } +#endif //update client hulls if the amount of water has changed by >10% //or if oxygen percentage has changed by 5% @@ -517,6 +508,7 @@ namespace Barotrauma for (int i = 0; i < waveY.Length; i++) { float maxDelta = Math.Max(Math.Abs(rightDelta[i]), Math.Abs(leftDelta[i])); +#if CLIENT if (maxDelta > Rand.Range(1.0f,10.0f)) { var particlePos = new Vector2(rect.X + WaveWidth * i, surface + waveY[i]); @@ -526,6 +518,7 @@ namespace Barotrauma particlePos, new Vector2(0.0f, -50.0f), 0.0f, this); } +#endif waveY[i] = waveY[i] + waveVel[i]; @@ -595,11 +588,11 @@ namespace Barotrauma } } - public void Extinquish(float deltaTime, float amount, Vector2 position) + public void Extinguish(float deltaTime, float amount, Vector2 position) { for (int i = fireSources.Count - 1; i >= 0; i-- ) { - fireSources[i].Extinquish(deltaTime, amount, position); + fireSources[i].Extinguish(deltaTime, amount, position); } } @@ -637,160 +630,6 @@ namespace Barotrauma return connectedHulls; } - public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true) - { - //if (back) return; - Rectangle drawRect; - if (!Visible) - { - drawRect = - Submarine == null ? rect : new Rectangle((int)(Submarine.DrawPosition.X + rect.X), (int)(Submarine.DrawPosition.Y + rect.Y), rect.Width, rect.Height); - - GUI.DrawRectangle(spriteBatch, - new Vector2(drawRect.X, -drawRect.Y), - new Vector2(rect.Width, rect.Height), - Color.Black,true, - 0, (int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f)); - } - - if (!ShowHulls && !GameMain.DebugDraw) return; - - if (!editing && !GameMain.DebugDraw) return; - - if (aiTarget != null) aiTarget.Draw(spriteBatch); - - drawRect = - Submarine == null ? rect : new Rectangle((int)(Submarine.DrawPosition.X + rect.X), (int)(Submarine.DrawPosition.Y + rect.Y), rect.Width, rect.Height); - - GUI.DrawRectangle(spriteBatch, - new Vector2(drawRect.X, -drawRect.Y), - new Vector2(rect.Width, rect.Height), - Color.Blue, false, (ID % 255) * 0.000001f, (int)Math.Max((1.5f / Screen.Selected.Cam.Zoom), 1.0f)); - - GUI.DrawRectangle(spriteBatch, - new Rectangle(drawRect.X, -drawRect.Y, rect.Width, rect.Height), - Color.Red * ((100.0f - OxygenPercentage) / 400.0f), true, 0, (int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f)); - - if (GameMain.DebugDraw) - { - GUI.SmallFont.DrawString(spriteBatch, "Pressure: " + ((int)pressure - rect.Y).ToString() + - " - Oxygen: " + ((int)OxygenPercentage), new Vector2(drawRect.X + 5, -drawRect.Y + 5), Color.White); - GUI.SmallFont.DrawString(spriteBatch, volume + " / " + FullVolume, new Vector2(drawRect.X + 5, -drawRect.Y + 20), Color.White); - - foreach (FireSource fs in fireSources) - { - GUI.DrawRectangle(spriteBatch, new Rectangle((int)fs.WorldPosition.X, (int)-fs.WorldPosition.Y, (int)fs.Size.X, (int)fs.Size.Y), Color.Orange, false); - } - } - - if ((IsSelected || isHighlighted) && editing) - { - GUI.DrawRectangle(spriteBatch, - new Vector2(drawRect.X + 5, -drawRect.Y + 5), - new Vector2(rect.Width - 10, rect.Height - 10), - isHighlighted ? Color.LightBlue * 0.5f : Color.Red * 0.5f, true, 0, (int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f)); - } - } - - public void Render(GraphicsDevice graphicsDevice, Camera cam) - { - if (renderer.PositionInBuffer > renderer.vertices.Length - 6) return; - - Vector2 submarinePos = Submarine == null ? Vector2.Zero : Submarine.DrawPosition; - - //calculate where the surface should be based on the water volume - float top = rect.Y + submarinePos.Y; - float bottom = top - rect.Height; - - float drawSurface = surface + submarinePos.Y; - - Matrix transform = cam.Transform * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f; - - if (bottom > cam.WorldView.Y || top < cam.WorldView.Y - cam.WorldView.Height) return; - - if (!update) - { - // create the four corners of our triangle. - - Vector3[] corners = new Vector3[4]; - - corners[0] = new Vector3(rect.X, rect.Y, 0.0f); - corners[1] = new Vector3(rect.X + rect.Width, rect.Y, 0.0f); - - corners[2] = new Vector3(corners[1].X, rect.Y-rect.Height, 0.0f); - corners[3] = new Vector3(corners[0].X, corners[2].Y, 0.0f); - - Vector2[] uvCoords = new Vector2[4]; - for (int i = 0; i < 4; i++ ) - { - corners[i] += new Vector3(submarinePos, 0.0f); - uvCoords[i] = Vector2.Transform(new Vector2(corners[i].X, -corners[i].Y), transform); - } - - renderer.vertices[renderer.PositionInBuffer] = new VertexPositionTexture(corners[0], uvCoords[0]); - renderer.vertices[renderer.PositionInBuffer + 1] = new VertexPositionTexture(corners[1], uvCoords[1]); - renderer.vertices[renderer.PositionInBuffer + 2] = new VertexPositionTexture(corners[2], uvCoords[2]); - - renderer.vertices[renderer.PositionInBuffer + 3] = new VertexPositionTexture(corners[0], uvCoords[0]); - renderer.vertices[renderer.PositionInBuffer + 4] = new VertexPositionTexture(corners[2], uvCoords[2]); - renderer.vertices[renderer.PositionInBuffer + 5] = new VertexPositionTexture(corners[3], uvCoords[3]); - - renderer.PositionInBuffer += 6; - - return; - } - - float x = rect.X + Submarine.DrawPosition.X; - int start = (int)Math.Floor((cam.WorldView.X - x) / WaveWidth); - start = Math.Max(start, 0); - - int end = (waveY.Length - 1) - - (int)Math.Floor((float)((x + rect.Width) - (cam.WorldView.X + cam.WorldView.Width)) / WaveWidth); - end = Math.Min(end, waveY.Length - 1); - - x += start * WaveWidth; - - for (int i = start; i < end; i++) - { - if (renderer.PositionInBuffer > renderer.vertices.Length - 6) return; - - Vector3[] corners = new Vector3[4]; - - corners[0] = new Vector3(x, top, 0.0f); - corners[3] = new Vector3(corners[0].X, drawSurface + waveY[i], 0.0f); - - //skip adjacent "water rects" if the surface of the water is roughly at the same position - int width = WaveWidth; - while (i < end - 1 && Math.Abs(waveY[i + 1] - waveY[i]) < 1.0f) - { - width += WaveWidth; - i++; - } - - corners[1] = new Vector3(x + width, top, 0.0f); - corners[2] = new Vector3(corners[1].X, drawSurface + waveY[i + 1], 0.0f); - - Vector2[] uvCoords = new Vector2[4]; - for (int n = 0; n < 4; n++) - { - uvCoords[n] = Vector2.Transform(new Vector2(corners[n].X, -corners[n].Y), transform); - } - - renderer.vertices[renderer.PositionInBuffer] = new VertexPositionTexture(corners[0], uvCoords[0]); - renderer.vertices[renderer.PositionInBuffer + 1] = new VertexPositionTexture(corners[1], uvCoords[1]); - renderer.vertices[renderer.PositionInBuffer + 2] = new VertexPositionTexture(corners[2], uvCoords[2]); - - renderer.vertices[renderer.PositionInBuffer + 3] = new VertexPositionTexture(corners[0], uvCoords[0]); - renderer.vertices[renderer.PositionInBuffer + 4] = new VertexPositionTexture(corners[2], uvCoords[2]); - renderer.vertices[renderer.PositionInBuffer + 5] = new VertexPositionTexture(corners[3], uvCoords[3]); - - renderer.PositionInBuffer += 6; - - x += width; - } - - } - //returns the water block which contains the point (or null if it isn't inside any) public static Hull FindHull(Vector2 position, Hull guess = null, bool useWorldCoordinates = true) { @@ -956,25 +795,6 @@ namespace Barotrauma } } - public override XElement Save(XElement parentElement) - { - XElement element = new XElement("Hull"); - - element.Add - ( - new XAttribute("ID", ID), - new XAttribute("rect", - (int)(rect.X - Submarine.HiddenSubPosition.X) + "," + - (int)(rect.Y - Submarine.HiddenSubPosition.Y) + "," + - rect.Width + "," + rect.Height), - new XAttribute("water", volume) - ); - - parentElement.Add(element); - - return element; - } - public static void Load(XElement element, Submarine submarine) { Rectangle rect = Rectangle.Empty; diff --git a/BarotraumaShared/Source/Map/Levels/Level.cs b/BarotraumaShared/Source/Map/Levels/Level.cs index ee672d5db..5101c526f 100644 --- a/BarotraumaShared/Source/Map/Levels/Level.cs +++ b/BarotraumaShared/Source/Map/Levels/Level.cs @@ -14,8 +14,7 @@ using Barotrauma.RuinGeneration; namespace Barotrauma { - - class Level + partial class Level { public const float ShaftHeight = 1000.0f; @@ -44,8 +43,6 @@ namespace Barotrauma static Level loaded; - private LevelRenderer renderer; - //how close the sub has to be to start/endposition to exit public const float ExitDistance = 6000.0f; @@ -168,9 +165,7 @@ namespace Barotrauma loaded = this; positionsOfInterest = new List(); - - renderer = new LevelRenderer(this); - + Voronoi voronoi = new Voronoi(1.0); List sites = new List(); @@ -178,10 +173,14 @@ namespace Barotrauma bodies = new List(); Rand.SetSyncedSeed(ToolBox.StringToInt(seed)); - + +#if CLIENT + renderer = new LevelRenderer(this); + backgroundColor = generationParams.BackgroundColor; float avgValue = (backgroundColor.R + backgroundColor.G + backgroundColor.G) / 3; GameMain.LightManager.AmbientLight = new Color(backgroundColor * (10.0f / avgValue), 1.0f); +#endif float minWidth = 6500.0f; if (Submarine.MainSub != null) @@ -440,7 +439,8 @@ namespace Barotrauma endPosition.Y = borders.Height; List cellsWithBody = new List(cells); - + +#if CLIENT List bodyVertices; bodies = CaveGenerator.GeneratePolygons(cellsWithBody, out bodyVertices); @@ -448,6 +448,7 @@ namespace Barotrauma renderer.SetWallVertices(CaveGenerator.GenerateWallShapes(cells)); renderer.PlaceSprites(generationParams.BackgroundSpriteAmount); +#endif ShaftBody = BodyFactory.CreateEdge(GameMain.World, ConvertUnits.ToSimUnits(new Vector2(borders.X, 0)), @@ -817,50 +818,14 @@ namespace Barotrauma WrappingWall.UpdateWallShift(Submarine.MainSub.WorldPosition, wrappingWalls); }*/ +#if CLIENT if (Hull.renderer != null) { Hull.renderer.ScrollWater((float)deltaTime); } renderer.Update(deltaTime); - } - - public void DrawFront(SpriteBatch spriteBatch) - { - if (renderer == null) return; - renderer.Draw(spriteBatch); - - if (GameMain.DebugDraw) - { - foreach (InterestingPosition pos in positionsOfInterest) - { - Color color = Color.Yellow; - if (pos.PositionType == PositionType.Cave) - { - color = Color.DarkOrange; - } - else if (pos.PositionType == PositionType.Ruin) - { - color = Color.LightGray; - } - - - GUI.DrawRectangle(spriteBatch, new Vector2(pos.Position.X-15.0f, -pos.Position.Y-15.0f), new Vector2(30.0f, 30.0f), color, true); - } - } - } - - public void DrawBack(GraphicsDevice graphics, SpriteBatch spriteBatch, Camera cam, BackgroundCreatureManager backgroundSpriteManager = null) - { - float brightness = MathHelper.Clamp(50.0f + (cam.Position.Y - Size.Y) / 2000.0f, 10.0f, 40.0f); - - float avgValue = (backgroundColor.R + backgroundColor.G + backgroundColor.G) / 3; - GameMain.LightManager.AmbientLight = new Color(backgroundColor * (brightness / avgValue), 1.0f); - - graphics.Clear(backgroundColor); - - if (renderer == null) return; - renderer.DrawBackground(spriteBatch, cam, backgroundSpriteManager); +#endif } public List GetCells(Vector2 pos, int searchDepth = 2) @@ -910,11 +875,13 @@ namespace Barotrauma private void Unload() { +#if CLIENT if (renderer!=null) { renderer.Dispose(); renderer = null; } +#endif if (ruins != null) { diff --git a/BarotraumaShared/Source/Map/LinkedSubmarine.cs b/BarotraumaShared/Source/Map/LinkedSubmarine.cs index f3bc5d9f4..877395290 100644 --- a/BarotraumaShared/Source/Map/LinkedSubmarine.cs +++ b/BarotraumaShared/Source/Map/LinkedSubmarine.cs @@ -12,8 +12,7 @@ using System.Xml.Linq; namespace Barotrauma { - - class LinkedSubmarinePrefab : MapEntityPrefab + partial class LinkedSubmarinePrefab : MapEntityPrefab { public readonly Submarine mainSub; @@ -30,7 +29,7 @@ namespace Barotrauma } } - class LinkedSubmarine : MapEntity + partial class LinkedSubmarine : MapEntity { private List wallVertices; @@ -106,142 +105,6 @@ namespace Barotrauma return Vector2.Distance(position, WorldPosition) < 50.0f; } - public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true) - { - if (!editing || wallVertices == null) return; - - Color color = (isHighlighted) ? Color.Orange : Color.Green; - if (IsSelected) color = Color.Red; - - Vector2 pos = Position; - - for (int i = 0; i < wallVertices.Count; i++) - { - Vector2 startPos = wallVertices[i] + pos; - startPos.Y = -startPos.Y; - - Vector2 endPos = wallVertices[(i + 1) % wallVertices.Count] + pos; - endPos.Y = -endPos.Y; - - GUI.DrawLine(spriteBatch, - startPos, - endPos, - color, 0.0f, 5); - } - - pos.Y = -pos.Y; - GUI.DrawLine(spriteBatch, pos + Vector2.UnitY * 50.0f, pos - Vector2.UnitY * 50.0f, color, 0.0f, 5); - GUI.DrawLine(spriteBatch, pos + Vector2.UnitX * 50.0f, pos - Vector2.UnitX * 50.0f, color, 0.0f, 5); - - Rectangle drawRect = rect; - drawRect.Y = -rect.Y; - GUI.DrawRectangle(spriteBatch, drawRect, Color.Red, true); - - foreach (MapEntity e in linkedTo) - { - GUI.DrawLine(spriteBatch, - new Vector2(WorldPosition.X, -WorldPosition.Y), - new Vector2(e.WorldPosition.X, -e.WorldPosition.Y), - Color.Red * 0.3f); - } - } - - public override void UpdateEditing(Camera cam) - { - if (editingHUD == null || editingHUD.UserData as LinkedSubmarine != this) - { - editingHUD = CreateEditingHUD(); - } - - editingHUD.Update((float)Timing.Step); - - if (!PlayerInput.LeftButtonClicked() || !PlayerInput.KeyDown(Keys.Space)) return; - - Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition); - - foreach (MapEntity entity in mapEntityList) - { - if (entity == this || !entity.IsHighlighted || !(entity is Item) || !entity.IsMouseOn(position)) continue; - if (((Item)entity).GetComponent() == null) continue; - if (linkedTo.Contains(entity)) - { - linkedTo.Remove(entity); - } - else - { - linkedTo.Add(entity); - } - } - } - - public override void DrawEditing(SpriteBatch spriteBatch, Camera cam) - { - if (editingHUD == null) return; - - editingHUD.Draw(spriteBatch); - } - - - private GUIComponent CreateEditingHUD(bool inGame = false) - { - int width = 450; - int x = GameMain.GraphicsWidth / 2 - width / 2, y = 10; - - editingHUD = new GUIFrame(new Rectangle(x, y, width, 100), ""); - editingHUD.Padding = new Vector4(10, 10, 0, 0); - editingHUD.UserData = this; - - new GUITextBlock(new Rectangle(0, 0, 100, 20), "Linked submarine", "", - Alignment.TopLeft, Alignment.TopLeft, editingHUD, false, GUI.LargeFont); - - var pathBox = new GUITextBox(new Rectangle(10,30,300,20), "", editingHUD); - pathBox.Font = GUI.SmallFont; - pathBox.Text = filePath; - - var reloadButton = new GUIButton(new Rectangle(320,30,80,20), "Refresh", "", editingHUD); - reloadButton.OnClicked = Reload; - reloadButton.UserData = pathBox; - - reloadButton.ToolTip = "Reload the linked submarine from the specified file"; - - y += 20; - - if (!inGame) - { - new GUITextBlock(new Rectangle(0, 0, 0, 20), "Hold space to link to a docking port", - "", Alignment.TopRight, Alignment.TopRight, editingHUD, false, GUI.SmallFont); - y += 25; - - } - return editingHUD; - } - - private bool Reload(GUIButton button, object obj) - { - var pathBox = obj as GUITextBox; - - if (!File.Exists(pathBox.Text)) - { - new GUIMessageBox("Error", "Submarine file \"" + pathBox.Text + "\" not found!"); - pathBox.Flash(Color.Red); - pathBox.Text = filePath; - return false; - } - - XDocument doc = Submarine.OpenFile(pathBox.Text); - if (doc == null || doc.Root == null) return false; - - pathBox.Flash(Color.Green); - - GenerateWallVertices(doc.Root); - saveElement = doc.Root; - saveElement.Name = "LinkedSubmarine"; - - filePath = pathBox.Text; - - return true; - } - private void GenerateWallVertices(XElement rootElement) { List points = new List(); @@ -267,87 +130,6 @@ namespace Barotrauma wallVertices = MathUtils.GiftWrap(points); } - public override XElement Save(XElement parentElement) - { - XElement saveElement = null; - - if (sub == null) - { - if (this.saveElement == null) - { - var doc = Submarine.OpenFile(filePath); - saveElement = doc.Root; - - saveElement.Name = "LinkedSubmarine"; - - saveElement.Add(new XAttribute("filepath", filePath)); - } - else - { - saveElement = this.saveElement; - } - - if (saveElement.Attribute("pos") != null) saveElement.Attribute("pos").Remove(); - saveElement.Add(new XAttribute("pos", ToolBox.Vector2ToString(Position - Submarine.HiddenSubPosition))); - - - - var linkedPort = linkedTo.FirstOrDefault(lt => (lt is Item) && ((Item)lt).GetComponent() != null); - if (linkedPort != null) - { - if (saveElement.Attribute("linkedto") != null) saveElement.Attribute("linkedto").Remove(); - - saveElement.Add(new XAttribute("linkedto", linkedPort.ID)); - } - } - else - { - - saveElement = new XElement("LinkedSubmarine"); - - - sub.SaveToXElement(saveElement); - } - - if (sub != null) - { - bool leaveBehind = false; - if (!sub.DockedTo.Contains(Submarine.MainSub)) - { - System.Diagnostics.Debug.Assert(Submarine.MainSub.AtEndPosition || Submarine.MainSub.AtStartPosition); - if (Submarine.MainSub.AtEndPosition) - { - leaveBehind = sub.AtEndPosition != Submarine.MainSub.AtEndPosition; - } - else - { - leaveBehind = sub.AtStartPosition != Submarine.MainSub.AtStartPosition; - } - } - - - if (leaveBehind) - { - saveElement.SetAttributeValue("location", Level.Loaded.Seed); - saveElement.SetAttributeValue("worldpos", ToolBox.Vector2ToString(sub.SubBody.Position)); - - } - else - { - if (saveElement.Attribute("location") != null) saveElement.Attribute("location").Remove(); - if (saveElement.Attribute("worldpos") != null) saveElement.Attribute("worldpos").Remove(); - } - - saveElement.SetAttributeValue("pos", ToolBox.Vector2ToString(Position - Submarine.HiddenSubPosition)); - } - - - - parentElement.Add(saveElement); - - return saveElement; - } - public static void Load(XElement element, Submarine submarine) { Vector2 pos = ToolBox.GetAttributeVector2(element, "pos", Vector2.Zero); diff --git a/BarotraumaShared/Source/Map/Structure.cs b/BarotraumaShared/Source/Map/Structure.cs index 30c338f09..2eac47531 100644 --- a/BarotraumaShared/Source/Map/Structure.cs +++ b/BarotraumaShared/Source/Map/Structure.cs @@ -10,11 +10,10 @@ using Lidgren.Network; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Barotrauma.Networking; -using Barotrauma.Lights; namespace Barotrauma { - class WallSection + partial class WallSection { public Rectangle rect; public float damage; @@ -24,8 +23,6 @@ namespace Barotrauma //public float lastSentDamage; - public ConvexHull hull; - public WallSection(Rectangle rect) { System.Diagnostics.Debug.Assert(rect.Width > 0 && rect.Height > 0); @@ -48,8 +45,6 @@ namespace Barotrauma public static int wallSectionSize = 96; public static List WallList = new List(); - List convexHulls; - StructurePrefab prefab; //farseer physics bodies, separated by gaps @@ -202,10 +197,12 @@ namespace Barotrauma } } +#if CLIENT if (convexHulls!=null) { convexHulls.ForEach(x => x.Move(amount)); } +#endif } public Structure(Rectangle rectangle, StructurePrefab sp, Submarine submarine) @@ -257,10 +254,12 @@ namespace Barotrauma } } +#if CLIENT if (prefab.CastShadow) { GenerateConvexHull(); } +#endif InsertToList(); } @@ -361,43 +360,6 @@ namespace Barotrauma } } - private void GenerateConvexHull() - { - // If not null and not empty , remove the hulls from the system - if(convexHulls != null && convexHulls.Any()) - convexHulls.ForEach(x => x.Remove()); - - // list all of hulls for this structure - convexHulls = new List(); - - var mergedSections = new List(); - foreach (var section in sections) - { - if (mergedSections.Count > 5) - { - mergedSections.Add(section); - GenerateMergedHull(mergedSections); - continue; - } - - // if there is a gap and we have sections to merge, do it. - if (section.gap != null) - { - GenerateMergedHull(mergedSections); - } - else - { - mergedSections.Add(section); - } - } - - // take care of any leftover pieces - if (mergedSections.Count > 0) - { - GenerateMergedHull(mergedSections); - } - } - private Rectangle GenerateMergedRect(List mergedSections) { if (isHorizontal) @@ -410,17 +372,6 @@ namespace Barotrauma } } - private void GenerateMergedHull(List mergedSections) - { - if (!mergedSections.Any()) return; - Rectangle mergedRect = GenerateMergedRect(mergedSections); - - var h = new ConvexHull(CalculateExtremes(mergedRect), Color.Black, this); - mergedSections.ForEach(x => x.hull = h); - convexHulls.Add(h); - mergedSections.Clear(); - } - private static Vector2[] CalculateExtremes(Rectangle sectionRect) { Vector2[] corners = new Vector2[4]; @@ -477,7 +428,9 @@ namespace Barotrauma } } +#if CLIENT if (convexHulls != null) convexHulls.ForEach(x => x.Remove()); +#endif } public override void Remove() @@ -504,7 +457,9 @@ namespace Barotrauma } } +#if CLIENT if (convexHulls != null) convexHulls.ForEach(x => x.Remove()); +#endif } public override bool IsVisible(Rectangle WorldView) @@ -708,8 +663,9 @@ namespace Barotrauma //remove existing gap if damage is below 50% sections[sectionIndex].gap.Remove(); sections[sectionIndex].gap = null; - if(CastShadow) - GenerateConvexHull(); +#if CLIENT + if(CastShadow) GenerateConvexHull(); +#endif } } else @@ -723,8 +679,9 @@ namespace Barotrauma gapRect.Height += 20; sections[sectionIndex].gap = new Gap(gapRect, !isHorizontal, Submarine); sections[sectionIndex].gap.ConnectedWall = this; - +#if CLIENT if(CastShadow) GenerateConvexHull(); +#endif } sections[sectionIndex].gap.Open = (damage / prefab.MaxHealth - 0.5f) * 2.0f; diff --git a/BarotraumaShared/Source/Networking/BanList.cs b/BarotraumaShared/Source/Networking/BanList.cs index 778f6e463..3e1147ddf 100644 --- a/BarotraumaShared/Source/Networking/BanList.cs +++ b/BarotraumaShared/Source/Networking/BanList.cs @@ -33,19 +33,12 @@ namespace Barotrauma.Networking } } - class BanList + partial class BanList { const string SavePath = "Data/bannedplayers.txt"; private List bannedPlayers; - private GUIComponent banFrame; - - public GUIComponent BanFrame - { - get { return banFrame; } - } - public BanList() { bannedPlayers = new List(); @@ -91,53 +84,14 @@ namespace Barotrauma.Networking return bannedPlayers.Any(bp => bp.CompareTo(IP)); } - public GUIComponent CreateBanFrame(GUIComponent parent) + private void RemoveBan(BannedPlayer banned) { - banFrame = new GUIListBox(new Rectangle(0, 0, 0, 0), "", parent); - - foreach (BannedPlayer bannedPlayer in bannedPlayers) - { - GUITextBlock textBlock = new GUITextBlock( - new Rectangle(0, 0, 0, 25), - bannedPlayer.IP + " (" + bannedPlayer.Name + ")", - "", - Alignment.Left, Alignment.Left, banFrame); - textBlock.Padding = new Vector4(10.0f, 10.0f, 0.0f, 0.0f); - textBlock.UserData = banFrame; - - var removeButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Remove", Alignment.Right | Alignment.CenterY, "", textBlock); - removeButton.UserData = bannedPlayer; - removeButton.OnClicked = RemoveBan; - if (bannedPlayer.IP.IndexOf(".x") <= -1) - { - var rangeBanButton = new GUIButton(new Rectangle(-100, 0, 100, 20), "Ban range", Alignment.Right | Alignment.CenterY, "", textBlock); - rangeBanButton.UserData = bannedPlayer; - rangeBanButton.OnClicked = RangeBan; - } - } - - return banFrame; - } - - private bool RemoveBan(GUIButton button, object obj) - { - BannedPlayer banned = obj as BannedPlayer; - if (banned == null) return false; - DebugConsole.Log("Removing ban from " + banned.Name); GameServer.Log("Removing ban from " + banned.Name, ServerLog.MessageType.ServerMessage); bannedPlayers.Remove(banned); Save(); - - if (banFrame != null) - { - banFrame.Parent.RemoveChild(banFrame); - CreateBanFrame(banFrame.Parent); - } - - return true; } public string ToRange(string ip) @@ -153,15 +107,12 @@ namespace Barotrauma.Networking return ip; } - private bool RangeBan(GUIButton button, object obj) + private void RangeBan(BannedPlayer banned) { - BannedPlayer banned = obj as BannedPlayer; - if (banned == null) return false; - banned.IP = ToRange(banned.IP); BannedPlayer bp; - while ((bp = bannedPlayers.Find(x => banned.CompareTo(x.IP)))!=null) + while ((bp = bannedPlayers.Find(x => banned.CompareTo(x.IP))) != null) { //remove all specific bans that are now covered by the rangeban bannedPlayers.Remove(bp); @@ -170,21 +121,6 @@ namespace Barotrauma.Networking bannedPlayers.Add(banned); Save(); - - if (banFrame != null) - { - banFrame.Parent.RemoveChild(banFrame); - CreateBanFrame(banFrame.Parent); - } - - return true; - } - - private bool CloseFrame(GUIButton button, object obj) - { - banFrame = null; - - return true; } public void Save() diff --git a/BarotraumaShared/Source/Networking/GameServer.cs b/BarotraumaShared/Source/Networking/GameServer.cs index e10b18a65..114d62daa 100644 --- a/BarotraumaShared/Source/Networking/GameServer.cs +++ b/BarotraumaShared/Source/Networking/GameServer.cs @@ -17,8 +17,6 @@ namespace Barotrauma.Networking //for keeping track of disconnected clients in case the reconnect shortly after private List disconnectedClients = new List(); - private NetStats netStats; - private int roundStartSeed; //is the server running @@ -89,7 +87,9 @@ namespace Barotrauma.Networking config = new NetPeerConfiguration("barotrauma"); +#if CLIENT netStats = new NetStats(); +#endif #if DEBUG config.SimulatedLoss = 0.05f; @@ -100,7 +100,7 @@ namespace Barotrauma.Networking config.ConnectionTimeout = 60.0f; NetIdUtils.Test(); -#endif +#endif config.Port = port; Port = port; @@ -332,19 +332,13 @@ namespace Barotrauma.Networking masterServerResponded = true; } - public override void AddToGUIUpdateList() - { - if (started) base.AddToGUIUpdateList(); - - if (settingsFrame != null) settingsFrame.AddToGUIUpdateList(); - if (log.LogFrame != null) log.LogFrame.AddToGUIUpdateList(); - } - public override void Update(float deltaTime) { +#if CLIENT if (ShowNetStats) netStats.Update(deltaTime); if (settingsFrame != null) settingsFrame.Update(deltaTime); if (log.LogFrame != null) log.LogFrame.Update(deltaTime); +#endif if (!started) return; @@ -1176,7 +1170,9 @@ namespace Barotrauma.Networking teamClients[i].Character = spawnedCharacter; +#if CLIENT GameMain.GameSession.CrewManager.characters.Add(spawnedCharacter); +#endif } if (characterInfo != null && hostTeam == teamID) @@ -1186,7 +1182,9 @@ namespace Barotrauma.Networking myCharacter.TeamID = (byte)teamID; Character.Controlled = myCharacter; +#if CLIENT GameMain.GameSession.CrewManager.characters.Add(myCharacter); +#endif } } @@ -1470,7 +1468,7 @@ namespace Barotrauma.Networking #if CLIENT GameMain.NetLobbyScreen.RemovePlayer(client.name); -#endif +#endif connectedClients.Remove(client); UpdateVoteStatus(); diff --git a/BarotraumaShared/Source/Networking/GameServerSettings.cs b/BarotraumaShared/Source/Networking/GameServerSettings.cs index 375b337ca..a7e204e53 100644 --- a/BarotraumaShared/Source/Networking/GameServerSettings.cs +++ b/BarotraumaShared/Source/Networking/GameServerSettings.cs @@ -76,10 +76,6 @@ namespace Barotrauma.Networking } } - private GUIFrame settingsFrame; - private GUIFrame[] settingsTabs; - private int settingsTabIndex; - public float AutoRestartTimer; private bool autoRestart; @@ -235,9 +231,13 @@ namespace Barotrauma.Networking doc.Root.SetAttributeValue("TraitorsEnabled", TraitorsEnabled.ToString()); - if (GameMain.NetLobbyScreen != null && GameMain.NetLobbyScreen.ServerMessage != null) + if (GameMain.NetLobbyScreen != null +#if CLIENT + && GameMain.NetLobbyScreen.ServerMessage != null +#endif + ) { - doc.Root.SetAttributeValue("ServerMessage", GameMain.NetLobbyScreen.ServerMessage.Text); + doc.Root.SetAttributeValue("ServerMessage", GameMain.NetLobbyScreen.ServerMessageText); } XmlWriterSettings settings = new XmlWriterSettings(); @@ -278,12 +278,18 @@ namespace Barotrauma.Networking TraitorsEnabled = traitorsEnabled; GameMain.NetLobbyScreen.SetTraitorsEnabled(traitorsEnabled); - if (GameMain.NetLobbyScreen != null && GameMain.NetLobbyScreen.ServerMessage != null) + if (GameMain.NetLobbyScreen != null +#if CLIENT + && GameMain.NetLobbyScreen.ServerMessage != null +#endif + ) { - GameMain.NetLobbyScreen.ServerMessage.Text = ToolBox.GetAttributeString(doc.Root, "ServerMessage", ""); + GameMain.NetLobbyScreen.ServerMessageText = ToolBox.GetAttributeString(doc.Root, "ServerMessage", ""); } +#if CLIENT showLogButton.Visible = SaveServerLogs; +#endif List monsterNames = Directory.GetDirectories("Content/Characters").ToList(); for (int i = 0; i < monsterNames.Count; i++) @@ -298,415 +304,6 @@ namespace Barotrauma.Networking extraCargo = new Dictionary(); } - private void CreateSettingsFrame() - { - settingsFrame = new GUIFrame(new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.Black * 0.5f, null); - - GUIFrame innerFrame = new GUIFrame(new Rectangle(0, 0, 400, 430), null, Alignment.Center, "", settingsFrame); - innerFrame.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f); - - new GUITextBlock(new Rectangle(0, -5, 0, 20), "Settings", "", innerFrame, GUI.LargeFont); - - string[] tabNames = { "Rounds", "Server", "Banlist", "Whitelist" }; - settingsTabs = new GUIFrame[tabNames.Length]; - for (int i = 0; i < tabNames.Length; i++) - { - settingsTabs[i] = new GUIFrame(new Rectangle(0, 15, 0, innerFrame.Rect.Height - 120), null, Alignment.Center, "InnerFrame", innerFrame); - settingsTabs[i].Padding = new Vector4(40.0f, 20.0f, 40.0f, 40.0f); - - var tabButton = new GUIButton(new Rectangle(85 * i, 35, 80, 20), tabNames[i], "", innerFrame); - tabButton.UserData = i; - tabButton.OnClicked = SelectSettingsTab; - } - - settingsTabs[2].Padding = Vector4.Zero; - - SelectSettingsTab(null, 0); - - var closeButton = new GUIButton(new Rectangle(10, 0, 100, 20), "Close", Alignment.BottomRight, "", innerFrame); - closeButton.OnClicked = ToggleSettingsFrame; - - //-------------------------------------------------------------------------------- - // game settings - //-------------------------------------------------------------------------------- - - int y = 0; - - settingsTabs[0].Padding = new Vector4(40.0f, 5.0f, 40.0f, 40.0f); - - new GUITextBlock(new Rectangle(0, y, 100, 20), "Submarine selection:", "", settingsTabs[0]); - var selectionFrame = new GUIFrame(new Rectangle(0, y + 20, 300, 20), null, settingsTabs[0]); - for (int i = 0; i < 3; i++) - { - var selectionTick = new GUITickBox(new Rectangle(i * 100, 0, 20, 20), ((SelectionMode)i).ToString(), Alignment.Left, selectionFrame); - selectionTick.Selected = i == (int)subSelectionMode; - selectionTick.OnSelected = SwitchSubSelection; - selectionTick.UserData = (SelectionMode)i; - } - - y += 45; - - new GUITextBlock(new Rectangle(0, y, 100, 20), "Mode selection:", "", settingsTabs[0]); - selectionFrame = new GUIFrame(new Rectangle(0, y + 20, 300, 20), null, settingsTabs[0]); - for (int i = 0; i < 3; i++) - { - var selectionTick = new GUITickBox(new Rectangle(i * 100, 0, 20, 20), ((SelectionMode)i).ToString(), Alignment.Left, selectionFrame); - selectionTick.Selected = i == (int)modeSelectionMode; - selectionTick.OnSelected = SwitchModeSelection; - selectionTick.UserData = (SelectionMode)i; - } - - y += 60; - - var endBox = new GUITickBox(new Rectangle(0, y, 20, 20), "End round when destination reached", Alignment.Left, settingsTabs[0]); - endBox.Selected = EndRoundAtLevelEnd; - endBox.OnSelected = (GUITickBox) => { EndRoundAtLevelEnd = GUITickBox.Selected; return true; }; - - y += 25; - - var endVoteBox = new GUITickBox(new Rectangle(0, y, 20, 20), "End round by voting", Alignment.Left, settingsTabs[0]); - endVoteBox.Selected = Voting.AllowEndVoting; - endVoteBox.OnSelected = (GUITickBox) => - { - Voting.AllowEndVoting = !Voting.AllowEndVoting; - GameMain.Server.UpdateVoteStatus(); - return true; - }; - - - var votesRequiredText = new GUITextBlock(new Rectangle(20, y + 15, 20, 20), "Votes required: 50 %", "", settingsTabs[0], GUI.SmallFont); - - var votesRequiredSlider = new GUIScrollBar(new Rectangle(150, y + 22, 100, 15), "", 0.1f, settingsTabs[0]); - votesRequiredSlider.UserData = votesRequiredText; - votesRequiredSlider.Step = 0.2f; - votesRequiredSlider.BarScroll = (EndVoteRequiredRatio - 0.5f) * 2.0f; - votesRequiredSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) => - { - GUITextBlock voteText = scrollBar.UserData as GUITextBlock; - - EndVoteRequiredRatio = barScroll / 2.0f + 0.5f; - voteText.Text = "Votes required: " + (int)MathUtils.Round(EndVoteRequiredRatio * 100.0f, 10.0f) + " %"; - return true; - }; - votesRequiredSlider.OnMoved(votesRequiredSlider, votesRequiredSlider.BarScroll); - - y += 35; - - var respawnBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Allow respawning", Alignment.Left, settingsTabs[0]); - respawnBox.Selected = AllowRespawn; - respawnBox.OnSelected = (GUITickBox) => - { - AllowRespawn = !AllowRespawn; - return true; - }; - - - var respawnIntervalText = new GUITextBlock(new Rectangle(20, y + 13, 20, 20), "Respawn interval", "", settingsTabs[0], GUI.SmallFont); - - var respawnIntervalSlider = new GUIScrollBar(new Rectangle(150, y + 20, 100, 15), "", 0.1f, settingsTabs[0]); - respawnIntervalSlider.UserData = respawnIntervalText; - respawnIntervalSlider.Step = 0.05f; - respawnIntervalSlider.BarScroll = RespawnInterval / 600.0f; - respawnIntervalSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) => - { - GUITextBlock text = scrollBar.UserData as GUITextBlock; - - RespawnInterval = Math.Max(barScroll * 600.0f, 10.0f); - text.Text = "Interval: " + ToolBox.SecondsToReadableTime(RespawnInterval); - return true; - }; - respawnIntervalSlider.OnMoved(respawnIntervalSlider, respawnIntervalSlider.BarScroll); - - y += 35; - - var minRespawnText = new GUITextBlock(new Rectangle(0, y, 200, 20), "Minimum players to respawn", "", settingsTabs[0]); - minRespawnText.ToolTip = "What percentage of players has to be dead/spectating until a respawn shuttle is dispatched"; - - var minRespawnSlider = new GUIScrollBar(new Rectangle(150, y + 20, 100, 15), "", 0.1f, settingsTabs[0]); - minRespawnSlider.ToolTip = minRespawnText.ToolTip; - minRespawnSlider.UserData = minRespawnText; - minRespawnSlider.Step = 0.1f; - minRespawnSlider.BarScroll = MinRespawnRatio; - minRespawnSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) => - { - GUITextBlock txt = scrollBar.UserData as GUITextBlock; - - MinRespawnRatio = barScroll; - txt.Text = "Minimum players to respawn: " + (int)MathUtils.Round(MinRespawnRatio * 100.0f, 10.0f) + " %"; - return true; - }; - minRespawnSlider.OnMoved(minRespawnSlider, MinRespawnRatio); - - y += 30; - - var respawnDurationText = new GUITextBlock(new Rectangle(0, y, 200, 20), "Duration of respawn transport", "", settingsTabs[0]); - respawnDurationText.ToolTip = "The amount of time respawned players have to navigate the respawn shuttle to the main submarine. " + - "After the duration expires, the shuttle will automatically head back out of the level."; - - var respawnDurationSlider = new GUIScrollBar(new Rectangle(150, y + 20, 100, 15), "", 0.1f, settingsTabs[0]); - respawnDurationSlider.ToolTip = minRespawnText.ToolTip; - respawnDurationSlider.UserData = respawnDurationText; - respawnDurationSlider.Step = 0.1f; - respawnDurationSlider.BarScroll = MaxTransportTime <= 0.0f ? 1.0f : (MaxTransportTime - 60.0f) / 600.0f; - respawnDurationSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) => - { - GUITextBlock txt = scrollBar.UserData as GUITextBlock; - - if (barScroll == 1.0f) - { - MaxTransportTime = 0; - txt.Text = "Duration of respawn transport: unlimited"; - } - else - { - MaxTransportTime = barScroll * 600.0f + 60.0f; - txt.Text = "Duration of respawn transport: " + ToolBox.SecondsToReadableTime(MaxTransportTime); - } - - return true; - }; - respawnDurationSlider.OnMoved(respawnDurationSlider, respawnDurationSlider.BarScroll); - - y += 35; - - var monsterButton = new GUIButton(new Rectangle(0, y, 130, 20), "Monster Spawns", "", settingsTabs[0]); - monsterButton.Enabled = !GameStarted; - var monsterFrame = new GUIListBox(new Rectangle(-290, 60, 280, 250), "", settingsTabs[0]); - monsterFrame.Visible = false; - monsterButton.UserData = monsterFrame; - monsterButton.OnClicked = (button, obj) => - { - if (gameStarted) - { - ((GUIComponent)obj).Visible = false; - button.Enabled = false; - return true; - } - ((GUIComponent)obj).Visible = !((GUIComponent)obj).Visible; - return true; - }; - List monsterNames = monsterEnabled.Keys.ToList(); - foreach (string s in monsterNames) - { - GUITextBlock textBlock = new GUITextBlock( - new Rectangle(0, 0, 260, 25), - s, - "", - Alignment.Left, Alignment.Left, monsterFrame); - textBlock.Padding = new Vector4(35.0f, 3.0f, 0.0f, 0.0f); - textBlock.UserData = monsterFrame; - textBlock.CanBeFocused = false; - - var monsterEnabledBox = new GUITickBox(new Rectangle(-25, 0, 20, 20), "", Alignment.Left, textBlock); - monsterEnabledBox.Selected = monsterEnabled[s]; - monsterEnabledBox.OnSelected = (GUITickBox) => - { - if (gameStarted) - { - monsterFrame.Visible = false; - monsterButton.Enabled = false; - return true; - } - monsterEnabled[s] = !monsterEnabled[s]; - return true; - }; - } - - var cargoButton = new GUIButton(new Rectangle(160, y, 130, 20), "Additional Cargo", "", settingsTabs[0]); - cargoButton.Enabled = !GameStarted; - - var cargoFrame = new GUIListBox(new Rectangle(300, 60, 280, 250), "", settingsTabs[0]); - cargoFrame.Visible = false; - cargoButton.UserData = cargoFrame; - cargoButton.OnClicked = (button, obj) => - { - if (gameStarted) - { - ((GUIComponent)obj).Visible = false; - button.Enabled = false; - return true; - } - ((GUIComponent)obj).Visible = !((GUIComponent)obj).Visible; - return true; - }; - - - foreach (MapEntityPrefab pf in MapEntityPrefab.list) - { - if (!(pf is ItemPrefab) || (pf.Price <= 0.0f && !pf.tags.Contains("smallitem"))) continue; - - GUITextBlock textBlock = new GUITextBlock( - new Rectangle(0, 0, 260, 25), - pf.Name, "", - Alignment.Left, Alignment.CenterLeft, cargoFrame, false, GUI.SmallFont); - textBlock.Padding = new Vector4(40.0f, 3.0f, 0.0f, 0.0f); - textBlock.UserData = cargoFrame; - textBlock.CanBeFocused = false; - - if (pf.sprite != null) - { - float scale = Math.Min(Math.Min(30.0f / pf.sprite.SourceRect.Width, 30.0f / pf.sprite.SourceRect.Height), 1.0f); - GUIImage img = new GUIImage(new Rectangle(-20-(int)(pf.sprite.SourceRect.Width*scale*0.5f), 12-(int)(pf.sprite.SourceRect.Height*scale*0.5f), 40, 40), pf.sprite, Alignment.Left, textBlock); - img.Color = pf.SpriteColor; - img.Scale = scale; - } - - int cargoVal = 0; - extraCargo.TryGetValue(pf.Name, out cargoVal); - var countText = new GUITextBlock( - new Rectangle(160, 0, 55, 25), - cargoVal.ToString(), - "", - Alignment.Left, Alignment.Center, textBlock); - - var incButton = new GUIButton(new Rectangle(200, 5, 15, 15), ">", "", textBlock); - incButton.UserData = countText; - incButton.OnClicked = (button, obj) => - { - int val; - if (extraCargo.TryGetValue(pf.Name, out val)) - { - extraCargo[pf.Name]++; val = extraCargo[pf.Name]; - } - else - { - extraCargo.Add(pf.Name,1); val = 1; - } - ((GUITextBlock)obj).Text = val.ToString(); - ((GUITextBlock)obj).SetTextPos(); - return true; - }; - - var decButton = new GUIButton(new Rectangle(160, 5, 15, 15), "<", "", textBlock); - decButton.UserData = countText; - decButton.OnClicked = (button, obj) => - { - int val; - if (extraCargo.TryGetValue(pf.Name, out val)) - { - extraCargo[pf.Name]--; - val = extraCargo[pf.Name]; - if (val <= 0) - { - extraCargo.Remove(pf.Name); - val = 0; - } - ((GUITextBlock)obj).Text = val.ToString(); - ((GUITextBlock)obj).SetTextPos(); - } - - return true; - }; - } - - - //-------------------------------------------------------------------------------- - // server settings - //-------------------------------------------------------------------------------- - - y = 0; - - - var startIntervalText = new GUITextBlock(new Rectangle(-10, y, 100, 20), "Autorestart delay", "", settingsTabs[1]); - var startIntervalSlider = new GUIScrollBar(new Rectangle(10, y + 22, 100, 15), "", 0.1f, settingsTabs[1]); - startIntervalSlider.UserData = startIntervalText; - startIntervalSlider.Step = 0.05f; - startIntervalSlider.BarScroll = AutoRestartInterval / 300.0f; - startIntervalSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) => - { - GUITextBlock text = scrollBar.UserData as GUITextBlock; - - AutoRestartInterval = Math.Max(barScroll * 300.0f, 10.0f); - - text.Text = "Autorestart delay: " + ToolBox.SecondsToReadableTime(AutoRestartInterval); - return true; - }; - startIntervalSlider.OnMoved(startIntervalSlider, startIntervalSlider.BarScroll); - - y += 45; - - var allowSpecBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Allow spectating", Alignment.Left, settingsTabs[1]); - allowSpecBox.Selected = AllowSpectating; - allowSpecBox.OnSelected = (GUITickBox) => - { - AllowSpectating = GUITickBox.Selected; - return true; - }; - - y += 40; - - var voteKickBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Allow vote kicking", Alignment.Left, settingsTabs[1]); - voteKickBox.Selected = Voting.AllowVoteKick; - voteKickBox.OnSelected = (GUITickBox) => - { - Voting.AllowVoteKick = !Voting.AllowVoteKick; - GameMain.Server.UpdateVoteStatus(); - return true; - }; - - var kickVotesRequiredText = new GUITextBlock(new Rectangle(20, y + 20, 20, 20), "Votes required: 50 %", "", settingsTabs[1], GUI.SmallFont); - - var kickVoteSlider = new GUIScrollBar(new Rectangle(150, y + 22, 100, 15), "", 0.1f, settingsTabs[1]); - kickVoteSlider.UserData = kickVotesRequiredText; - kickVoteSlider.Step = 0.2f; - kickVoteSlider.BarScroll = (KickVoteRequiredRatio - 0.5f) * 2.0f; - kickVoteSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) => - { - GUITextBlock voteText = scrollBar.UserData as GUITextBlock; - - KickVoteRequiredRatio = barScroll / 2.0f + 0.5f; - voteText.Text = "Votes required: " + (int)MathUtils.Round(KickVoteRequiredRatio * 100.0f, 10.0f) + " %"; - return true; - }; - kickVoteSlider.OnMoved(kickVoteSlider, kickVoteSlider.BarScroll); - - y += 45; - - var shareSubsBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Share submarine files with players", Alignment.Left, settingsTabs[1]); - shareSubsBox.Selected = AllowFileTransfers; - shareSubsBox.OnSelected = (GUITickBox) => - { - AllowFileTransfers = GUITickBox.Selected; - return true; - }; - - y += 40; - - var randomizeLevelBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Randomize level seed between rounds", Alignment.Left, settingsTabs[1]); - randomizeLevelBox.Selected = RandomizeSeed; - randomizeLevelBox.OnSelected = (GUITickBox) => - { - RandomizeSeed = GUITickBox.Selected; - return true; - }; - - y += 40; - - var saveLogsBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Save server logs", Alignment.Left, settingsTabs[1]); - saveLogsBox.Selected = SaveServerLogs; - saveLogsBox.OnSelected = (GUITickBox) => - { - SaveServerLogs = GUITickBox.Selected; - showLogButton.Visible = SaveServerLogs; - return true; - }; - - - //-------------------------------------------------------------------------------- - // banlist - //-------------------------------------------------------------------------------- - - - banList.CreateBanFrame(settingsTabs[2]); - - //-------------------------------------------------------------------------------- - // whitelist - //-------------------------------------------------------------------------------- - - whitelist.CreateWhiteListFrame(settingsTabs[3]); - - } - public void LoadClientPermissions() { if (!File.Exists(ClientPermissionsFile)) return; @@ -759,110 +356,5 @@ namespace Barotrauma.Networking DebugConsole.ThrowError("Saving client permissions to " + ClientPermissionsFile + " failed", e); } } - - private bool SwitchSubSelection(GUITickBox tickBox) - { - subSelectionMode = (SelectionMode)tickBox.UserData; - - foreach (GUIComponent otherTickBox in tickBox.Parent.children) - { - if (otherTickBox == tickBox) continue; - ((GUITickBox)otherTickBox).Selected = false; - } - - Voting.AllowSubVoting = subSelectionMode == SelectionMode.Vote; - - if (subSelectionMode == SelectionMode.Random) - { - GameMain.NetLobbyScreen.SubList.Select(Rand.Range(0, GameMain.NetLobbyScreen.SubList.CountChildren)); - } - - return true; - } - - private bool SelectSettingsTab(GUIButton button, object obj) - { - settingsTabIndex = (int)obj; - - for (int i = 0; i < settingsTabs.Length; i++ ) - { - settingsTabs[i].Visible = i == settingsTabIndex; - } - - return true; - } - - private bool SwitchModeSelection(GUITickBox tickBox) - { - modeSelectionMode = (SelectionMode)tickBox.UserData; - - foreach (GUIComponent otherTickBox in tickBox.Parent.children) - { - if (otherTickBox == tickBox) continue; - ((GUITickBox)otherTickBox).Selected = false; - } - - Voting.AllowModeVoting = modeSelectionMode == SelectionMode.Vote; - - if (modeSelectionMode == SelectionMode.Random) - { - GameMain.NetLobbyScreen.ModeList.Select(Rand.Range(0, GameMain.NetLobbyScreen.ModeList.CountChildren)); - } - - return true; - } - - - public bool ToggleSettingsFrame(GUIButton button, object obj) - { - if (settingsFrame==null) - { - CreateSettingsFrame(); - } - else - { - settingsFrame = null; - SaveSettings(); - } - - return false; - } - - public void ManagePlayersFrame(GUIFrame infoFrame) - { - GUIListBox cList = new GUIListBox(new Rectangle(0, 0, 0, 300), Color.White * 0.7f, "", infoFrame); - cList.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f); - //crewList.OnSelected = SelectCrewCharacter; - - foreach (Client c in ConnectedClients) - { - GUIFrame frame = new GUIFrame(new Rectangle(0, 0, 0, 40), Color.Transparent, null, cList); - frame.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f); - frame.Color = (c.inGame && c.Character!=null && !c.Character.IsDead) ? Color.Gold * 0.2f : Color.Transparent; - frame.HoverColor = Color.LightGray * 0.5f; - frame.SelectedColor = Color.Gold * 0.5f; - - GUITextBlock textBlock = new GUITextBlock( - new Rectangle(40, 0, 0, 25), - c.name + " (" + c.Connection.RemoteEndPoint.Address.ToString() + ")", - Color.Transparent, Color.White, - Alignment.Left, Alignment.Left, - null, frame); - - var banButton = new GUIButton(new Rectangle(-110, 0, 100, 20), "Ban", Alignment.Right | Alignment.CenterY, "", frame); - banButton.UserData = c.name; - banButton.OnClicked = GameMain.NetLobbyScreen.BanPlayer; - - var rangebanButton = new GUIButton(new Rectangle(-220, 0, 100, 20), "Ban range", Alignment.Right | Alignment.CenterY, "", frame); - rangebanButton.UserData = c.name; - rangebanButton.OnClicked = GameMain.NetLobbyScreen.BanPlayerRange; - - var kickButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Kick", Alignment.Right | Alignment.CenterY, "", frame); - kickButton.UserData = c.name; - kickButton.OnClicked = GameMain.NetLobbyScreen.KickPlayer; - - textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f); - } - } } } diff --git a/BarotraumaShared/Source/Networking/NetworkMember.cs b/BarotraumaShared/Source/Networking/NetworkMember.cs index a58273954..8b65f9bf6 100644 --- a/BarotraumaShared/Source/Networking/NetworkMember.cs +++ b/BarotraumaShared/Source/Networking/NetworkMember.cs @@ -66,7 +66,7 @@ namespace Barotrauma.Networking Kick } - abstract class NetworkMember + abstract partial class NetworkMember { #if DEBUG public Dictionary messageCount = new Dictionary(); @@ -83,10 +83,6 @@ namespace Barotrauma.Networking protected TimeSpan updateInterval; protected DateTime updateTimer; - protected GUIFrame inGameHUD; - protected GUIListBox chatBox; - protected GUITextBox chatMsgBox; - public int EndVoteCount, EndVoteMax; //private GUITextBlock endVoteText; @@ -130,11 +126,6 @@ namespace Barotrauma.Networking get { return gameStarted; } } - public GUIFrame InGameHUD - { - get { return inGameHUD; } - } - public virtual List ConnectedClients { get { return null; } @@ -142,52 +133,11 @@ namespace Barotrauma.Networking public NetworkMember() { - inGameHUD = new GUIFrame(new Rectangle(0,0,0,0), null, null); - inGameHUD.CanBeFocused = false; - - int width = (int)MathHelper.Clamp(GameMain.GraphicsWidth * 0.35f, 350, 500); - int height = (int)MathHelper.Clamp(GameMain.GraphicsHeight * 0.15f, 100, 200); - chatBox = new GUIListBox(new Rectangle( - GameMain.GraphicsWidth - 20 - width, - GameMain.GraphicsHeight - 40 - 25 - height, - width, height), - Color.White * 0.5f, "", inGameHUD); - chatBox.Padding = Vector4.Zero; - - chatMsgBox = new GUITextBox( - new Rectangle(chatBox.Rect.X, chatBox.Rect.Y + chatBox.Rect.Height + 20, chatBox.Rect.Width, 25), - Color.White * 0.5f, Color.Black, Alignment.TopLeft, Alignment.Left, "", inGameHUD); - chatMsgBox.Font = GUI.SmallFont; - chatMsgBox.MaxTextLength = ChatMessage.MaxLength; - chatMsgBox.Padding = Vector4.Zero; - chatMsgBox.OnEnterPressed = EnterChatMessage; - chatMsgBox.OnTextChanged = TypingChatMessage; - + InitProjSpecific(); + Voting = new Voting(); } - public bool TypingChatMessage(GUITextBox textBox, string text) - { - string tempStr; - string command = ChatMessage.GetChatMessageCommand(text, out tempStr); - switch (command) - { - case "r": - case "radio": - textBox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Radio]; - break; - case "d": - case "dead": - textBox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Dead]; - break; - default: - textBox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Default]; - break; - } - - return true; - } - public bool CanUseRadio(Character sender) { if (sender == null) return false; @@ -200,26 +150,6 @@ namespace Barotrauma.Networking return radioComponent.HasRequiredContainedItems(false); } - public bool EnterChatMessage(GUITextBox textBox, string message) - { - textBox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Default]; - - if (string.IsNullOrWhiteSpace(message)) return false; - - if (this == GameMain.Server) - { - GameMain.Server.SendChatMessage(message, null, null); - } - else if (this == GameMain.Client) - { - GameMain.Client.SendChatMessage(message); - } - - if (textBox == chatMsgBox) textBox.Deselect(); - - return true; - } - public void AddChatMessage(string message, ChatMessageType type, string senderName="", Character senderCharacter = null) { AddChatMessage(ChatMessage.Create(senderName, message, type, senderCharacter)); @@ -236,6 +166,7 @@ namespace Barotrauma.Networking message.Sender.ShowSpeechBubble(2.0f, ChatMessage.MessageColor[(int)message.Type]); } +#if CLIENT GameMain.NetLobbyScreen.NewChatMessage(message); while (chatBox.CountChildren > 20) @@ -273,20 +204,14 @@ namespace Barotrauma.Networking } GUI.PlayUISound(soundType); +#endif } public virtual void KickPlayer(string kickedName, bool ban, bool range = false) { } - public virtual void AddToGUIUpdateList() - { - if (gameStarted && Screen.Selected == GameMain.GameScreen) - { - inGameHUD.AddToGUIUpdateList(); - } - } - public virtual void Update(float deltaTime) { +#if CLIENT if (gameStarted && Screen.Selected == GameMain.GameScreen) { chatMsgBox.Visible = Character.Controlled == null || Character.Controlled.CanSpeak; @@ -314,58 +239,7 @@ namespace Barotrauma.Networking chatMsgBox.Select(); } } - } - - public virtual void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch) - { - if (!gameStarted || Screen.Selected != GameMain.GameScreen) return; - - GameMain.GameSession.CrewManager.Draw(spriteBatch); - - inGameHUD.Draw(spriteBatch); - - if (EndVoteCount > 0) - { - if (GameMain.NetworkMember.myCharacter == null) - { - GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - 180.0f, 40), - "Votes to end the round (y/n): " + EndVoteCount + "/" + (EndVoteMax - EndVoteCount), Color.White, null, 0, GUI.SmallFont); - } - else - { - GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - 140.0f, 40), - "Votes (y/n): " + EndVoteCount + "/" + (EndVoteMax - EndVoteCount), Color.White, null, 0, GUI.SmallFont); - } - } - - if (respawnManager != null) - { - string respawnInfo = ""; - - if (respawnManager.CurrentState == RespawnManager.State.Waiting && - respawnManager.CountdownStarted) - { - respawnInfo = respawnManager.RespawnTimer <= 0.0f ? "" : "Respawn Shuttle dispatching in " + ToolBox.SecondsToReadableTime(respawnManager.RespawnTimer); - - } - else if (respawnManager.CurrentState == RespawnManager.State.Transporting) - { - respawnInfo = respawnManager.TransportTimer <= 0.0f ? "" : "Shuttle leaving in " + ToolBox.SecondsToReadableTime(respawnManager.TransportTimer); - } - - if (!string.IsNullOrEmpty(respawnInfo)) - { - GUI.DrawString(spriteBatch, - new Vector2(120.0f, 10), - respawnInfo, Color.White, null, 0, GUI.SmallFont); - } - - } - } - - public virtual bool SelectCrewCharacter(Character character, GUIComponent crewFrame) - { - return false; +#endif } public virtual void Disconnect() { } diff --git a/BarotraumaShared/Source/Networking/ServerLog.cs b/BarotraumaShared/Source/Networking/ServerLog.cs index 1018b9527..d5113ace3 100644 --- a/BarotraumaShared/Source/Networking/ServerLog.cs +++ b/BarotraumaShared/Source/Networking/ServerLog.cs @@ -6,7 +6,7 @@ using System.Linq; namespace Barotrauma.Networking { - class ServerLog + partial class ServerLog { private struct LogMessage { @@ -56,10 +56,6 @@ namespace Barotrauma.Networking private string serverName; - public GUIFrame LogFrame; - - private GUIListBox listBox; - private readonly Queue lines; private int unsavedLineCount; @@ -88,12 +84,14 @@ namespace Barotrauma.Networking lines.Enqueue(newText); +#if CLIENT if (LogFrame != null) { AddLine(newText); listBox.UpdateScrollBarSize(); } +#endif unsavedLineCount++; @@ -108,122 +106,12 @@ namespace Barotrauma.Networking lines.Dequeue(); } +#if CLIENT while (listBox != null && listBox.children.Count > LinesPerFile) { listBox.RemoveChild(listBox.children[0]); - } - } - - public void CreateLogFrame() - { - LogFrame = new GUIFrame(new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.Black * 0.5f); - - GUIFrame innerFrame = new GUIFrame(new Rectangle(0, 0, 600, 420), null, Alignment.Center, "", LogFrame); - innerFrame.Padding = new Vector4(10.0f, 20.0f, 10.0f, 20.0f); - - new GUITextBlock(new Rectangle(-200, 0, 100, 15), "Filter", "", Alignment.TopRight, Alignment.CenterRight, innerFrame, false, GUI.SmallFont); - - GUITextBox searchBox = new GUITextBox(new Rectangle(-20, 0, 180, 15), Alignment.TopRight, "", innerFrame); - searchBox.Font = GUI.SmallFont; - searchBox.OnTextChanged = (textBox, text) => - { - msgFilter = text; - FilterMessages(); - return true; - }; - GUIComponent.KeyboardDispatcher.Subscriber = searchBox; - - var clearButton = new GUIButton(new Rectangle(0, 0, 15, 15), "x", Alignment.TopRight, "", innerFrame); - clearButton.OnClicked = ClearFilter; - clearButton.UserData = searchBox; - - listBox = new GUIListBox(new Rectangle(0, 30, 450, 340), "", Alignment.TopRight, innerFrame); - - int y = 30; - foreach (MessageType msgType in Enum.GetValues(typeof(MessageType))) - { - var tickBox = new GUITickBox(new Rectangle(0, y, 20, 20), messageTypeName[(int)msgType], Alignment.TopLeft, GUI.SmallFont, innerFrame); - tickBox.Selected = true; - tickBox.TextColor = messageColor[(int)msgType]; - - tickBox.OnSelected += (GUITickBox tb) => - { - msgTypeHidden[(int)msgType] = !tb.Selected; - FilterMessages(); - return true; - }; - - y += 20; } - - var currLines = lines.ToList(); - - foreach (LogMessage line in currLines) - { - AddLine(line); - } - - listBox.UpdateScrollBarSize(); - - if (listBox.BarScroll == 0.0f || listBox.BarScroll == 1.0f) listBox.BarScroll = 1.0f; - - GUIButton closeButton = new GUIButton(new Rectangle(-100, 10, 100, 15), "Close", Alignment.BottomRight, "", innerFrame); - closeButton.OnClicked = (button, userData) => - { - LogFrame = null; - return true; - }; - - msgFilter = ""; - } - - private void AddLine(LogMessage line) - { - float prevSize = listBox.BarSize; - - var textBlock = new GUITextBlock(new Rectangle(0, 0, 0, 0), line.Text, "", Alignment.TopLeft, Alignment.TopLeft, listBox, true, GUI.SmallFont); - textBlock.Rect = new Rectangle(textBlock.Rect.X, textBlock.Rect.Y, textBlock.Rect.Width, Math.Max(13, textBlock.Rect.Height)); - textBlock.TextColor = messageColor[(int)line.Type]; - textBlock.CanBeFocused = false; - textBlock.UserData = line; - - if ((prevSize == 1.0f && listBox.BarScroll == 0.0f) || (prevSize < 1.0f && listBox.BarScroll == 1.0f)) listBox.BarScroll = 1.0f; - } - - private bool FilterMessages() - { - string filter = msgFilter == null ? "" : msgFilter.ToLower(); - - foreach (GUIComponent child in listBox.children) - { - var textBlock = child as GUITextBlock; - if (textBlock == null) continue; - - child.Visible = true; - - if (msgTypeHidden[(int)((LogMessage)child.UserData).Type]) - { - child.Visible = false; - continue; - } - - textBlock.Visible = string.IsNullOrEmpty(filter) || textBlock.Text.ToLower().Contains(filter); - } - - listBox.BarScroll = 0.0f; - - return true; - } - - public bool ClearFilter(GUIComponent button, object obj) - { - var searchBox = button.UserData as GUITextBox; - if (searchBox != null) searchBox.Text = ""; - - msgFilter = ""; - FilterMessages(); - - return true; +#endif } public void Save() diff --git a/BarotraumaShared/Source/Networking/WhiteList.cs b/BarotraumaShared/Source/Networking/WhiteList.cs index e3a22253d..a0cd042f4 100644 --- a/BarotraumaShared/Source/Networking/WhiteList.cs +++ b/BarotraumaShared/Source/Networking/WhiteList.cs @@ -19,7 +19,7 @@ namespace Barotrauma.Networking } } - class WhiteList + partial class WhiteList { const string SavePath = "Data/whitelist.txt"; @@ -29,11 +29,6 @@ namespace Barotrauma.Networking get { return whitelistedPlayers; } } - private GUIComponent whitelistFrame; - - private GUITextBox nameBox; - private GUITextBox ipBox; - public bool Enabled; public WhiteList() @@ -122,103 +117,21 @@ namespace Barotrauma.Networking return true; } - public GUIComponent CreateWhiteListFrame(GUIComponent parent) + private void RemoveFromWhiteList(WhiteListedPlayer wlp) { - if (whitelistFrame!=null) - { - whitelistFrame.Parent.ClearChildren(); - whitelistFrame = null; - } - - parent.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f); - - var enabledTick = new GUITickBox(new Rectangle(0, 0, 20, 20), "Enabled", Alignment.TopLeft, parent); - enabledTick.Selected = Enabled; - enabledTick.OnSelected = (GUITickBox box) => - { - Enabled = !Enabled; - - if (Enabled) - { - foreach (Client c in GameMain.Server.ConnectedClients) - { - if (!IsWhiteListed(c.name,c.Connection.RemoteEndPoint.Address.ToString())) - { - whitelistedPlayers.Add(new WhiteListedPlayer(c.name, c.Connection.RemoteEndPoint.Address.ToString())); - if (whitelistFrame != null) CreateWhiteListFrame(whitelistFrame.Parent); - } - } - } - - Save(); - return true; - }; - - new GUITextBlock(new Rectangle(0, -35, 90, 20), "Name:", "", Alignment.BottomLeft, Alignment.CenterLeft, parent, false, GUI.Font); - nameBox = new GUITextBox(new Rectangle(100, -35, 170, 20), Alignment.BottomLeft, "", parent); - nameBox.Font = GUI.Font; - - new GUITextBlock(new Rectangle(0, 0, 90, 20), "IP Address:", "", Alignment.BottomLeft, Alignment.CenterLeft, parent, false, GUI.Font); - ipBox = new GUITextBox(new Rectangle(100, 0, 170, 20), Alignment.BottomLeft, "", parent); - ipBox.Font = GUI.Font; - - var addnewButton = new GUIButton(new Rectangle(0, 35, 150, 20), "Add to whitelist", Alignment.BottomLeft, "", parent); - addnewButton.OnClicked = AddToWhiteList; - - whitelistFrame = new GUIListBox(new Rectangle(0, 30, 0, parent.Rect.Height-110), "", parent); - - foreach (WhiteListedPlayer wlp in whitelistedPlayers) - { - string blockText = wlp.Name; - if (!string.IsNullOrWhiteSpace(wlp.IP)) blockText += " (" + wlp.IP + ")"; - GUITextBlock textBlock = new GUITextBlock( - new Rectangle(0, 0, 0, 25), - blockText, - "", - Alignment.Left, Alignment.Left, whitelistFrame); - textBlock.Padding = new Vector4(10.0f, 10.0f, 0.0f, 0.0f); - textBlock.UserData = wlp; - - var removeButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Remove", Alignment.Right | Alignment.CenterY, "", textBlock); - removeButton.UserData = wlp; - removeButton.OnClicked = RemoveFromWhiteList; - } - - return parent; - } - - private bool RemoveFromWhiteList(GUIButton button, object obj) - { - WhiteListedPlayer wlp = obj as WhiteListedPlayer; - if (wlp == null) return false; - DebugConsole.Log("Removing " + wlp.Name + " from whitelist"); GameServer.Log("Removing " + wlp.Name + " from whitelist", ServerLog.MessageType.ServerMessage); whitelistedPlayers.Remove(wlp); Save(); - - if (whitelistFrame != null) - { - whitelistFrame.Parent.ClearChildren(); - CreateWhiteListFrame(whitelistFrame.Parent); - } - - return true; } - private bool AddToWhiteList(GUIButton button, object obj) + private void AddToWhiteList(string name,string ip) { - if (string.IsNullOrWhiteSpace(nameBox.Text)) return false; - if (whitelistedPlayers.Any(x => x.Name.ToLower() == nameBox.Text.ToLower() && x.IP == ipBox.Text)) return false; - whitelistedPlayers.Add(new WhiteListedPlayer(nameBox.Text,ipBox.Text)); + if (string.IsNullOrWhiteSpace(name)) return; + if (whitelistedPlayers.Any(x => x.Name.ToLower() == name.ToLower() && x.IP == ip)) return; + whitelistedPlayers.Add(new WhiteListedPlayer(name, ip)); Save(); - - if (whitelistFrame != null) - { - CreateWhiteListFrame(whitelistFrame.Parent); - } - return true; } } } diff --git a/BarotraumaShared/Source/Utils/MathUtils.cs b/BarotraumaShared/Source/Utils/MathUtils.cs index 30d09ee5d..fbd29da62 100644 --- a/BarotraumaShared/Source/Utils/MathUtils.cs +++ b/BarotraumaShared/Source/Utils/MathUtils.cs @@ -6,6 +6,16 @@ using System.Text; namespace Barotrauma { + //TODO: perhaps find a better place for this? + [Flags] + public enum Alignment + { + CenterX = 1, Left = 2, Right = 4, CenterY = 8, Top = 16, Bottom = 32, + TopLeft = (Top | Left), TopCenter = (CenterX | Top), TopRight = (Top | Right), + CenterLeft = (Left | CenterY), Center = (CenterX | CenterY), CenterRight = (Right | CenterY), + BottomLeft = (Bottom | Left), BottomCenter = (CenterX | Bottom), BottomRight = (Bottom | Right), + } + static class MathUtils { public static Vector2 SmoothStep(Vector2 v1, Vector2 v2, float amount) @@ -533,18 +543,4 @@ namespace Barotrauma return Math.Sign(d2 - d1); } } - - class CompareSegmentPointCW : IComparer - { - private Vector2 center; - - public CompareSegmentPointCW(Vector2 center) - { - this.center = center; - } - public int Compare(Lights.SegmentPoint a, Lights.SegmentPoint b) - { - return -CompareCCW.Compare(a.WorldPos, b.WorldPos, center); - } - } } diff --git a/BarotraumaShared/Source/Utils/ToolBox.cs b/BarotraumaShared/Source/Utils/ToolBox.cs index bbf2aa6c5..5b01841f7 100644 --- a/BarotraumaShared/Source/Utils/ToolBox.cs +++ b/BarotraumaShared/Source/Utils/ToolBox.cs @@ -26,7 +26,7 @@ namespace Barotrauma } } - public static class ToolBox + public static partial class ToolBox { public static bool IsProperFilenameCase(string filename) { @@ -384,24 +384,6 @@ namespace Barotrauma return str.Substring(0, maxCharacters-3) + "..."; } - public static string LimitString(string str, ScalableFont font, int maxWidth) - { - if (maxWidth <= 0 || string.IsNullOrWhiteSpace(str)) return ""; - - float currWidth = font.MeasureString("...").X; - for (int i = 0; i < str.Length; i++ ) - { - currWidth += font.MeasureString(str[i].ToString()).X; - - if (currWidth > maxWidth) - { - return str.Substring(0, Math.Max(i - 2, 1)) + "..."; - } - } - - return str; - } - public static string RandomSeed(int length) { var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; @@ -466,75 +448,6 @@ namespace Barotrauma return d[n, m]; } - public static string WrapText(string text, float lineLength, ScalableFont font, float textScale = 1.0f) //TODO: could integrate this into the ScalableFont class directly - { - if (font.MeasureString(text).X < lineLength) return text; - - text = text.Replace("\n", " \n "); - - string[] words = text.Split(' '); - - StringBuilder wrappedText = new StringBuilder(); - float linePos = 0f; - float spaceWidth = font.MeasureString(" ").X * textScale; - for (int i = 0; i < words.Length; ++i) - { - if (string.IsNullOrWhiteSpace(words[i]) && words[i] != "\n") continue; - - Vector2 size = font.MeasureString(words[i]) * textScale; - if (size.X > lineLength) - { - if (linePos == 0.0f) - { - wrappedText.AppendLine(words[i]); - } - else - { - do - { - if (words[i].Length == 0) break; - - wrappedText.Append(words[i][0]); - words[i] = words[i].Remove(0, 1); - - linePos += size.X; - } while (words[i].Length > 0 && (size = font.MeasureString((words[i][0]).ToString()) * textScale).X + linePos < lineLength); - - wrappedText.Append("\n"); - linePos = 0.0f; - i--; - } - - continue; - } - - if (linePos + size.X < lineLength) - { - wrappedText.Append(words[i]); - if (words[i] == "\n") - { - linePos = 0.0f; - } - else - { - - linePos += size.X + spaceWidth; - } - } - else - { - wrappedText.Append("\n"); - wrappedText.Append(words[i]); - - linePos = size.X + spaceWidth; - } - - if (i < words.Length - 1) wrappedText.Append(" "); - } - - return wrappedText.ToString(); - } - public static string SecondsToReadableTime(float seconds) { if (seconds < 60.0f) diff --git a/Hyper.ComponentModel/Hyper.ComponentModel.csproj b/Hyper.ComponentModel/Hyper.ComponentModel.csproj index 40cc4e68e..b2c9b109b 100644 --- a/Hyper.ComponentModel/Hyper.ComponentModel.csproj +++ b/Hyper.ComponentModel/Hyper.ComponentModel.csproj @@ -9,8 +9,9 @@ Properties Hyper.ComponentModel Hyper.ComponentModel - v3.5 + v4.5 512 + true @@ -20,6 +21,8 @@ DEBUG;TRACE prompt 4 + false + x86 pdbonly @@ -29,6 +32,8 @@ prompt 4 bin\Release\Hyper.ComponentModel.XML + false + x86