Further separation of client-specific code

Still not done here, just gonna push a commit now so I can pull this from elsewhere.
This commit is contained in:
juanjp600
2017-06-16 16:02:07 -03:00
parent e4a878113f
commit 7168a534ed
64 changed files with 3733 additions and 2954 deletions

View File

@@ -68,10 +68,27 @@
<Compile Include="Source\Characters\BackgroundSprite\BackgroundCreaturePrefab.cs" />
<Compile Include="Source\Characters\BackgroundSprite\BackgroundSpriteManager.cs" />
<Compile Include="Source\Characters\BackgroundSprite\BackgroundSpritePrefab.cs" />
<Compile Include="Source\Characters\Character.cs" />
<Compile Include="Source\Characters\CharacterHUD.cs" />
<Compile Include="Source\Characters\CharacterInfo.cs" />
<Compile Include="Source\Characters\CharacterSound.cs" />
<Compile Include="Source\Characters\HUDProgressBar.cs" />
<Compile Include="Source\Characters\Jobs\JobPrefab.cs" />
<Compile Include="Source\Characters\Limb.cs" />
<Compile Include="Source\DebugConsole.cs" />
<Compile Include="Source\EventInput\EventInput.cs" />
<Compile Include="Source\EventInput\KeyboardDispatcher.cs" />
<Compile Include="Source\Fonts\ScalableFont.cs" />
<Compile Include="Source\GameMain.cs" />
<Compile Include="Source\GameSession\CrewManager.cs" />
<Compile Include="Source\GameSession\GameModes\SinglePlayerMode.cs" />
<Compile Include="Source\GameSession\GameModes\Tutorials\BasicTutorial.cs" />
<Compile Include="Source\GameSession\GameModes\Tutorials\EditorTutorial.cs" />
<Compile Include="Source\GameSession\GameModes\Tutorials\TutorialMode.cs" />
<Compile Include="Source\GameSession\GameModes\Tutorials\TutorialType.cs" />
<Compile Include="Source\GameSession\GameSession.cs" />
<Compile Include="Source\GameSession\ShiftSummary.cs" />
<Compile Include="Source\GameSettings.cs" />
<Compile Include="Source\GUI\ComponentStyle.cs" />
<Compile Include="Source\GUI\GUI.cs" />
<Compile Include="Source\GUI\GUIButton.cs" />
@@ -89,10 +106,19 @@
<Compile Include="Source\GUI\GUITextBox.cs" />
<Compile Include="Source\GUI\GUITickBox.cs" />
<Compile Include="Source\GUI\LoadingScreen.cs" />
<Compile Include="Source\Items\CharacterInventory.cs" />
<Compile Include="Source\Items\Components\ItemLabel.cs" />
<Compile Include="Source\Items\FixRequirement.cs" />
<Compile Include="Source\Items\Inventory.cs" />
<Compile Include="Source\Items\Item.cs" />
<Compile Include="Source\Map\MapEntity.cs" />
<Compile Include="Source\Map\MapEntityPrefab.cs" />
<Compile Include="Source\Map\Structure.cs" />
<Compile Include="Source\Map\StructurePrefab.cs" />
<Compile Include="Source\Map\WayPoint.cs" />
<Compile Include="Source\Networking\GameClient.cs" />
<Compile Include="Source\Networking\GameServer.cs" />
<Compile Include="Source\Networking\Voting.cs" />
<Compile Include="Source\Particles\Particle.cs" />
<Compile Include="Source\Particles\ParticleEmitter.cs" />
<Compile Include="Source\Particles\ParticleManager.cs" />

View File

@@ -0,0 +1,256 @@
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Joints;
using Barotrauma.Networking;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Particles;
namespace Barotrauma
{
partial class Character : Entity, IDamageable, IPropertyObject, IClientSerializable, IServerSerializable
{
private List<CharacterSound> sounds;
//the Character that the player is currently controlling
private static Character controlled;
public static Character Controlled
{
get { return controlled; }
set
{
if (controlled == value) return;
controlled = value;
CharacterHUD.Reset();
if (controlled != null)
{
controlled.Enabled = true;
}
}
}
private Dictionary<object, HUDProgressBar> hudProgressBars;
public Dictionary<object, HUDProgressBar> HUDProgressBars
{
get { return hudProgressBars; }
}
private void InitProjSpecific(XDocument doc)
{
for (int i = 0; i < Enum.GetNames(typeof(InputType)).Length; i++)
{
keys[i] = new Key(GameMain.Config.KeyBind((InputType)i));
}
var soundElements = doc.Root.Elements("sound").ToList();
sounds = new List<CharacterSound>();
foreach (XElement soundElement in soundElements)
{
sounds.Add(new CharacterSound(soundElement));
}
hudProgressBars = new Dictionary<object, HUDProgressBar>();
}
public static void AddAllToGUIUpdateList()
{
for (int i = 0; i < CharacterList.Count; i++)
{
CharacterList[i].AddToGUIUpdateList();
}
}
public virtual void AddToGUIUpdateList()
{
if (controlled == this)
{
CharacterHUD.AddToGUIUpdateList(this);
}
}
private void UpdateControlled(float deltaTime)
{
if (controlled == this)
{
Lights.LightManager.ViewTarget = this;
CharacterHUD.Update(deltaTime, this);
foreach (HUDProgressBar progressBar in hudProgressBars.Values)
{
progressBar.Update(deltaTime);
}
foreach (var pb in hudProgressBars.Where(pb => pb.Value.FadeTimer <= 0.0f).ToList())
{
hudProgressBars.Remove(pb.Key);
}
}
}
public void Draw(SpriteBatch spriteBatch)
{
if (!Enabled) return;
AnimController.Draw(spriteBatch);
}
public void DrawHUD(SpriteBatch spriteBatch, Camera cam)
{
CharacterHUD.Draw(spriteBatch, this, cam);
}
public virtual void DrawFront(SpriteBatch spriteBatch, Camera cam)
{
if (!Enabled) return;
if (GameMain.DebugDraw)
{
AnimController.DebugDraw(spriteBatch);
if (aiTarget != null) aiTarget.Draw(spriteBatch);
}
/*if (memPos != null && memPos.Count > 0 && controlled == this)
{
PosInfo serverPos = memPos.Last();
Vector2 remoteVec = ConvertUnits.ToDisplayUnits(serverPos.Position);
if (Submarine != null)
{
remoteVec += Submarine.DrawPosition;
}
remoteVec.Y = -remoteVec.Y;
PosInfo localPos = memLocalPos.Find(m => m.ID == serverPos.ID);
int mpind = memLocalPos.FindIndex(lp => lp.ID == localPos.ID);
PosInfo localPos1 = mpind > 0 ? memLocalPos[mpind - 1] : null;
PosInfo localPos2 = mpind < memLocalPos.Count-1 ? memLocalPos[mpind + 1] : null;
Vector2 localVec = ConvertUnits.ToDisplayUnits(localPos.Position);
Vector2 localVec1 = localPos1 != null ? ConvertUnits.ToDisplayUnits(((PosInfo)localPos1).Position) : Vector2.Zero;
Vector2 localVec2 = localPos2 != null ? ConvertUnits.ToDisplayUnits(((PosInfo)localPos2).Position) : Vector2.Zero;
if (Submarine != null)
{
localVec += Submarine.DrawPosition;
localVec1 += Submarine.DrawPosition;
localVec2 += Submarine.DrawPosition;
}
localVec.Y = -localVec.Y;
localVec1.Y = -localVec1.Y;
localVec2.Y = -localVec2.Y;
//GUI.DrawLine(spriteBatch, remoteVec, localVec, Color.Yellow, 0, 10);
if (localPos1 != null) GUI.DrawLine(spriteBatch, remoteVec, localVec1, Color.Lime, 0, 2);
if (localPos2 != null) GUI.DrawLine(spriteBatch, remoteVec + Vector2.One, localVec2 + Vector2.One, Color.Red, 0, 2);
}
Vector2 mouseDrawPos = CursorWorldPosition;
mouseDrawPos.Y = -mouseDrawPos.Y;
GUI.DrawLine(spriteBatch, mouseDrawPos - new Vector2(0, 5), mouseDrawPos + new Vector2(0, 5), Color.Red, 0, 10);
Vector2 closestItemPos = closestItem != null ? closestItem.DrawPosition : Vector2.Zero;
closestItemPos.Y = -closestItemPos.Y;
GUI.DrawLine(spriteBatch, closestItemPos - new Vector2(0, 5), closestItemPos + new Vector2(0, 5), Color.Lime, 0, 10);*/
if (this == controlled || GUI.DisableHUD) return;
Vector2 pos = DrawPosition;
pos.Y = -pos.Y;
if (speechBubbleTimer > 0.0f)
{
GUI.SpeechBubbleIcon.Draw(spriteBatch, pos - Vector2.UnitY * 100.0f,
speechBubbleColor * Math.Min(speechBubbleTimer, 1.0f), 0.0f,
Math.Min((float)speechBubbleTimer, 1.0f));
}
if (this == controlled) return;
if (info != null)
{
Vector2 namePos = new Vector2(pos.X, pos.Y - 110.0f - (5.0f / cam.Zoom)) - GUI.Font.MeasureString(Info.Name) * 0.5f / cam.Zoom;
Color nameColor = Color.White;
if (Character.Controlled != null && TeamID != Character.Controlled.TeamID)
{
nameColor = Color.Red;
}
GUI.Font.DrawString(spriteBatch, Info.Name, namePos + new Vector2(1.0f / cam.Zoom, 1.0f / cam.Zoom), Color.Black, 0.0f, Vector2.Zero, 1.0f / cam.Zoom, SpriteEffects.None, 0.001f);
GUI.Font.DrawString(spriteBatch, Info.Name, namePos, nameColor, 0.0f, Vector2.Zero, 1.0f / cam.Zoom, SpriteEffects.None, 0.0f);
if (GameMain.DebugDraw)
{
GUI.Font.DrawString(spriteBatch, ID.ToString(), namePos - new Vector2(0.0f, 20.0f), Color.White);
}
}
if (isDead) return;
if (health < maxHealth * 0.98f)
{
Vector2 healthBarPos = new Vector2(pos.X - 50, DrawPosition.Y + 100.0f);
GUI.DrawProgressBar(spriteBatch, healthBarPos, new Vector2(100.0f, 15.0f), health / maxHealth, Color.Lerp(Color.Red, Color.Green, health / maxHealth) * 0.8f);
}
}
/// <summary>
/// Creates a progress bar that's "linked" to the specified object (or updates an existing one if there's one already linked to the object)
/// The progress bar will automatically fade out after 1 sec if the method hasn't been called during that time
/// </summary>
public HUDProgressBar UpdateHUDProgressBar(object linkedObject, Vector2 worldPosition, float progress, Color emptyColor, Color fullColor)
{
if (controlled != this) return null;
HUDProgressBar progressBar = null;
if (!hudProgressBars.TryGetValue(linkedObject, out progressBar))
{
progressBar = new HUDProgressBar(worldPosition, Submarine, emptyColor, fullColor);
hudProgressBars.Add(linkedObject, progressBar);
}
progressBar.WorldPosition = worldPosition;
progressBar.FadeTimer = Math.Max(progressBar.FadeTimer, 1.0f);
progressBar.Progress = progress;
return progressBar;
}
public void PlaySound(CharacterSound.SoundType soundType)
{
if (sounds == null || sounds.Count == 0) return;
var matchingSounds = sounds.FindAll(s => s.Type == soundType);
if (matchingSounds.Count == 0) return;
var selectedSound = matchingSounds[Rand.Int(matchingSounds.Count)];
selectedSound.Sound.Play(1.0f, selectedSound.Range, AnimController.WorldPosition);
}
private void ImplodeFX()
{
Vector2 centerOfMass = AnimController.GetCenterOfMass();
SoundPlayer.PlaySound("implode", 1.0f, 150.0f, WorldPosition);
for (int i = 0; i < 10; i++)
{
Particle p = GameMain.ParticleManager.CreateParticle("waterblood",
ConvertUnits.ToDisplayUnits(centerOfMass) + Rand.Vector(5.0f),
Rand.Vector(10.0f));
if (p != null) p.Size *= 2.0f;
GameMain.ParticleManager.CreateParticle("bubbles",
ConvertUnits.ToDisplayUnits(centerOfMass) + Rand.Vector(5.0f),
new Vector2(Rand.Range(-50f, 50f), Rand.Range(-100f, 50f)));
}
}
}
}

View File

@@ -0,0 +1,75 @@
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
{
partial class CharacterInfo
{
public GUIFrame CreateInfoFrame(Rectangle rect)
{
GUIFrame frame = new GUIFrame(rect, Color.Transparent);
frame.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
return CreateInfoFrame(frame);
}
public GUIFrame CreateInfoFrame(GUIFrame frame)
{
new GUIImage(new Rectangle(0, 0, 30, 30), HeadSprite, Alignment.TopLeft, frame);
ScalableFont font = frame.Rect.Width < 280 ? GUI.SmallFont : GUI.Font;
int x = 0, y = 0;
new GUITextBlock(new Rectangle(x + 60, y, 200, 20), Name, "", frame, font);
y += 20;
if (Job != null)
{
new GUITextBlock(new Rectangle(x + 60, y, 200, 20), Job.Name, "", frame, font);
y += 30;
var skills = Job.Skills;
skills.Sort((s1, s2) => -s1.Level.CompareTo(s2.Level));
new GUITextBlock(new Rectangle(x, y, 200, 20), "Skills:", "", frame, font);
y += 20;
foreach (Skill skill in skills)
{
Color textColor = Color.White * (0.5f + skill.Level / 200.0f);
new GUITextBlock(new Rectangle(x, y, 200, 20), skill.Name, Color.Transparent, textColor, Alignment.Left, "", frame).Font = font;
new GUITextBlock(new Rectangle(x, y, 200, 20), skill.Level.ToString(), Color.Transparent, textColor, Alignment.Right, "", frame).Font = font;
y += 20;
}
}
return frame;
}
public GUIFrame CreateCharacterFrame(GUIComponent parent, string text, object userData)
{
GUIFrame frame = new GUIFrame(new Rectangle(0, 0, 0, 40), Color.Transparent, "ListBoxElement", parent);
frame.UserData = userData;
GUITextBlock textBlock = new GUITextBlock(
new Rectangle(40, 0, 0, 25),
text,
null, null,
Alignment.Left, Alignment.Left,
"", frame, false);
textBlock.Font = GUI.SmallFont;
textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
new GUIImage(new Rectangle(-5, -5, 0, 0), HeadSprite, Alignment.Left, frame);
return frame;
}
}
}

View File

@@ -0,0 +1,57 @@
using Microsoft.Xna.Framework;
using System.Collections.Generic;
using System.Globalization;
using System.Xml.Linq;
using System.Linq;
namespace Barotrauma
{
partial class JobPrefab
{
public GUIFrame CreateInfoFrame()
{
int width = 500, height = 400;
GUIFrame backFrame = new GUIFrame(Rectangle.Empty, Color.Black * 0.5f);
backFrame.Padding = Vector4.Zero;
GUIFrame frame = new GUIFrame(new Rectangle(GameMain.GraphicsWidth / 2 - width / 2, GameMain.GraphicsHeight / 2 - height / 2, width, height), "", backFrame);
frame.Padding = new Vector4(30.0f, 30.0f, 30.0f, 30.0f);
new GUITextBlock(new Rectangle(0, 0, 100, 20), Name, "", Alignment.TopLeft, Alignment.TopLeft, frame, false, GUI.LargeFont);
var descriptionBlock = new GUITextBlock(new Rectangle(0, 40, 0, 0), Description, "", Alignment.TopLeft, Alignment.TopLeft, frame, true, GUI.SmallFont);
new GUITextBlock(new Rectangle(0, 40 + descriptionBlock.Rect.Height + 20, 100, 20), "Skills: ", "", Alignment.TopLeft, Alignment.TopLeft, frame, false, GUI.LargeFont);
int y = 40 + descriptionBlock.Rect.Height + 50;
foreach (SkillPrefab skill in Skills)
{
string skillDescription = Skill.GetLevelName((int)skill.LevelRange.X);
string skillDescription2 = Skill.GetLevelName((int)skill.LevelRange.Y);
if (skillDescription2 != skillDescription)
{
skillDescription += "/" + skillDescription2;
}
new GUITextBlock(new Rectangle(0, y, 100, 20),
" - " + skill.Name + ": " + skillDescription, "", Alignment.TopLeft, Alignment.TopLeft, frame, false, GUI.SmallFont);
y += 20;
}
new GUITextBlock(new Rectangle(250, 40 + descriptionBlock.Rect.Height + 20, 0, 20), "Items: ", "", Alignment.TopLeft, Alignment.TopLeft, frame, false, GUI.LargeFont);
y = 40 + descriptionBlock.Rect.Height + 50;
foreach (string itemName in ItemNames)
{
new GUITextBlock(new Rectangle(250, y, 100, 20),
" - " + itemName, "", Alignment.TopLeft, Alignment.TopLeft, frame, false, GUI.SmallFont);
y += 20;
}
return backFrame;
}
}
}

View File

@@ -0,0 +1,95 @@
using System;
using System.Xml.Linq;
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Joints;
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;
namespace Barotrauma
{
partial class Limb
{
Sound hitSound;
public Sound HitSound
{
get { return hitSound; }
}
public void Draw(SpriteBatch spriteBatch)
{
float brightness = 1.0f - (burnt / 100.0f) * 0.5f;
Color color = new Color(brightness, brightness, brightness);
body.Dir = Dir;
bool hideLimb = wearingItems.Any(w => w != null && w.HideLimb);
if (!hideLimb)
{
body.Draw(spriteBatch, sprite, color, null, scale);
}
else
{
body.UpdateDrawPosition();
}
if (LightSource != null)
{
LightSource.Position = body.DrawPosition;
}
foreach (WearableSprite wearable in wearingItems)
{
SpriteEffects spriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
Vector2 origin = wearable.Sprite.Origin;
if (body.Dir == -1.0f) origin.X = wearable.Sprite.SourceRect.Width - origin.X;
float depth = sprite.Depth - 0.000001f;
if (wearable.DepthLimb != LimbType.None)
{
Limb depthLimb = character.AnimController.GetLimb(wearable.DepthLimb);
if (depthLimb != null)
{
depth = depthLimb.sprite.Depth - 0.000001f;
}
}
wearable.Sprite.Draw(spriteBatch,
new Vector2(body.DrawPosition.X, -body.DrawPosition.Y),
color, origin,
-body.DrawRotation,
scale, spriteEffect, depth);
}
if (damage > 0.0f && damagedSprite != null && !hideLimb)
{
SpriteEffects spriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
float depth = sprite.Depth - 0.0000015f;
damagedSprite.Draw(spriteBatch,
new Vector2(body.DrawPosition.X, -body.DrawPosition.Y),
color * Math.Min(damage / 50.0f, 1.0f), sprite.Origin,
-body.DrawRotation,
1.0f, spriteEffect, depth);
}
if (!GameMain.DebugDraw) return;
if (pullJoint != null)
{
Vector2 pos = ConvertUnits.ToDisplayUnits(pullJoint.WorldAnchorB);
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 5, 5), Color.Red, true);
}
}
}
}

View File

@@ -0,0 +1,496 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Barotrauma.Networking;
using Barotrauma.Items.Components;
using System.Text;
using FarseerPhysics;
namespace Barotrauma
{
static partial class DebugConsole
{
static bool isOpen;
//used for keeping track of the message entered when pressing up/down
static int selectedIndex;
public static bool IsOpen
{
get
{
return isOpen;
}
}
static GUIFrame frame;
static GUIListBox listBox;
static GUITextBox textBox;
private static string InputText
{
get { return textBox.Text; }
set { textBox.Text = value; }
}
public static void Init(GameWindow window)
{
int x = 20, y = 20;
int width = 800, height = 500;
frame = new GUIFrame(new Rectangle(x, y, width, height), new Color(0.4f, 0.4f, 0.4f, 0.8f));
frame.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
listBox = new GUIListBox(new Rectangle(0, 0, 0, frame.Rect.Height - 40), Color.Black, "", frame);
//listBox.Color = Color.Black * 0.7f;
textBox = new GUITextBox(new Rectangle(0, 0, 0, 20), Color.Black, Color.White, Alignment.BottomLeft, Alignment.Left, "", frame);
//textBox.Color = Color.Black * 0.7f;
//messages already added before initialization -> add them to the listbox
List<ColoredText> unInitializedMessages = new List<ColoredText>(Messages);
Messages.Clear();
foreach (ColoredText msg in unInitializedMessages)
{
NewMessage(msg.Text, msg.Color);
}
NewMessage("Press F3 to open/close the debug console", Color.Cyan);
NewMessage("Enter \"help\" for a list of available console commands", Color.Cyan);
}
public static void AddToGUIUpdateList()
{
if (isOpen)
{
frame.AddToGUIUpdateList();
}
}
public static void Update(GameMain game, float deltaTime)
{
if (PlayerInput.KeyHit(Keys.F3))
{
isOpen = !isOpen;
if (isOpen)
{
textBox.Select();
AddToGUIUpdateList();
}
else
{
GUIComponent.ForceMouseOn(null);
textBox.Deselect();
}
//keyboardDispatcher.Subscriber = (isOpen) ? textBox : null;
}
if (isOpen)
{
frame.Update(deltaTime);
Character.DisableControls = true;
if (PlayerInput.KeyHit(Keys.Up))
{
SelectMessage(-1);
}
else if (PlayerInput.KeyHit(Keys.Down))
{
SelectMessage(1);
}
//textBox.Update(deltaTime);
if (PlayerInput.KeyDown(Keys.Enter) && textBox.Text != "")
{
ExecuteCommand(textBox.Text, game);
textBox.Text = "";
//selectedIndex = messages.Count;
}
}
}
private static void SelectMessage(int direction)
{
int messageCount = listBox.children.Count;
if (messageCount == 0) return;
direction = Math.Min(Math.Max(-1, direction), 1);
selectedIndex += direction;
if (selectedIndex < 0) selectedIndex = messageCount - 1;
selectedIndex = selectedIndex % messageCount;
textBox.Text = (listBox.children[selectedIndex] as GUITextBlock).Text;
}
public static void Draw(SpriteBatch spriteBatch)
{
if (!isOpen) return;
frame.Draw(spriteBatch);
}
private static bool IsCommandPermitted(string command, GameClient client)
{
switch (command)
{
case "kick":
return client.HasPermission(ClientPermissions.Kick);
case "ban":
case "banip":
return client.HasPermission(ClientPermissions.Ban);
case "netstats":
case "help":
case "dumpids":
case "admin":
return true;
default:
return false;
}
}
private static bool ExecProjSpecific(string[] commands)
{
switch (commands[0].ToLowerInvariant())
{
case "startclient":
if (commands.Length == 1) return true;
if (GameMain.Client == null)
{
GameMain.NetworkMember = new GameClient("Name");
GameMain.Client.ConnectToServer(commands[1]);
}
break;
case "mainmenuscreen":
case "mainmenu":
case "menu":
GameMain.GameSession = null;
List<Character> characters = new List<Character>(Character.CharacterList);
foreach (Character c in characters)
{
c.Remove();
}
GameMain.MainMenuScreen.Select();
break;
case "gamescreen":
case "game":
GameMain.GameScreen.Select();
break;
case "editmapscreen":
case "editmap":
case "edit":
if (commands.Length > 1)
{
Submarine.Load(string.Join(" ", commands.Skip(1)), true);
}
GameMain.EditMapScreen.Select();
break;
case "editcharacter":
case "editchar":
GameMain.EditCharacterScreen.Select();
break;
case "controlcharacter":
case "control":
{
if (commands.Length < 2) break;
var character = FindMatchingCharacter(commands, true);
if (character != null)
{
Character.Controlled = character;
}
}
break;
case "setclientcharacter":
{
if (GameMain.Server == null) break;
int separatorIndex = Array.IndexOf(commands, ";");
if (separatorIndex == -1 || commands.Length < 4)
{
ThrowError("Invalid parameters. The command should be formatted as \"setclientcharacter [client] ; [character]\"");
break;
}
string[] commandsLeft = commands.Take(separatorIndex).ToArray();
string[] commandsRight = commands.Skip(separatorIndex).ToArray();
string clientName = String.Join(" ", commandsLeft.Skip(1));
var client = GameMain.Server.ConnectedClients.Find(c => c.name == clientName);
if (client == null)
{
ThrowError("Client \"" + clientName + "\" not found.");
}
var character = FindMatchingCharacter(commandsRight, false);
GameMain.Server.SetClientCharacter(client, character);
}
break;
case "test":
Submarine.Load("aegir mark ii", true);
GameMain.DebugDraw = true;
GameMain.LightManager.LosEnabled = false;
GameMain.EditMapScreen.Select();
break;
case "shake":
GameMain.GameScreen.Cam.Shake = 10.0f;
break;
case "losenabled":
case "los":
case "drawlos":
GameMain.LightManager.LosEnabled = !GameMain.LightManager.LosEnabled;
break;
case "lighting":
case "lightingenabled":
case "light":
case "lights":
GameMain.LightManager.LightingEnabled = !GameMain.LightManager.LightingEnabled;
break;
case "tutorial":
TutorialMode.StartTutorial(Tutorials.TutorialType.TutorialTypes[0]);
break;
case "editortutorial":
GameMain.EditMapScreen.Select();
GameMain.EditMapScreen.StartTutorial();
break;
case "lobbyscreen":
case "lobby":
GameMain.LobbyScreen.Select();
break;
case "savemap":
case "savesub":
case "save":
if (commands.Length < 2) break;
if (GameMain.EditMapScreen.CharacterMode)
{
GameMain.EditMapScreen.ToggleCharacterMode();
}
string fileName = string.Join(" ", commands.Skip(1));
if (fileName.Contains("../"))
{
DebugConsole.ThrowError("Illegal symbols in filename (../)");
return true;
}
if (Submarine.SaveCurrent(System.IO.Path.Combine(Submarine.SavePath, fileName + ".sub")))
{
NewMessage("Sub saved", Color.Green);
//Submarine.Loaded.First().CheckForErrors();
}
break;
case "loadmap":
case "loadsub":
case "load":
if (commands.Length < 2) break;
Submarine.Load(string.Join(" ", commands.Skip(1)), true);
break;
case "cleansub":
for (int i = MapEntity.mapEntityList.Count - 1; i >= 0; i--)
{
MapEntity me = MapEntity.mapEntityList[i];
if (me.SimPosition.Length() > 2000.0f)
{
DebugConsole.NewMessage("Removed " + me.Name + " (simposition " + me.SimPosition + ")", Color.Orange);
MapEntity.mapEntityList.RemoveAt(i);
}
else if (me.MoveWithLevel)
{
DebugConsole.NewMessage("Removed " + me.Name + " (MoveWithLevel==true)", Color.Orange);
MapEntity.mapEntityList.RemoveAt(i);
}
else if (me is Item)
{
Item item = me as Item;
var wire = item.GetComponent<Wire>();
if (wire == null) continue;
if (wire.GetNodes().Count > 0 && !wire.Connections.Any(c => c != null))
{
wire.Item.Drop(null);
DebugConsole.NewMessage("Dropped wire (ID: " + wire.Item.ID + ") - attached on wall but no connections found", Color.Orange);
}
}
}
break;
case "messagebox":
if (commands.Length < 3) break;
new GUIMessageBox(commands[1], commands[2]);
break;
case "debugdraw":
GameMain.DebugDraw = !GameMain.DebugDraw;
break;
case "disablehud":
case "hud":
GUI.DisableHUD = !GUI.DisableHUD;
GameMain.Instance.IsMouseVisible = !GameMain.Instance.IsMouseVisible;
break;
case "followsub":
Camera.FollowSub = !Camera.FollowSub;
break;
case "drawaitargets":
case "showaitargets":
AITarget.ShowAITargets = !AITarget.ShowAITargets;
break;
#if DEBUG
case "spamevents":
foreach (Item item in Item.ItemList)
{
for (int i = 0; i<item.components.Count; i++)
{
if (item.components[i] is IServerSerializable)
{
GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ComponentState, i });
}
var itemContainer = item.GetComponent<ItemContainer>();
if (itemContainer != null)
{
GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.InventoryState });
}
GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.Status });
item.NeedsPositionUpdate = true;
}
}
foreach (Character c in Character.CharacterList)
{
GameMain.Server.CreateEntityEvent(c, new object[] { NetEntityEvent.Type.Status });
}
foreach (Structure wall in Structure.WallList)
{
GameMain.Server.CreateEntityEvent(wall);
}
break;
case "spamchatmessages":
int msgCount = 1000;
if (commands.Length > 1) int.TryParse(commands[1], out msgCount);
int msgLength = 50;
if (commands.Length > 2) int.TryParse(commands[2], out msgLength);
for (int i = 0; i < msgCount; i++)
{
if (GameMain.Server != null)
{
GameMain.Server.SendChatMessage(ToolBox.RandomSeed(msgLength), ChatMessageType.Default);
}
else
{
GameMain.Client.SendChatMessage(ToolBox.RandomSeed(msgLength));
}
}
break;
#endif
case "cleanbuild":
GameMain.Config.MusicVolume = 0.5f;
GameMain.Config.SoundVolume = 0.5f;
DebugConsole.NewMessage("Music and sound volume set to 0.5", Color.Green);
GameMain.Config.GraphicsWidth = 0;
GameMain.Config.GraphicsHeight = 0;
GameMain.Config.WindowMode = WindowMode.Fullscreen;
DebugConsole.NewMessage("Resolution set to 0 x 0 (screen resolution will be used)", Color.Green);
DebugConsole.NewMessage("Fullscreen enabled", Color.Green);
GameSettings.VerboseLogging = false;
if (GameMain.Config.MasterServerUrl != "http://www.undertowgames.com/baromaster")
{
DebugConsole.ThrowError("MasterServerUrl \"" + GameMain.Config.MasterServerUrl + "\"!");
}
GameMain.Config.Save("config.xml");
var saveFiles = System.IO.Directory.GetFiles(SaveUtil.SaveFolder);
foreach (string saveFile in saveFiles)
{
System.IO.File.Delete(saveFile);
DebugConsole.NewMessage("Deleted " + saveFile, Color.Green);
}
if (System.IO.Directory.Exists(System.IO.Path.Combine(SaveUtil.SaveFolder, "temp")))
{
System.IO.Directory.Delete(System.IO.Path.Combine(SaveUtil.SaveFolder, "temp"), true);
DebugConsole.NewMessage("Deleted temp save folder", Color.Green);
}
if (System.IO.Directory.Exists(ServerLog.SavePath))
{
var logFiles = System.IO.Directory.GetFiles(ServerLog.SavePath);
foreach (string logFile in logFiles)
{
System.IO.File.Delete(logFile);
DebugConsole.NewMessage("Deleted " + logFile, Color.Green);
}
}
if (System.IO.File.Exists("filelist.xml"))
{
System.IO.File.Delete("filelist.xml");
DebugConsole.NewMessage("Deleted filelist", Color.Green);
}
if (System.IO.File.Exists("Submarines/TutorialSub.sub"))
{
System.IO.File.Delete("Submarines/TutorialSub.sub");
DebugConsole.NewMessage("Deleted TutorialSub from the submarine folder", Color.Green);
}
if (System.IO.File.Exists(GameServer.SettingsFile))
{
System.IO.File.Delete(GameServer.SettingsFile);
DebugConsole.NewMessage("Deleted server settings", Color.Green);
}
if (System.IO.File.Exists(GameServer.ClientPermissionsFile))
{
System.IO.File.Delete(GameServer.ClientPermissionsFile);
DebugConsole.NewMessage("Deleted client permission file", Color.Green);
}
if (System.IO.File.Exists("crashreport.txt"))
{
System.IO.File.Delete("crashreport.txt");
DebugConsole.NewMessage("Deleted crashreport.txt", Color.Green);
}
if (!System.IO.File.Exists("Content/Map/TutorialSub.sub"))
{
DebugConsole.ThrowError("TutorialSub.sub not found!");
}
break;
default:
return false; //command not found
break;
}
return true; //command found
}
}
}

View File

@@ -0,0 +1,197 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Xml.Linq;
namespace Barotrauma
{
partial class GameSession
{
private InfoFrameTab selectedTab;
private GUIButton infoButton;
private GUIFrame infoFrame;
public Map Map
{
get
{
SinglePlayerMode mode = (gameMode as SinglePlayerMode);
return (mode == null) ? null : mode.Map;
}
}
private ShiftSummary shiftSummary;
public ShiftSummary ShiftSummary
{
get { return shiftSummary; }
}
public bool LoadPrevious(GUIButton button, object obj)
{
Submarine.Unload();
SaveUtil.LoadGame(saveFile);
GameMain.LobbyScreen.Select();
return true;
}
private bool ToggleInfoFrame(GUIButton button, object obj)
{
if (infoFrame == null)
{
if (CrewManager != null && CrewManager.CrewCommander != null && CrewManager.CrewCommander.IsOpen)
{
CrewManager.CrewCommander.ToggleGUIFrame();
}
CreateInfoFrame();
SelectInfoFrameTab(null, selectedTab);
}
else
{
infoFrame = null;
}
return true;
}
public void CreateInfoFrame()
{
int width = 600, height = 400;
infoFrame = new GUIFrame(
Rectangle.Empty, Color.Black * 0.8f, null);
var innerFrame = new GUIFrame(
new Rectangle(GameMain.GraphicsWidth / 2 - width / 2, GameMain.GraphicsHeight / 2 - height / 2, width, height), "", infoFrame);
innerFrame.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
var crewButton = new GUIButton(new Rectangle(0, -30, 100, 20), "Crew", "", innerFrame);
crewButton.UserData = InfoFrameTab.Crew;
crewButton.OnClicked = SelectInfoFrameTab;
var missionButton = new GUIButton(new Rectangle(100, -30, 100, 20), "Mission", "", innerFrame);
missionButton.UserData = InfoFrameTab.Mission;
missionButton.OnClicked = SelectInfoFrameTab;
if (GameMain.Server != null)
{
var manageButton = new GUIButton(new Rectangle(200, -30, 130, 20), "Manage players", "", innerFrame);
manageButton.UserData = InfoFrameTab.ManagePlayers;
manageButton.OnClicked = SelectInfoFrameTab;
}
var closeButton = new GUIButton(new Rectangle(0, 0, 80, 20), "Close", Alignment.BottomCenter, "", innerFrame);
closeButton.OnClicked = ToggleInfoFrame;
}
private bool SelectInfoFrameTab(GUIButton button, object userData)
{
selectedTab = (InfoFrameTab)userData;
CreateInfoFrame();
switch (selectedTab)
{
case InfoFrameTab.Crew:
CrewManager.CreateCrewFrame(CrewManager.characters, infoFrame.children[0] as GUIFrame);
break;
case InfoFrameTab.Mission:
CreateMissionInfo(infoFrame.children[0] as GUIFrame);
break;
case InfoFrameTab.ManagePlayers:
GameMain.Server.ManagePlayersFrame(infoFrame.children[0] as GUIFrame);
break;
}
return true;
}
private void CreateMissionInfo(GUIFrame infoFrame)
{
if (Mission == null)
{
new GUITextBlock(new Rectangle(0, 0, 0, 50), "No mission", "", infoFrame, true);
return;
}
new GUITextBlock(new Rectangle(0, 0, 0, 40), Mission.Name, "", infoFrame, GUI.LargeFont);
new GUITextBlock(new Rectangle(0, 50, 0, 20), "Reward: " + Mission.Reward, "", infoFrame, true);
new GUITextBlock(new Rectangle(0, 70, 0, 50), Mission.Description, "", infoFrame, true);
}
public void AddToGUIUpdateList()
{
infoButton.AddToGUIUpdateList();
if (gameMode != null) gameMode.AddToGUIUpdateList();
if (infoFrame != null) infoFrame.AddToGUIUpdateList();
}
public void Update(float deltaTime)
{
TaskManager.Update(deltaTime);
if (GUI.DisableHUD) return;
//guiRoot.Update(deltaTime);
infoButton.Update(deltaTime);
if (gameMode != null) gameMode.Update(deltaTime);
if (Mission != null) Mission.Update(deltaTime);
if (infoFrame != null)
{
infoFrame.Update(deltaTime);
if (CrewManager != null && CrewManager.CrewCommander != null && CrewManager.CrewCommander.IsOpen)
{
infoFrame = null;
}
}
}
public void Draw(SpriteBatch spriteBatch)
{
if (GUI.DisableHUD) return;
infoButton.Draw(spriteBatch);
if (gameMode != null) gameMode.Draw(spriteBatch);
if (infoFrame != null) infoFrame.Draw(spriteBatch);
}
public void Save(string filePath)
{
XDocument doc = new XDocument(
new XElement("Gamesession"));
var now = DateTime.Now;
doc.Root.Add(new XAttribute("savetime", now.ToShortTimeString() + ", " + now.ToShortDateString()));
doc.Root.Add(new XAttribute("submarine", submarine == null ? "" : submarine.Name));
doc.Root.Add(new XAttribute("mapseed", Map.Seed));
((SinglePlayerMode)gameMode).Save(doc.Root);
try
{
doc.Save(filePath);
}
catch
{
DebugConsole.ThrowError("Saving gamesession to \"" + filePath + "\" failed!");
}
}
}
}

View File

@@ -0,0 +1,479 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Barotrauma
{
public enum WindowMode
{
Windowed, Fullscreen, BorderlessWindowed
}
public partial class GameSettings
{
private GUIFrame settingsFrame;
private GUIButton applyButton;
public GUIFrame SettingsFrame
{
get
{
if (settingsFrame == null) CreateSettingsFrame();
return settingsFrame;
}
}
private float soundVolume, musicVolume;
private WindowMode windowMode;
private KeyOrMouse[] keyMapping;
public KeyOrMouse KeyBind(InputType inputType)
{
return keyMapping[(int)inputType];
}
public int GraphicsWidth { get; set; }
public int GraphicsHeight { get; set; }
public bool VSyncEnabled { get; set; }
public bool EnableSplashScreen { get; set; }
//public bool FullScreenEnabled { get; set; }
public WindowMode WindowMode
{
get { return windowMode; }
set { windowMode = value; }
}
private bool unsavedSettings;
public bool UnsavedSettings
{
get
{
return unsavedSettings;
}
private set
{
unsavedSettings = value;
if (applyButton != null)
{
//applyButton.Selected = unsavedSettings;
applyButton.Enabled = unsavedSettings;
applyButton.Text = unsavedSettings ? "Apply*" : "Apply";
}
}
}
public float SoundVolume
{
get { return soundVolume; }
set
{
soundVolume = MathHelper.Clamp(value, 0.0f, 1.0f);
Sounds.SoundManager.MasterVolume = soundVolume;
}
}
public float MusicVolume
{
get { return musicVolume; }
set
{
musicVolume = MathHelper.Clamp(value, 0.0f, 1.0f);
SoundPlayer.MusicVolume = musicVolume;
}
}
private void InitProjSpecific(XDocument doc)
{
if (doc == null)
{
GraphicsWidth = 1024;
GraphicsHeight = 678;
return;
}
XElement graphicsMode = doc.Root.Element("graphicsmode");
GraphicsWidth = ToolBox.GetAttributeInt(graphicsMode, "width", 0);
GraphicsHeight = ToolBox.GetAttributeInt(graphicsMode, "height", 0);
VSyncEnabled = ToolBox.GetAttributeBool(graphicsMode, "vsync", true);
if (GraphicsWidth == 0 || GraphicsHeight == 0)
{
GraphicsWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
GraphicsHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
}
//FullScreenEnabled = ToolBox.GetAttributeBool(graphicsMode, "fullscreen", true);
var windowModeStr = ToolBox.GetAttributeString(graphicsMode, "displaymode", "Fullscreen");
if (!Enum.TryParse<WindowMode>(windowModeStr, out windowMode))
{
windowMode = WindowMode.Fullscreen;
}
SoundVolume = ToolBox.GetAttributeFloat(doc.Root, "soundvolume", 1.0f);
MusicVolume = ToolBox.GetAttributeFloat(doc.Root, "musicvolume", 0.3f);
EnableSplashScreen = ToolBox.GetAttributeBool(doc.Root, "enablesplashscreen", true);
keyMapping = new KeyOrMouse[Enum.GetNames(typeof(InputType)).Length];
keyMapping[(int)InputType.Up] = new KeyOrMouse(Keys.W);
keyMapping[(int)InputType.Down] = new KeyOrMouse(Keys.S);
keyMapping[(int)InputType.Left] = new KeyOrMouse(Keys.A);
keyMapping[(int)InputType.Right] = new KeyOrMouse(Keys.D);
keyMapping[(int)InputType.Run] = new KeyOrMouse(Keys.LeftShift);
keyMapping[(int)InputType.Chat] = new KeyOrMouse(Keys.Tab);
keyMapping[(int)InputType.CrewOrders] = new KeyOrMouse(Keys.C);
keyMapping[(int)InputType.Select] = new KeyOrMouse(Keys.E);
keyMapping[(int)InputType.Use] = new KeyOrMouse(0);
keyMapping[(int)InputType.Aim] = new KeyOrMouse(1);
foreach (XElement subElement in doc.Root.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "keymapping":
foreach (XAttribute attribute in subElement.Attributes())
{
InputType inputType;
if (Enum.TryParse(attribute.Name.ToString(), true, out inputType))
{
int mouseButton;
if (int.TryParse(attribute.Value.ToString(), out mouseButton))
{
keyMapping[(int)inputType] = new KeyOrMouse(mouseButton);
}
else
{
Keys key;
if (Enum.TryParse(attribute.Value.ToString(), true, out key))
{
keyMapping[(int)inputType] = new KeyOrMouse(key);
}
}
}
}
break;
}
}
foreach (InputType inputType in Enum.GetValues(typeof(InputType)))
{
if (keyMapping[(int)inputType] == null)
{
DebugConsole.ThrowError("Key binding for the input type \"" + inputType + " not set!");
keyMapping[(int)inputType] = new KeyOrMouse(Keys.D1);
}
}
UnsavedSettings = false;
}
public void Save(string filePath)
{
UnsavedSettings = false;
XDocument doc = new XDocument();
if (doc.Root == null)
{
doc.Add(new XElement("config"));
}
doc.Root.Add(
new XAttribute("masterserverurl", MasterServerUrl),
new XAttribute("autocheckupdates", AutoCheckUpdates),
new XAttribute("musicvolume", musicVolume),
new XAttribute("soundvolume", soundVolume),
new XAttribute("verboselogging", VerboseLogging),
new XAttribute("enablesplashscreen", EnableSplashScreen));
if (WasGameUpdated)
{
doc.Root.Add(new XAttribute("wasgameupdated", true));
}
XElement gMode = doc.Root.Element("graphicsmode");
if (gMode == null)
{
gMode = new XElement("graphicsmode");
doc.Root.Add(gMode);
}
if (GraphicsWidth == 0 || GraphicsHeight == 0)
{
gMode.ReplaceAttributes(new XAttribute("displaymode", windowMode));
}
else
{
gMode.ReplaceAttributes(
new XAttribute("width", GraphicsWidth),
new XAttribute("height", GraphicsHeight),
new XAttribute("vsync", VSyncEnabled),
new XAttribute("displaymode", windowMode));
}
if (SelectedContentPackage != null)
{
doc.Root.Add(new XElement("contentpackage",
new XAttribute("path", SelectedContentPackage.Path)));
}
var keyMappingElement = new XElement("keymapping");
doc.Root.Add(keyMappingElement);
for (int i = 0; i < keyMapping.Length; i++)
{
if (keyMapping[i].MouseButton == null)
{
keyMappingElement.Add(new XAttribute(((InputType)i).ToString(), keyMapping[i].Key));
}
else
{
keyMappingElement.Add(new XAttribute(((InputType)i).ToString(), keyMapping[i].MouseButton));
}
}
doc.Save(filePath);
}
private bool ChangeSoundVolume(GUIScrollBar scrollBar, float barScroll)
{
UnsavedSettings = true;
SoundVolume = barScroll;
return true;
}
private bool ChangeMusicVolume(GUIScrollBar scrollBar, float barScroll)
{
UnsavedSettings = true;
MusicVolume = barScroll;
return true;
}
public void ResetSettingsFrame()
{
settingsFrame = null;
}
private void CreateSettingsFrame()
{
settingsFrame = new GUIFrame(new Rectangle(0, 0, 500, 500), null, Alignment.Center, "");
new GUITextBlock(new Rectangle(0, -30, 0, 30), "Settings", "", Alignment.TopCenter, Alignment.TopCenter, settingsFrame, false, GUI.LargeFont);
int x = 0, y = 10;
new GUITextBlock(new Rectangle(0, y, 20, 20), "Resolution", "", Alignment.TopLeft, Alignment.TopLeft, settingsFrame);
var resolutionDD = new GUIDropDown(new Rectangle(0, y + 20, 180, 20), "", "", settingsFrame);
resolutionDD.OnSelected = SelectResolution;
var supportedModes = new List<DisplayMode>();
foreach (DisplayMode mode in GraphicsAdapter.DefaultAdapter.SupportedDisplayModes)
{
if (supportedModes.FirstOrDefault(m => m.Width == mode.Width && m.Height == mode.Height) != null) continue;
resolutionDD.AddItem(mode.Width + "x" + mode.Height, mode);
supportedModes.Add(mode);
if (GraphicsWidth == mode.Width && GraphicsHeight == mode.Height) resolutionDD.SelectItem(mode);
}
if (resolutionDD.SelectedItemData == null)
{
resolutionDD.SelectItem(GraphicsAdapter.DefaultAdapter.SupportedDisplayModes.Last());
}
y += 50;
//var fullScreenTick = new GUITickBox(new Rectangle(x, y, 20, 20), "Fullscreen", Alignment.TopLeft, settingsFrame);
//fullScreenTick.OnSelected = ToggleFullScreen;
//fullScreenTick.Selected = FullScreenEnabled;
new GUITextBlock(new Rectangle(x, y, 20, 20), "Display mode", "", Alignment.TopLeft, Alignment.TopLeft, settingsFrame);
var displayModeDD = new GUIDropDown(new Rectangle(x, y + 20, 180, 20), "", "", settingsFrame);
displayModeDD.AddItem("Fullscreen", WindowMode.Fullscreen);
displayModeDD.AddItem("Windowed", WindowMode.Windowed);
displayModeDD.AddItem("Borderless windowed", WindowMode.BorderlessWindowed);
displayModeDD.SelectItem(GameMain.Config.WindowMode);
displayModeDD.OnSelected = (guiComponent, obj) => { GameMain.Config.WindowMode = (WindowMode)guiComponent.UserData; return true; };
y += 70;
GUITickBox vsyncTickBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Enable vertical sync", Alignment.CenterY | Alignment.Left, settingsFrame);
vsyncTickBox.OnSelected = (GUITickBox box) =>
{
VSyncEnabled = !VSyncEnabled;
GameMain.GraphicsDeviceManager.SynchronizeWithVerticalRetrace = VSyncEnabled;
GameMain.GraphicsDeviceManager.ApplyChanges();
UnsavedSettings = true;
return true;
};
vsyncTickBox.Selected = VSyncEnabled;
y += 70;
new GUITextBlock(new Rectangle(0, y, 100, 20), "Sound volume:", "", settingsFrame);
GUIScrollBar soundScrollBar = new GUIScrollBar(new Rectangle(0, y + 20, 150, 20), "", 0.1f, settingsFrame);
soundScrollBar.BarScroll = SoundVolume;
soundScrollBar.OnMoved = ChangeSoundVolume;
soundScrollBar.Step = 0.05f;
new GUITextBlock(new Rectangle(0, y + 40, 100, 20), "Music volume:", "", settingsFrame);
GUIScrollBar musicScrollBar = new GUIScrollBar(new Rectangle(0, y + 60, 150, 20), "", 0.1f, settingsFrame);
musicScrollBar.BarScroll = MusicVolume;
musicScrollBar.OnMoved = ChangeMusicVolume;
musicScrollBar.Step = 0.05f;
x = 200;
y = 10;
new GUITextBlock(new Rectangle(x, y, 20, 20), "Content package", "", Alignment.TopLeft, Alignment.TopLeft, settingsFrame);
var contentPackageDD = new GUIDropDown(new Rectangle(x, y + 20, 200, 20), "", "", settingsFrame);
foreach (ContentPackage contentPackage in ContentPackage.list)
{
contentPackageDD.AddItem(contentPackage.Name, contentPackage);
if (SelectedContentPackage == contentPackage) contentPackageDD.SelectItem(contentPackage);
}
y += 50;
new GUITextBlock(new Rectangle(x, y, 100, 20), "Controls:", "", settingsFrame);
y += 30;
var inputNames = Enum.GetNames(typeof(InputType));
for (int i = 0; i < inputNames.Length; i++)
{
new GUITextBlock(new Rectangle(x, y, 100, 18), inputNames[i] + ": ", "", Alignment.TopLeft, Alignment.CenterLeft, settingsFrame);
var keyBox = new GUITextBox(new Rectangle(x + 100, y, 120, 18), null, null, Alignment.TopLeft, Alignment.CenterLeft, "", settingsFrame);
keyBox.Text = keyMapping[i].ToString();
keyBox.UserData = i;
keyBox.OnSelected += KeyBoxSelected;
keyBox.SelectedColor = Color.Gold * 0.3f;
y += 20;
}
applyButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Apply", Alignment.BottomRight, "", settingsFrame);
applyButton.OnClicked = ApplyClicked;
}
private void KeyBoxSelected(GUITextBox textBox, Keys key)
{
textBox.Text = "";
CoroutineManager.StartCoroutine(WaitForKeyPress(textBox));
}
private bool MarkUnappliedChanges(GUIButton button, object obj)
{
UnsavedSettings = true;
return true;
}
private bool SelectResolution(GUIComponent selected, object userData)
{
DisplayMode mode = selected.UserData as DisplayMode;
if (mode == null) return false;
if (GraphicsWidth == mode.Width && GraphicsHeight == mode.Height) return false;
GraphicsWidth = mode.Width;
GraphicsHeight = mode.Height;
//GameMain.Graphics.PreferredBackBufferWidth = GraphicsWidth;
//GameMain.Graphics.PreferredBackBufferHeight = GraphicsHeight;
//GameMain.Graphics.ApplyChanges();
//CoroutineManager.StartCoroutine(GameMain.Instance.Load());
UnsavedSettings = true;
return true;
}
private IEnumerable<object> WaitForKeyPress(GUITextBox keyBox)
{
yield return CoroutineStatus.Running;
while (keyBox.Selected && PlayerInput.GetKeyboardState.GetPressedKeys().Length == 0
&& !PlayerInput.LeftButtonClicked() && !PlayerInput.RightButtonClicked())
{
if (Screen.Selected != GameMain.MainMenuScreen && !GUI.SettingsMenuOpen) yield return CoroutineStatus.Success;
yield return CoroutineStatus.Running;
}
UnsavedSettings = true;
int keyIndex = (int)keyBox.UserData;
if (PlayerInput.LeftButtonClicked())
{
keyMapping[keyIndex] = new KeyOrMouse(0);
keyBox.Text = "Mouse1";
}
else if (PlayerInput.LeftButtonClicked())
{
keyMapping[keyIndex] = new KeyOrMouse(1);
keyBox.Text = "Mouse2";
}
else if (PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0)
{
Keys key = PlayerInput.GetKeyboardState.GetPressedKeys()[0];
keyMapping[keyIndex] = new KeyOrMouse(key);
keyBox.Text = key.ToString("G");
}
else
{
yield return CoroutineStatus.Success;
}
keyBox.Deselect();
yield return CoroutineStatus.Success;
}
private bool ApplyClicked(GUIButton button, object userData)
{
Save("config.xml");
settingsFrame.Flash(Color.Green);
if (GameMain.GraphicsWidth != GameMain.Config.GraphicsWidth || GameMain.GraphicsHeight != GameMain.Config.GraphicsHeight)
{
new GUIMessageBox("Restart required", "You need to restart the game for the resolution changes to take effect.");
}
return true;
}
}
}

View File

@@ -0,0 +1,82 @@
using System;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Barotrauma.Networking;
using Lidgren.Network;
using System.Collections.Generic;
using Barotrauma.Items.Components;
namespace Barotrauma
{
partial class CharacterInventory : Inventory
{
public Vector2[] SlotPositions;
private GUIButton[] useOnSelfButton;
void InitProjSpecific()
{
useOnSelfButton = new GUIButton[2];
if (icons == null) icons = TextureLoader.FromFile("Content/UI/inventoryIcons.png");
SlotPositions = new Vector2[limbSlots.Length];
int rectWidth = 40, rectHeight = 40;
int spacing = 10;
for (int i = 0; i < SlotPositions.Length; i++)
{
switch (i)
{
//head, torso, legs
case 0:
case 1:
case 2:
SlotPositions[i] = new Vector2(
spacing,
GameMain.GraphicsHeight - (spacing + rectHeight) * (3 - i));
break;
//lefthand, righthand
case 3:
case 4:
SlotPositions[i] = new Vector2(
spacing * 2 + rectWidth + (spacing + rectWidth) * (i - 2),
GameMain.GraphicsHeight - (spacing + rectHeight) * 3);
useOnSelfButton[i - 3] = new GUIButton(
new Rectangle((int)SlotPositions[i].X, (int)(SlotPositions[i].Y - spacing - rectHeight),
rectWidth, rectHeight), "Use", "")
{
UserData = i,
OnClicked = UseItemOnSelf
};
break;
case 5:
SlotPositions[i] = new Vector2(
spacing * 2 + rectWidth + (spacing + rectWidth) * (i - 5),
GameMain.GraphicsHeight - (spacing + rectHeight) * 3);
break;
default:
SlotPositions[i] = new Vector2(
spacing * 2 + rectWidth + (spacing + rectWidth) * ((i - 6) % 5),
GameMain.GraphicsHeight - (spacing + rectHeight) * ((i > 10) ? 2 : 1));
break;
}
}
}
private bool UseItemOnSelf(GUIButton button, object obj)
{
if (!(obj is int)) return false;
int slotIndex = (int)obj;
return UseItemOnSelf(slotIndex);
}
}
}

View File

@@ -0,0 +1,89 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
partial class ItemLabel : ItemComponent, IDrawableComponent
{
private GUITextBlock textBlock;
private Color textColor;
[HasDefaultValue("", true), Editable(100)]
public string Text
{
get { return textBlock.Text.Replace("\n", ""); }
set
{
if (value == TextBlock.Text || item.Rect.Width < 5) return;
if (textBlock.Rect.Width != item.Rect.Width || textBlock.Rect.Height != item.Rect.Height)
{
textBlock = null;
}
TextBlock.Text = value;
}
}
[Editable, HasDefaultValue("0.0,0.0,0.0,1.0", true)]
public string TextColor
{
get { return ToolBox.Vector4ToString(textColor.ToVector4()); }
set
{
textColor = new Color(ToolBox.ParseToVector4(value));
if (textBlock != null) textBlock.TextColor = textColor;
}
}
[Editable, HasDefaultValue(1.0f, true)]
public float TextScale
{
get { return textBlock == null ? 1.0f : textBlock.TextScale; }
set
{
if (textBlock != null) textBlock.TextScale = MathHelper.Clamp(value, 0.1f, 10.0f);
}
}
private GUITextBlock TextBlock
{
get
{
if (textBlock == null)
{
textBlock = new GUITextBlock(new Rectangle(item.Rect.X, -item.Rect.Y, item.Rect.Width, item.Rect.Height), "",
Color.Transparent, textColor,
Alignment.TopLeft, Alignment.Center,
null, null, true);
textBlock.Font = GUI.SmallFont;
textBlock.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
textBlock.TextDepth = item.Sprite.Depth - 0.0001f;
textBlock.TextScale = TextScale;
}
return textBlock;
}
}
public override void Move(Vector2 amount)
{
textBlock.Rect = new Rectangle(item.Rect.X, -item.Rect.Y, item.Rect.Width, item.Rect.Height);
}
public ItemLabel(Item item, XElement element)
: base(item, element)
{
}
public void Draw(SpriteBatch spriteBatch, bool editing = false)
{
var drawPos = new Vector2(
item.DrawPosition.X - item.Rect.Width / 2.0f,
-(item.DrawPosition.Y + item.Rect.Height / 2.0f));
textBlock.Draw(spriteBatch, drawPos - textBlock.Rect.Location.ToVector2());
}
}
}

View File

@@ -0,0 +1,191 @@
using Barotrauma.Networking;
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
{
partial class FixRequirement
{
private static GUIFrame frame;
public bool CanBeFixed(Character character, GUIComponent reqFrame = null)
{
foreach (string itemName in requiredItems)
{
Item item = character.Inventory.FindItem(itemName);
bool itemFound = (item != null);
if (reqFrame != null)
{
GUIComponent component = reqFrame.children.Find(c => c.UserData as string == itemName);
GUITextBlock text = component as GUITextBlock;
if (text != null) text.TextColor = itemFound ? Color.LightGreen : Color.Red;
}
}
foreach (Skill skill in requiredSkills)
{
float characterSkill = character.GetSkillLevel(skill.Name);
bool sufficientSkill = characterSkill >= skill.Level;
if (reqFrame != null)
{
GUIComponent component = reqFrame.children.Find(c => c.UserData as Skill == skill);
GUITextBlock text = component as GUITextBlock;
if (text != null) text.TextColor = sufficientSkill ? Color.LightGreen : Color.Red;
}
}
return CanBeFixed(character);
}
private static void CreateGUIFrame(Item item)
{
int width = 400, height = 500;
int y = 0;
frame = new GUIFrame(new Rectangle(0, 0, width, height), null, Alignment.Center, "");
frame.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
frame.UserData = item;
new GUITextBlock(new Rectangle(0, 0, 200, 20), "Attempting to fix " + item.Name, "", frame);
y = y + 40;
foreach (FixRequirement requirement in item.FixRequirements)
{
GUIFrame reqFrame = new GUIFrame(
new Rectangle(0, y, 0, 20 + Math.Max(requirement.requiredItems.Count, requirement.requiredSkills.Count) * 15),
Color.Transparent, null, frame);
reqFrame.UserData = requirement;
var fixButton = new GUIButton(new Rectangle(0, 0, 50, 20), "Fix", "", reqFrame);
fixButton.OnClicked = FixButtonPressed;
fixButton.UserData = requirement;
var tickBox = new GUITickBox(new Rectangle(70, 0, 20, 20), requirement.name, Alignment.Left, reqFrame);
tickBox.Enabled = false;
int y2 = 20;
foreach (string itemName in requirement.requiredItems)
{
var itemBlock = new GUITextBlock(new Rectangle(30, y2, 200, 15), itemName, "", reqFrame);
itemBlock.Font = GUI.SmallFont;
itemBlock.UserData = itemName;
y2 += 15;
}
y2 = 20;
foreach (Skill skill in requirement.requiredSkills)
{
var skillBlock = new GUITextBlock(new Rectangle(0, y2, 200, 15), skill.Name + " - " + skill.Level, "", Alignment.Right, Alignment.TopLeft, reqFrame);
skillBlock.Font = GUI.SmallFont;
skillBlock.UserData = skill;
y2 += 15;
}
y += reqFrame.Rect.Height;
}
}
private static bool FixButtonPressed(GUIButton button, object obj)
{
FixRequirement requirement = obj as FixRequirement;
if (requirement == null) return true;
Item item = frame.UserData as Item;
if (item == null) return true;
if (!requirement.CanBeFixed(Character.Controlled, button.Parent)) return true;
if (GameMain.Client != null)
{
GameMain.Client.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.Repair, item.FixRequirements.IndexOf(requirement) });
}
else if (GameMain.Server != null)
{
GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.Status });
requirement.Fixed = true;
}
else
{
requirement.Fixed = true;
}
return true;
}
private static void UpdateGUIFrame(Item item, Character character)
{
if (frame == null) return;
bool unfixedFound = false;
foreach (GUIComponent child in frame.children)
{
FixRequirement requirement = child.UserData as FixRequirement;
if (requirement == null) continue;
if (requirement.Fixed)
{
child.Color = Color.LightGreen * 0.3f;
child.GetChild<GUITickBox>().Selected = true;
}
else
{
bool canBeFixed = requirement.CanBeFixed(character, child);
unfixedFound = true;
//child.GetChild<GUITickBox>().Selected = canBeFixed;
GUITickBox tickBox = child.GetChild<GUITickBox>();
if (tickBox.Selected)
{
tickBox.Selected = canBeFixed;
requirement.Fixed = canBeFixed;
}
child.Color = Color.Red * 0.2f;
//tickBox.State = GUIComponent.ComponentState.None;
}
}
if (!unfixedFound)
{
item.Condition = 100.0f;
frame = null;
}
}
public static void DrawHud(SpriteBatch spriteBatch, Item item, Character character)
{
if (frame == null) return;
frame.Draw(spriteBatch);
}
public static void AddToGUIUpdateList()
{
if (frame == null) return;
frame.AddToGUIUpdateList();
}
public static void UpdateHud(Item item, Character character)
{
if (frame == null || frame.UserData != item)
{
CreateGUIFrame(item);
}
UpdateGUIFrame(item, character);
if (frame == null) return;
frame.Update((float)Timing.Step);
}
}
}

View File

@@ -0,0 +1,203 @@
using System.Linq;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Barotrauma.Networking;
using System;
using System.Collections.Generic;
using Barotrauma.Items.Components;
namespace Barotrauma
{
partial class InventorySlot
{
public GUIComponent.ComponentState State;
public bool IsHighlighted
{
get
{
return State == GUIComponent.ComponentState.Hover;
}
}
public Color Color;
public Color BorderHighlightColor;
private CoroutineHandle BorderHighlightCoroutine;
public void ShowBorderHighlight(Color color, float fadeInDuration, float fadeOutDuration)
{
if (BorderHighlightCoroutine != null)
{
BorderHighlightCoroutine = null;
}
BorderHighlightCoroutine = CoroutineManager.StartCoroutine(UpdateBorderHighlight(color, fadeInDuration, fadeOutDuration));
}
private IEnumerable<object> UpdateBorderHighlight(Color color, float fadeInDuration, float fadeOutDuration)
{
float t = 0.0f;
while (t < fadeInDuration + fadeOutDuration)
{
BorderHighlightColor = (t < fadeInDuration) ?
Color.Lerp(Color.Transparent, color, t / fadeInDuration) :
Color.Lerp(color, Color.Transparent, (t - fadeInDuration) / fadeOutDuration);
t += CoroutineManager.DeltaTime;
yield return CoroutineStatus.Running;
}
yield return CoroutineStatus.Success;
}
}
partial class Inventory
{
public virtual void Draw(SpriteBatch spriteBatch, bool subInventory = false)
{
if (slots == null || isSubInventory != subInventory) return;
for (int i = 0; i < capacity; i++)
{
if (slots[i].Disabled) continue;
//don't draw the item if it's being dragged out of the slot
bool drawItem = draggingItem == null || draggingItem != Items[i] || slots[i].IsHighlighted;
DrawSlot(spriteBatch, slots[i], Items[i], drawItem);
}
if (draggingItem != null &&
(draggingSlot == null || (!draggingSlot.Rect.Contains(PlayerInput.MousePosition) && draggingItem.ParentInventory == this)))
{
Rectangle dragRect = new Rectangle(
(int)PlayerInput.MousePosition.X - 10,
(int)PlayerInput.MousePosition.Y - 10,
40, 40);
DrawSlot(spriteBatch, new InventorySlot(dragRect), draggingItem);
}
for (int i = 0; i < capacity; i++)
{
if (slots[i].IsHighlighted && !slots[i].Disabled && Items[i] != null)
{
string toolTip = "";
if (GameMain.DebugDraw)
{
toolTip = Items[i].ToString();
}
else
{
toolTip = string.IsNullOrEmpty(Items[i].Description) ?
Items[i].Name :
Items[i].Name + '\n' + Items[i].Description;
}
DrawToolTip(spriteBatch, toolTip, slots[i].Rect);
break;
}
}
}
protected void DrawToolTip(SpriteBatch spriteBatch, string toolTip, Rectangle highlightedSlot)
{
int maxWidth = 300;
toolTip = ToolBox.WrapText(toolTip, maxWidth, GUI.Font);
Vector2 textSize = GUI.Font.MeasureString(toolTip);
Vector2 rectSize = textSize * 1.2f;
Vector2 pos = new Vector2(highlightedSlot.Right, highlightedSlot.Y - rectSize.Y);
pos.X = (int)(pos.X + 3);
pos.Y = (int)pos.Y;
GUI.DrawRectangle(spriteBatch, pos, rectSize, Color.Black * 0.8f, true);
GUI.Font.DrawString(spriteBatch, toolTip,
new Vector2((int)(pos.X + rectSize.X * 0.5f), (int)(pos.Y + rectSize.Y * 0.5f)),
Color.White, 0.0f,
new Vector2((int)(textSize.X * 0.5f), (int)(textSize.Y * 0.5f)),
1.0f, SpriteEffects.None, 0.0f);
}
public void DrawSubInventory(SpriteBatch spriteBatch, int slotIndex)
{
var item = Items[slotIndex];
if (item == null) return;
var container = item.GetComponent<ItemContainer>();
if (container == null) return;
if (container.Inventory.slots == null || !container.Inventory.isSubInventory) return;
int itemCapacity = container.Capacity;
#if DEBUG
System.Diagnostics.Debug.Assert(slotIndex >= 0 && slotIndex < Items.Length);
#else
if (slotIndex < 0 || slotIndex >= Items.Length) return;
#endif
var slot = slots[slotIndex];
Rectangle containerRect = new Rectangle(slot.Rect.X - 5, slot.Rect.Y - (40 + 10) * itemCapacity - 5,
slot.Rect.Width + 10, slot.Rect.Height + (40 + 10) * itemCapacity + 10);
GUI.DrawRectangle(spriteBatch, new Rectangle(containerRect.X, containerRect.Y, containerRect.Width, containerRect.Height - slot.Rect.Height - 5), Color.Black * 0.8f, true);
GUI.DrawRectangle(spriteBatch, containerRect, Color.White);
container.Inventory.Draw(spriteBatch, true);
if (!containerRect.Contains(PlayerInput.MousePosition))
{
if (draggingItem == null || draggingItem.Container != item) selectedSlot = -1;
}
}
protected void DrawSlot(SpriteBatch spriteBatch, InventorySlot slot, Item item, bool drawItem = true)
{
Rectangle rect = slot.Rect;
GUI.DrawRectangle(spriteBatch, rect, (slot.IsHighlighted ? Color.Red * 0.4f : slot.Color), true);
if (item != null && drawItem)
{
if (item.Condition < 100.0f)
{
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X, rect.Bottom - 8, rect.Width, 8), Color.Black * 0.8f, true);
GUI.DrawRectangle(spriteBatch,
new Rectangle(rect.X, rect.Bottom - 8, (int)(rect.Width * item.Condition / 100.0f), 8),
Color.Lerp(Color.Red, Color.Green, item.Condition / 100.0f) * 0.8f, true);
}
var containedItems = item.ContainedItems;
if (containedItems != null && containedItems.Length == 1 && containedItems[0].Condition < 100.0f)
{
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X, rect.Y, rect.Width, 8), Color.Black * 0.8f, true);
GUI.DrawRectangle(spriteBatch,
new Rectangle(rect.X, rect.Y, (int)(rect.Width * containedItems[0].Condition / 100.0f), 8),
Color.Lerp(Color.Red, Color.Green, containedItems[0].Condition / 100.0f) * 0.8f, true);
}
}
GUI.DrawRectangle(spriteBatch, rect, (slot.IsHighlighted ? Color.Red * 0.4f : slot.Color), false);
if (slot.BorderHighlightColor != Color.Transparent)
{
Rectangle highlightRect = slot.Rect;
highlightRect.Inflate(3, 3);
GUI.DrawRectangle(spriteBatch, highlightRect, slot.BorderHighlightColor, false, 0, 5);
}
if (item == null || !drawItem) return;
item.Sprite.Draw(spriteBatch, new Vector2(rect.X + rect.Width / 2, rect.Y + rect.Height / 2), item.Color);
}
}
}

View File

@@ -50,9 +50,6 @@ namespace Barotrauma
}
}
//is the mouse inside the rect
protected bool isHighlighted;
//protected bool isSelected;
private static bool disableSelect;
@@ -76,13 +73,6 @@ namespace Barotrauma
get { return selectedList.Count > 0; }
}
public bool IsHighlighted
{
get { return isHighlighted; }
set { isHighlighted = value; }
}
public bool IsSelected
{
get { return selectedList.Contains(this); }

View File

@@ -0,0 +1,138 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Contacts;
using FarseerPhysics.Factories;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Networking;
using Barotrauma.Lights;
namespace Barotrauma
{
partial class Structure : MapEntity, IDamageable, IServerSerializable
{
public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true)
{
if (prefab.sprite == null) return;
Draw(spriteBatch, editing, back, null);
}
public override void DrawDamage(SpriteBatch spriteBatch, Effect damageEffect)
{
Draw(spriteBatch, false, false, damageEffect);
}
private void Draw(SpriteBatch spriteBatch, bool editing, bool back = true, Effect damageEffect = null)
{
if (prefab.sprite == null) return;
Color color = (isHighlighted) ? Color.Orange : Color.White;
if (IsSelected && editing)
{
color = Color.Red;
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X, -rect.Y, rect.Width, rect.Height), color);
}
Vector2 drawOffset = Submarine == null ? Vector2.Zero : Submarine.DrawPosition;
float depth = prefab.sprite.Depth;
depth -= (ID % 255) * 0.000001f;
if (back && damageEffect == null)
{
if (prefab.BackgroundSprite != null)
{
prefab.BackgroundSprite.DrawTiled(
spriteBatch,
new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)),
new Vector2(rect.Width, rect.Height),
color, Point.Zero);
}
}
SpriteEffects oldEffects = prefab.sprite.effects;
prefab.sprite.effects ^= SpriteEffects;
if (back == prefab.sprite.Depth > 0.5f || editing)
{
for (int i = 0; i < sections.Length; i++)
{
if (damageEffect != null)
{
float newCutoff = Math.Min((sections[i].damage / prefab.MaxHealth), 0.65f);
if (Math.Abs(newCutoff - Submarine.DamageEffectCutoff) > 0.01f)
{
damageEffect.Parameters["aCutoff"].SetValue(newCutoff);
damageEffect.Parameters["cCutoff"].SetValue(newCutoff * 1.2f);
damageEffect.CurrentTechnique.Passes[0].Apply();
Submarine.DamageEffectCutoff = newCutoff;
}
}
Point textureOffset = new Point(
Math.Abs(rect.Location.X - sections[i].rect.Location.X),
Math.Abs(rect.Location.Y - sections[i].rect.Location.Y));
if (flippedX && isHorizontal)
{
textureOffset.X = rect.Width - textureOffset.X - sections[i].rect.Width;
}
prefab.sprite.DrawTiled(
spriteBatch,
new Vector2(sections[i].rect.X + drawOffset.X, -(sections[i].rect.Y + drawOffset.Y)),
new Vector2(sections[i].rect.Width, sections[i].rect.Height),
color,
textureOffset, depth);
}
}
prefab.sprite.effects = oldEffects;
}
public override XElement Save(XElement parentElement)
{
XElement element = new XElement("Structure");
element.Add(new XAttribute("name", prefab.Name),
new XAttribute("ID", ID),
new XAttribute("rect",
(int)(rect.X - Submarine.HiddenSubPosition.X) + "," +
(int)(rect.Y - Submarine.HiddenSubPosition.Y) + "," +
rect.Width + "," + rect.Height));
for (int i = 0; i < sections.Length; i++)
{
if (sections[i].damage == 0.0f) continue;
var sectionElement =
new XElement("section",
new XAttribute("i", i),
new XAttribute("damage", sections[i].damage));
if (sections[i].gap != null)
{
sectionElement.Add(new XAttribute("gap", sections[i].gap.ID));
}
element.Add(sectionElement);
}
parentElement.Add(element);
return element;
}
}
}

View File

@@ -0,0 +1,44 @@
using System;
using System.Xml.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;
namespace Barotrauma
{
partial class StructurePrefab : MapEntityPrefab
{
public override void DrawPlacing(SpriteBatch spriteBatch, Camera cam)
{
Vector2 position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub);
//Vector2 placeSize = size;
Rectangle newRect = new Rectangle((int)position.X, (int)position.Y, (int)size.X, (int)size.Y);
if (placePosition == Vector2.Zero)
{
if (PlayerInput.LeftButtonHeld())
placePosition = Submarine.MouseToWorldGrid(cam, Submarine.MainSub);
newRect.X = (int)position.X;
newRect.Y = (int)position.Y;
//sprite.Draw(spriteBatch, new Vector2(position.X, -position.Y), placeSize, Color.White);
}
else
{
Vector2 placeSize = size;
if (resizeHorizontal) placeSize.X = position.X - placePosition.X;
if (resizeVertical) placeSize.Y = placePosition.Y - position.Y;
newRect = Submarine.AbsRect(placePosition, placeSize);
}
sprite.DrawTiled(spriteBatch, new Vector2(newRect.X, -newRect.Y), new Vector2(newRect.Width, newRect.Height), Color.White);
GUI.DrawRectangle(spriteBatch, new Rectangle(newRect.X - GameMain.GraphicsWidth, -newRect.Y, newRect.Width + GameMain.GraphicsWidth * 2, newRect.Height), Color.White);
GUI.DrawRectangle(spriteBatch, new Rectangle(newRect.X, -newRect.Y - GameMain.GraphicsHeight, newRect.Width, newRect.Height + GameMain.GraphicsHeight * 2), Color.White);
}
}
}

View File

@@ -0,0 +1,249 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using FarseerPhysics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
//using Microsoft.Xna.Framework.Input;
using System.Collections.ObjectModel;
using Barotrauma.Items.Components;
using FarseerPhysics.Dynamics;
namespace Barotrauma
{
partial class WayPoint : MapEntity
{
private static Texture2D iconTexture;
private const int IconSize = 32;
private static int[] iconIndices = { 3, 0, 1, 2 };
public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true)
{
if (!editing && !GameMain.DebugDraw) return;
if (IsHidden()) return;
//Rectangle drawRect =
// Submarine == null ? rect : new Rectangle((int)(Submarine.DrawPosition.X + rect.X), (int)(Submarine.DrawPosition.Y + rect.Y), rect.Width, rect.Height);
Vector2 drawPos = Position;
if (Submarine != null) drawPos += Submarine.DrawPosition;
drawPos.Y = -drawPos.Y;
Color clr = currentHull == null ? Color.Blue : Color.White;
if (IsSelected) clr = Color.Red;
if (isHighlighted) clr = Color.DarkRed;
int iconX = iconIndices[(int)spawnType] * IconSize % iconTexture.Width;
int iconY = (int)(Math.Floor(iconIndices[(int)spawnType] * IconSize / (float)iconTexture.Width)) * IconSize;
int iconSize = ConnectedGap == null && Ladders == null ? IconSize : (int)(IconSize * 1.5f);
spriteBatch.Draw(iconTexture,
new Rectangle((int)(drawPos.X - iconSize / 2), (int)(drawPos.Y - iconSize / 2), iconSize, iconSize),
new Rectangle(iconX, iconY, IconSize, IconSize), clr);
//GUI.DrawRectangle(spriteBatch, new Rectangle(drawRect.X, -drawRect.Y, rect.Width, rect.Height), clr, true);
//GUI.SmallFont.DrawString(spriteBatch, Position.ToString(), new Vector2(Position.X, -Position.Y), Color.White);
foreach (MapEntity e in linkedTo)
{
GUI.DrawLine(spriteBatch,
drawPos,
new Vector2(e.DrawPosition.X, -e.DrawPosition.Y),
Color.Green);
}
}
private bool IsHidden()
{
if (spawnType == SpawnType.Path)
{
return (!GameMain.DebugDraw && !ShowWayPoints);
}
else
{
return (!GameMain.DebugDraw && !ShowSpawnPoints);
}
}
public override void UpdateEditing(Camera cam)
{
if (editingHUD == null || editingHUD.UserData != this)
{
editingHUD = CreateEditingHUD();
}
editingHUD.Update((float)Timing.Step);
if (PlayerInput.LeftButtonClicked())
{
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
foreach (MapEntity e in mapEntityList)
{
if (e.GetType() != typeof(WayPoint)) continue;
if (e == this) continue;
if (!Submarine.RectContains(e.Rect, position)) continue;
linkedTo.Add(e);
e.linkedTo.Add(this);
}
}
}
public override void DrawEditing(SpriteBatch spriteBatch, Camera cam)
{
if (editingHUD != null) editingHUD.Draw(spriteBatch);
}
private bool ChangeSpawnType(GUIButton button, object obj)
{
GUITextBlock spawnTypeText = button.Parent as GUITextBlock;
spawnType += (int)button.UserData;
if (spawnType > SpawnType.Cargo) spawnType = SpawnType.Human;
if (spawnType < SpawnType.Human) spawnType = SpawnType.Cargo;
spawnTypeText.Text = spawnType.ToString();
return true;
}
private bool EnterIDCardTags(GUITextBox textBox, string text)
{
IdCardTags = text.Split(',');
textBox.Text = text;
textBox.Color = Color.Green;
textBox.Deselect();
return true;
}
private bool EnterAssignedJob(GUITextBox textBox, string text)
{
string trimmedName = text.ToLowerInvariant().Trim();
assignedJob = JobPrefab.List.Find(jp => jp.Name.ToLowerInvariant() == trimmedName);
if (assignedJob != null && trimmedName != "none")
{
textBox.Color = Color.Green;
textBox.Text = (assignedJob == null) ? "None" : assignedJob.Name;
}
textBox.Deselect();
return true;
}
private bool TextBoxChanged(GUITextBox textBox, string text)
{
textBox.Color = Color.Red;
return true;
}
private GUIComponent CreateEditingHUD(bool inGame = false)
{
int width = 500;
int height = spawnType == SpawnType.Path ? 100 : 140;
int x = GameMain.GraphicsWidth / 2 - width / 2, y = 10;
editingHUD = new GUIFrame(new Rectangle(x, y, width, height), Color.Black * 0.5f);
editingHUD.Padding = new Vector4(10, 10, 0, 0);
editingHUD.UserData = this;
if (spawnType == SpawnType.Path)
{
new GUITextBlock(new Rectangle(0, 0, 100, 20), "Editing waypoint", "", editingHUD);
new GUITextBlock(new Rectangle(0, 20, 100, 20), "Hold space to link to another waypoint", "", editingHUD);
}
else
{
new GUITextBlock(new Rectangle(0, 0, 100, 20), "Editing spawnpoint", "", editingHUD);
new GUITextBlock(new Rectangle(0, 25, 100, 20), "Spawn type: ", "", editingHUD);
var spawnTypeText = new GUITextBlock(new Rectangle(0, 25, 200, 20), spawnType.ToString(), "", Alignment.Right, Alignment.TopLeft, editingHUD);
var button = new GUIButton(new Rectangle(-30, 0, 20, 20), "-", Alignment.Right, "", spawnTypeText);
button.UserData = -1;
button.OnClicked = ChangeSpawnType;
button = new GUIButton(new Rectangle(0, 0, 20, 20), "+", Alignment.Right, "", spawnTypeText);
button.UserData = 1;
button.OnClicked = ChangeSpawnType;
y = 40 + 20;
new GUITextBlock(new Rectangle(0, y, 100, 20), "ID Card tags:", Color.Transparent, Color.White, Alignment.TopLeft, null, editingHUD);
GUITextBox propertyBox = new GUITextBox(new Rectangle(100, y, 200, 20), "", editingHUD);
propertyBox.Text = string.Join(", ", idCardTags);
propertyBox.OnEnterPressed = EnterIDCardTags;
propertyBox.OnTextChanged = TextBoxChanged;
propertyBox.ToolTip = "Characters spawning at this spawnpoint will have the specified tags added to their ID card. You can, for example, use these tags to limit access to some parts of the sub.";
y = y + 30;
new GUITextBlock(new Rectangle(0, y, 100, 20), "Assigned job:", Color.Transparent, Color.White, Alignment.TopLeft, null, editingHUD);
propertyBox = new GUITextBox(new Rectangle(100, y, 200, 20), "", editingHUD);
propertyBox.Text = (assignedJob == null) ? "None" : assignedJob.Name;
propertyBox.OnEnterPressed = EnterAssignedJob;
propertyBox.OnTextChanged = TextBoxChanged;
propertyBox.ToolTip = "Only characters with the specified job will spawn at this spawnpoint.";
}
//GUI.Font.DrawString(spriteBatch, "Spawnpoint: " + spawnType.ToString() + " +/-", new Vector2(x, y + 40), Color.Black);
y = y + 30;
return editingHUD;
}
public override XElement Save(XElement parentElement)
{
if (MoveWithLevel) return null;
XElement element = new XElement("WayPoint");
element.Add(new XAttribute("ID", ID),
new XAttribute("x", (int)(rect.X - Submarine.HiddenSubPosition.X)),
new XAttribute("y", (int)(rect.Y - Submarine.HiddenSubPosition.Y)),
new XAttribute("spawn", spawnType));
if (idCardTags.Length > 0)
{
element.Add(new XAttribute("idcardtags", string.Join(",", idCardTags)));
}
if (assignedJob != null) element.Add(new XAttribute("job", assignedJob.Name));
if (ConnectedGap != null) element.Add(new XAttribute("gap", ConnectedGap.ID));
if (Ladders != null) element.Add(new XAttribute("ladders", Ladders.Item.ID));
parentElement.Add(element);
if (linkedTo != null)
{
int i = 0;
foreach (MapEntity e in linkedTo)
{
element.Add(new XAttribute("linkedto" + i, e.ID));
i += 1;
}
}
return element;
}
}
}

View File

@@ -0,0 +1,217 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using RestSharp;
using Barotrauma.Items.Components;
namespace Barotrauma.Networking
{
partial class GameServer : NetworkMember
{
private GUIButton showLogButton;
private GUIScrollBar clientListScrollBar;
void InitProjSpecific()
{
//----------------------------------------
var endRoundButton = new GUIButton(new Rectangle(GameMain.GraphicsWidth - 170, 20, 150, 20), "End round", Alignment.TopLeft, "", inGameHUD);
endRoundButton.OnClicked = (btn, userdata) => { EndGame(); return true; };
log = new ServerLog(name);
showLogButton = new GUIButton(new Rectangle(GameMain.GraphicsWidth - 170 - 170, 20, 150, 20), "Server Log", Alignment.TopLeft, "", inGameHUD);
showLogButton.OnClicked = (GUIButton button, object userData) =>
{
if (log.LogFrame == null)
{
log.CreateLogFrame();
}
else
{
log.LogFrame = null;
GUIComponent.KeyboardDispatcher.Subscriber = null;
}
return true;
};
GUIButton settingsButton = new GUIButton(new Rectangle(GameMain.GraphicsWidth - 170 - 170 - 170, 20, 150, 20), "Settings", Alignment.TopLeft, "", inGameHUD);
settingsButton.OnClicked = ToggleSettingsFrame;
settingsButton.UserData = "settingsButton";
entityEventManager = new ServerEntityEventManager(this);
whitelist = new WhiteList();
banList = new BanList();
LoadSettings();
LoadClientPermissions();
//----------------------------------------
}
public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
{
base.Draw(spriteBatch);
if (settingsFrame != null)
{
settingsFrame.Draw(spriteBatch);
}
else if (log.LogFrame != null)
{
log.LogFrame.Draw(spriteBatch);
}
if (!ShowNetStats) return;
GUI.Font.DrawString(spriteBatch, "Unique Events: " + entityEventManager.UniqueEvents.Count, new Vector2(10, 50), Color.White);
int width = 200, height = 300;
int x = GameMain.GraphicsWidth - width, y = (int)(GameMain.GraphicsHeight * 0.3f);
if (clientListScrollBar == null)
{
clientListScrollBar = new GUIScrollBar(new Rectangle(x + width - 10, y, 10, height), "", 1.0f);
}
GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black * 0.7f, true);
GUI.Font.DrawString(spriteBatch, "Network statistics:", new Vector2(x + 10, y + 10), Color.White);
GUI.SmallFont.DrawString(spriteBatch, "Connections: " + server.ConnectionsCount, new Vector2(x + 10, y + 30), Color.White);
GUI.SmallFont.DrawString(spriteBatch, "Received bytes: " + MathUtils.GetBytesReadable(server.Statistics.ReceivedBytes), new Vector2(x + 10, y + 45), Color.White);
GUI.SmallFont.DrawString(spriteBatch, "Received packets: " + server.Statistics.ReceivedPackets, new Vector2(x + 10, y + 60), Color.White);
GUI.SmallFont.DrawString(spriteBatch, "Sent bytes: " + MathUtils.GetBytesReadable(server.Statistics.SentBytes), new Vector2(x + 10, y + 75), Color.White);
GUI.SmallFont.DrawString(spriteBatch, "Sent packets: " + server.Statistics.SentPackets, new Vector2(x + 10, y + 90), Color.White);
int resentMessages = 0;
int clientListHeight = connectedClients.Count * 40;
float scrollBarHeight = (height - 110) / (float)Math.Max(clientListHeight, 110);
if (clientListScrollBar.BarSize != scrollBarHeight)
{
clientListScrollBar.BarSize = scrollBarHeight;
}
int startY = y + 110;
y = (startY - (int)(clientListScrollBar.BarScroll * (clientListHeight - (height - 110))));
foreach (Client c in connectedClients)
{
Color clientColor = c.Connection.AverageRoundtripTime > 0.3f ? Color.Red : Color.White;
if (y >= startY && y < startY + height - 120)
{
GUI.SmallFont.DrawString(spriteBatch, c.name + " (" + c.Connection.RemoteEndPoint.Address.ToString() + ")", new Vector2(x + 10, y), clientColor);
GUI.SmallFont.DrawString(spriteBatch, "Ping: " + (int)(c.Connection.AverageRoundtripTime * 1000.0f) + " ms", new Vector2(x + 20, y + 10), clientColor);
}
if (y + 25 >= startY && y < startY + height - 130) GUI.SmallFont.DrawString(spriteBatch, "Resent messages: " + c.Connection.Statistics.ResentMessages, new Vector2(x + 20, y + 20), clientColor);
resentMessages += (int)c.Connection.Statistics.ResentMessages;
y += 40;
}
clientListScrollBar.Update(1.0f / 60.0f);
clientListScrollBar.Draw(spriteBatch);
netStats.AddValue(NetStats.NetStatType.ResentMessages, Math.Max(resentMessages, 0));
netStats.AddValue(NetStats.NetStatType.SentBytes, server.Statistics.SentBytes);
netStats.AddValue(NetStats.NetStatType.ReceivedBytes, server.Statistics.ReceivedBytes);
netStats.Draw(spriteBatch, new Rectangle(200, 0, 800, 200), this);
}
private void UpdateFileTransferIndicator(Client client)
{
var transfers = fileSender.ActiveTransfers.FindAll(t => t.Connection == client.Connection);
var clientNameBox = GameMain.NetLobbyScreen.PlayerList.FindChild(client.name);
var clientInfo = clientNameBox.FindChild("filetransfer");
if (clientInfo == null)
{
clientNameBox.ClearChildren();
clientInfo = new GUIFrame(new Rectangle(0, 0, 180, 0), Color.Transparent, Alignment.TopRight, null, clientNameBox);
clientInfo.UserData = "filetransfer";
}
else if (transfers.Count == 0)
{
clientInfo.Parent.RemoveChild(clientInfo);
}
clientInfo.ClearChildren();
var progressBar = new GUIProgressBar(new Rectangle(0, 4, 160, clientInfo.Rect.Height - 8), Color.Green, "", 0.0f, Alignment.Left, clientInfo);
progressBar.IsHorizontal = true;
progressBar.ProgressGetter = () => { return transfers.Sum(t => t.Progress) / transfers.Count; };
var textBlock = new GUITextBlock(new Rectangle(0, 2, 160, 0), "", "", Alignment.TopLeft, Alignment.Left | Alignment.CenterY, clientInfo, true, GUI.SmallFont);
textBlock.TextGetter = () =>
{ return MathUtils.GetBytesReadable(transfers.Sum(t => t.SentOffset)) + " / " + MathUtils.GetBytesReadable(transfers.Sum(t => t.Data.Length)); };
var cancelButton = new GUIButton(new Rectangle(-5, 0, 14, 0), "X", Alignment.Right, "", clientInfo);
cancelButton.OnClicked = (GUIButton button, object userdata) =>
{
transfers.ForEach(t => fileSender.CancelTransfer(t));
return true;
};
}
public override bool SelectCrewCharacter(Character character, GUIComponent crewFrame)
{
if (character == null) return false;
var characterFrame = crewFrame.FindChild("selectedcharacter");
if (character != myCharacter)
{
var banButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Ban", Alignment.BottomRight, "", characterFrame);
banButton.UserData = character.Name;
banButton.OnClicked += GameMain.NetLobbyScreen.BanPlayer;
var rangebanButton = new GUIButton(new Rectangle(0, -25, 100, 20), "Ban range", Alignment.BottomRight, "", characterFrame);
rangebanButton.UserData = character.Name;
rangebanButton.OnClicked += GameMain.NetLobbyScreen.BanPlayerRange;
var kickButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Kick", Alignment.BottomLeft, "", characterFrame);
kickButton.UserData = character.Name;
kickButton.OnClicked += GameMain.NetLobbyScreen.KickPlayer;
}
return true;
}
private GUIMessageBox upnpBox;
void InitUPnP()
{
server.UPnP.ForwardPort(config.Port, "barotrauma");
upnpBox = new GUIMessageBox("Please wait...", "Attempting UPnP port forwarding", new string[] { "Cancel" });
upnpBox.Buttons[0].OnClicked = upnpBox.Close;
}
bool DiscoveringUPnP()
{
return server.UPnP.Status == UPnPStatus.Discovering && GUIMessageBox.VisibleBox == upnpBox;
}
void FinishUPnP()
{
upnpBox.Close(null, null);
}
public bool StartGameClicked(GUIButton button, object obj)
{
return StartGame();
}
}
}

View File

@@ -0,0 +1,169 @@
using Barotrauma.Networking;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Barotrauma
{
partial class Voting
{
public bool AllowSubVoting
{
get { return allowSubVoting; }
set
{
if (value == allowSubVoting) return;
allowSubVoting = value;
GameMain.NetLobbyScreen.SubList.Enabled = value || GameMain.Server != null;
GameMain.NetLobbyScreen.InfoFrame.FindChild("subvotes").Visible = value;
if (GameMain.Server != null)
{
UpdateVoteTexts(GameMain.Server.ConnectedClients, VoteType.Sub);
GameMain.Server.UpdateVoteStatus();
}
else
{
GameMain.NetLobbyScreen.SubList.Deselect();
}
}
}
public bool AllowModeVoting
{
get { return allowModeVoting; }
set
{
if (value == allowModeVoting) return;
allowModeVoting = value;
GameMain.NetLobbyScreen.ModeList.Enabled = value || GameMain.Server != null;
GameMain.NetLobbyScreen.InfoFrame.FindChild("modevotes").Visible = value;
if (GameMain.Server != null)
{
UpdateVoteTexts(GameMain.Server.ConnectedClients, VoteType.Mode);
GameMain.Server.UpdateVoteStatus();
}
else
{
GameMain.NetLobbyScreen.ModeList.Deselect();
}
}
}
public void UpdateVoteTexts(List<Client> clients, VoteType voteType)
{
GUIListBox listBox = (voteType == VoteType.Sub) ?
GameMain.NetLobbyScreen.SubList : GameMain.NetLobbyScreen.ModeList;
foreach (GUIComponent comp in listBox.children)
{
GUITextBlock voteText = comp.FindChild("votes") as GUITextBlock;
if (voteText != null) comp.RemoveChild(voteText);
}
List<Pair<object, int>> voteList = GetVoteList(voteType, clients);
foreach (Pair<object, int> votable in voteList)
{
SetVoteText(listBox, votable.First, votable.Second);
}
}
private void SetVoteText(GUIListBox listBox, object userData, int votes)
{
if (userData == null) return;
foreach (GUIComponent comp in listBox.children)
{
if (comp.UserData != userData) continue;
GUITextBlock voteText = comp.FindChild("votes") as GUITextBlock;
if (voteText == null)
{
voteText = new GUITextBlock(new Rectangle(0, 0, 30, 0), "", "", Alignment.Right, Alignment.Right, comp);
voteText.UserData = "votes";
}
voteText.Text = votes == 0 ? "" : votes.ToString();
}
}
public void ClientWrite(NetBuffer msg, VoteType voteType, object data)
{
if (GameMain.Server != null) return;
msg.Write((byte)voteType);
switch (voteType)
{
case VoteType.Sub:
Submarine sub = data as Submarine;
if (sub == null) return;
msg.Write(sub.Name);
break;
case VoteType.Mode:
GameModePreset gameMode = data as GameModePreset;
if (gameMode == null) return;
msg.Write(gameMode.Name);
break;
case VoteType.EndRound:
if (!(data is bool)) return;
msg.Write((bool)data);
break;
case VoteType.Kick:
Client votedClient = data as Client;
if (votedClient == null) return;
msg.Write(votedClient.ID);
break;
}
msg.WritePadBits();
}
public void ClientRead(NetIncomingMessage inc)
{
if (GameMain.Server != null) return;
AllowSubVoting = inc.ReadBoolean();
if (allowSubVoting)
{
foreach (Submarine sub in Submarine.SavedSubmarines)
{
SetVoteText(GameMain.NetLobbyScreen.SubList, sub, 0);
}
int votableCount = inc.ReadByte();
for (int i = 0; i < votableCount; i++)
{
int votes = inc.ReadByte();
string subName = inc.ReadString();
Submarine sub = Submarine.SavedSubmarines.Find(sm => sm.Name == subName);
SetVoteText(GameMain.NetLobbyScreen.SubList, sub, votes);
}
}
AllowModeVoting = inc.ReadBoolean();
if (allowModeVoting)
{
int votableCount = inc.ReadByte();
for (int i = 0; i < votableCount; i++)
{
int votes = inc.ReadByte();
string modeName = inc.ReadString();
GameModePreset mode = GameModePreset.list.Find(m => m.Name == modeName);
SetVoteText(GameMain.NetLobbyScreen.ModeList, mode, votes);
}
}
AllowEndVoting = inc.ReadBoolean();
if (AllowEndVoting)
{
GameMain.NetworkMember.EndVoteCount = inc.ReadByte();
GameMain.NetworkMember.EndVoteMax = inc.ReadByte();
}
AllowVoteKick = inc.ReadBoolean();
inc.ReadPadBits();
}
}
}

View File

@@ -125,7 +125,7 @@ namespace Barotrauma
StreamWriter sw = new StreamWriter(filePath);
StringBuilder sb = new StringBuilder();
sb.AppendLine("Barotrauma crash report (generated on " + DateTime.Now + ")");
sb.AppendLine("Barotrauma Client crash report (generated on " + DateTime.Now + ")");
sb.AppendLine("\n");
sb.AppendLine("Barotrauma seems to have crashed. Sorry for the inconvenience! ");
sb.AppendLine("If you'd like to help fix the bug that caused the crash, please send this file to the developers on the Undertow Games forums.");

View File

@@ -54,6 +54,12 @@ namespace Barotrauma
get { return serverMessage; }
}
public string ServerMessageText
{
get { return serverMessage.Text; }
set { serverMessage.Text = value; }
}
public GUIListBox SubList
{
get { return subList; }
@@ -68,6 +74,11 @@ namespace Barotrauma
{
get { return modeList; }
}
public int SelectedModeIndex
{
get { return modeList.SelectedIndex; }
set { modeList.Select(value); }
}
public GUIListBox PlayerList
{
@@ -80,6 +91,12 @@ namespace Barotrauma
private set;
}
public bool StartButtonEnabled
{
get { return StartButton.Enabled; }
set { StartButton.Enabled = value; }
}
public GUIFrame InfoFrame
{
get { return infoFrame; }
@@ -454,7 +471,7 @@ namespace Barotrauma
base.Select();
}
public void ShowSpectateButton()
{
if (GameMain.Client == null) return;

View File

@@ -35,6 +35,9 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="MonoGame.Framework, Version=3.5.1.1679, Culture=neutral, processorArchitecture=MSIL" />
<Reference Include="RestSharp">
<HintPath>..\packages\RestSharp.105.2.3\lib\net45\RestSharp.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
@@ -47,10 +50,19 @@
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Source\Camera.cs" />
<Compile Include="Source\Characters\Character.cs" />
<Compile Include="Source\DebugConsole.cs" />
<Compile Include="Source\GameMain.cs" />
<Compile Include="Source\GameSession\GameSession.cs" />
<Compile Include="Source\GameSettings.cs" />
<Compile Include="Source\Items\CharacterInventory.cs" />
<Compile Include="Source\Items\Components\ItemLabel.cs" />
<Compile Include="Source\Networking\GameClient.cs" />
<Compile Include="Source\Networking\GameServer.cs" />
<Compile Include="Source\Networking\Voting.cs" />
<Compile Include="Source\PlayerInput.cs" />
<Compile Include="Source\Program.cs" />
<Compile Include="Source\Screens\NetLobbyScreen.cs" />
<Compile Include="Source\Sprite\Sprite.cs" />
</ItemGroup>
<ItemGroup>

View File

@@ -0,0 +1,42 @@
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Joints;
using Barotrauma.Networking;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Microsoft.Xna.Framework;
namespace Barotrauma
{
partial class Character : Entity, IDamageable, IPropertyObject, IClientSerializable, IServerSerializable
{
//the Character that the player is currently controlling
private const Character controlled = null;
public static Character Controlled
{
get { return controlled; }
set
{
//do nothing
}
}
private void InitProjSpecific(XDocument doc)
{
//do nothing
}
private void UpdateControlled(float deltaTime)
{
//do nothing
}
private void ImplodeFX()
{
//do nothing
}
}
}

View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Barotrauma.Networking;
using Barotrauma.Items.Components;
using System.Text;
using FarseerPhysics;
namespace Barotrauma
{
static partial class DebugConsole
{
private static string InputText;
private static bool ExecProjSpecific(string[] commands)
{
return false; //command not found
}
}
}

View File

@@ -11,25 +11,69 @@ namespace Barotrauma
{
class GameMain
{
public static readonly Version Version = Assembly.GetEntryAssembly().GetName().Version;
public static World World;
public static GameSettings Config;
public static GameServer Server;
public static GameSession GameSession;
public static GameClient Client
{
get { return null; }
}
public const GameClient Client = null;
public static NetworkMember NetworkMember
{
get { return Server as NetworkMember; }
}
public static Screen EditMapScreen
public static GameSession GameSession;
public static GameMain Instance
{
get { return null; }
get;
private set;
}
//only screens the server implements
public static GameScreen GameScreen;
public static NetLobbyScreen NetLobbyScreen;
//null screens because they are not implemented by the server,
//but they're checked for all over the place
//TODO: maybe clean up instead of having these constants
public const Screen MainMenuScreen = null;
public const Screen LobbyScreen = null;
public const Screen ServerListScreen = null;
public const Screen EditMapScreen = null;
public const Screen EditCharacterScreen = null;
//
public static ContentPackage SelectedPackage
{
get { return Config.SelectedContentPackage; }
}
public GameMain()
{
Instance = this;
Config = new GameSettings("serverconfig.xml");
if (Config.WasGameUpdated)
{
UpdaterUtil.CleanOldFiles();
Config.WasGameUpdated = false;
Config.Save("serverconfig.xml");
}
}
public void Run()
{
//TODO: implement
}
public CoroutineHandle ShowLoading(IEnumerable<object> loader, bool waitKeyHit = true)
{
return CoroutineManager.StartCoroutine(loader);
}
}
}

View File

@@ -0,0 +1,12 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Xml.Linq;
namespace Barotrauma
{
partial class GameSession
{
public const Map Map = null;
}
}

View File

@@ -0,0 +1,49 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Barotrauma
{
public enum WindowMode
{
Windowed, Fullscreen, BorderlessWindowed
}
public partial class GameSettings
{
private void InitProjSpecific(XDocument doc)
{
//do nothing
}
public void Save(string filePath)
{
XDocument doc = new XDocument();
if (doc.Root == null)
{
doc.Add(new XElement("config"));
}
doc.Root.Add(
new XAttribute("masterserverurl", MasterServerUrl),
new XAttribute("autocheckupdates", AutoCheckUpdates),
new XAttribute("verboselogging", VerboseLogging));
if (WasGameUpdated)
{
doc.Root.Add(new XAttribute("wasgameupdated", true));
}
if (SelectedContentPackage != null)
{
doc.Root.Add(new XElement("contentpackage",
new XAttribute("path", SelectedContentPackage.Path)));
}
doc.Save(filePath);
}
}
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Barotrauma.Networking;
using Lidgren.Network;
using System.Collections.Generic;
using Barotrauma.Items.Components;
namespace Barotrauma
{
partial class CharacterInventory : Inventory
{
void InitProjSpecific()
{
//do nothing
}
}
}

View File

@@ -0,0 +1,39 @@
using Microsoft.Xna.Framework;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
partial class ItemLabel : ItemComponent, IDrawableComponent
{
[HasDefaultValue("", true), Editable(100)]
public string Text
{
get;
set;
}
[Editable, HasDefaultValue("0.0,0.0,0.0,1.0", true)]
public string TextColor
{
get;
set;
}
[Editable, HasDefaultValue(1.0f, true)]
public float TextScale
{
get;
set;
}
public override void Move(Vector2 amount)
{
//do nothing
}
public ItemLabel(Item item, XElement element)
: base(item, element)
{
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using RestSharp;
using Barotrauma.Items.Components;
namespace Barotrauma.Networking
{
partial class GameServer : NetworkMember
{
void InitProjSpecific()
{
//do nothing
}
void InitUPnP()
{
server.UPnP.ForwardPort(config.Port, "barotrauma");
}
bool DiscoveringUPnP()
{
return server.UPnP.Status == UPnPStatus.Discovering;
}
void FinishUPnP()
{
//do nothing
}
}
}

View File

@@ -0,0 +1,25 @@
using Barotrauma.Networking;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Barotrauma
{
partial class Voting
{
public bool AllowSubVoting
{
get { return allowSubVoting; }
set { allowSubVoting = value; }
}
public bool AllowModeVoting
{
get { return allowModeVoting; }
set { allowModeVoting = value; }
}
}
}

View File

@@ -7,8 +7,6 @@ using System.Text;
#if WINDOWS
using System.Management;
using System.Windows.Forms;
using Microsoft.Xna.Framework.Graphics;
#endif
#endregion
@@ -29,109 +27,29 @@ namespace Barotrauma
[STAThread]
static void Main()
{
using (var game = new GameMain())
{
#if DEBUG
game.Run();
#else
bool attemptRestart = false;
do
{
try
{
game.Run();
attemptRestart = false;
}
catch (Exception e)
{
if (restartAttempts < 5 && CheckException(game, e))
{
attemptRestart = true;
restartAttempts++;
}
else
{
CrashDump(game, "crashreport.txt", e);
attemptRestart = false;
}
}
} while (attemptRestart);
#endif
}
}
private static bool CheckException(GameMain game, Exception e)
{
#if WINDOWS
if (e is SharpDX.SharpDXException)
GameMain game = null;
try
{
switch ((uint)((SharpDX.SharpDXException)e).ResultCode.Code)
{
case 0x887A0022: //DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
switch (restartAttempts)
{
case 0:
//just wait and try again
System.Threading.Thread.Sleep(100);
return true;
case 1:
//force focus to this window
var myForm = (System.Windows.Forms.Form)System.Windows.Forms.Form.FromHandle(game.Window.Handle);
myForm.Focus();
return true;
case 2:
//try disabling hardware mode switch
if (GameMain.Config.WindowMode == WindowMode.Fullscreen)
{
DebugConsole.NewMessage("Failed to set fullscreen mode, switching configuration to borderless windowed", Microsoft.Xna.Framework.Color.Red);
GameMain.Config.WindowMode = WindowMode.BorderlessWindowed;
GameMain.Config.Save("config.xml");
}
return false;
default:
return false;
}
case 0x80070057: //E_INVALIDARG/Invalid Arguments
DebugConsole.NewMessage("Invalid graphics settings, attempting to fix", Microsoft.Xna.Framework.Color.Red);
GameMain.Config.GraphicsWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
GameMain.Config.GraphicsHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
game.ApplyGraphicsSettings();
return true;
default:
return false;
}
game = new GameMain();
game.Run();
}
catch (Exception e)
{
CrashDump(game, "servercrashreport.txt", e);
}
#endif
return false;
}
public static void CrashMessageBox(string message)
{
#if WINDOWS
MessageBox.Show(message, "Oops! Barotrauma just crashed.", MessageBoxButtons.OK, MessageBoxIcon.Error);
#endif
}
static void CrashDump(GameMain game, string filePath, Exception exception)
{
StreamWriter sw = new StreamWriter(filePath);
StringBuilder sb = new StringBuilder();
sb.AppendLine("Barotrauma crash report (generated on " + DateTime.Now + ")");
sb.AppendLine("Barotrauma Dedicated Server crash report (generated on " + DateTime.Now + ")");
sb.AppendLine("\n");
sb.AppendLine("Barotrauma seems to have crashed. Sorry for the inconvenience! ");
sb.AppendLine("If you'd like to help fix the bug that caused the crash, please send this file to the developers on the Undertow Games forums.");
sb.AppendLine("\n");
sb.AppendLine("Game version " + GameMain.Version);
sb.AppendLine("Graphics mode: " + GameMain.Config.GraphicsWidth + "x" + GameMain.Config.GraphicsHeight + " (" + GameMain.Config.WindowMode.ToString() + ")");
sb.AppendLine("Selected content package: " + GameMain.SelectedPackage.Name);
sb.AppendLine("Level seed: " + ((Level.Loaded == null) ? "no level loaded" : Level.Loaded.Seed));
sb.AppendLine("Loaded submarine: " + ((Submarine.MainSub == null) ? "None" : Submarine.MainSub.Name + " (" + Submarine.MainSub.MD5Hash + ")"));
@@ -164,10 +82,7 @@ namespace Barotrauma
sw.WriteLine(sb.ToString());
sw.Close();
CrashMessageBox( "A crash report (\"crashreport.txt\") was saved in the root folder of the game."+
" If you'd like to help fix this bug, please post the report on the Undertow Games forums.");
sw.Close();
}
}
#endif

View File

@@ -0,0 +1,62 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Networking;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;
using System.ComponentModel;
namespace Barotrauma
{
partial class NetLobbyScreen : Screen
{
public Submarine SelectedSub;
public Submarine SelectedShuttle;
private GameModePreset[] GameModes;
public int SelectedModeIndex;
public GameModePreset SelectedMode
{
get { return GameModes[SelectedModeIndex]; }
}
public string ServerMessageText;
public int MissionTypeIndex;
public List<JobPrefab> JobPreferences
{
get
{
return null;
}
}
private List<Submarine> subs = new List<Submarine>();
public List<Submarine> GetSubList()
{
return subs;
}
public string LevelSeed
{
get
{
return levelSeed;
}
set
{
if (levelSeed == value) return;
levelSeed = value;
}
}
public bool StartButtonEnabled
{
get { return true; }
set { /* do nothing */ }
}
}
}

View File

@@ -1271,7 +1271,6 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)packages.config" />
<None Include="$(MSBuildThisFileDirectory)Source\Screens\sygwkgy0.iv5" />
<None Include="$(MSBuildThisFileDirectory)Submarines\Nehalennia.sub" />
<None Include="$(MSBuildThisFileDirectory)Submarines\TutorialSub.sub" />
<None Include="$(MSBuildThisFileDirectory)Submarines\Vellamo.sub" />
@@ -1309,12 +1308,9 @@
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\Animation\Ragdoll.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\Attack.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\Character.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\CharacterHUD.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\CharacterInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\CharacterNetworking.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\CharacterSound.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\DelayedEffect.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\HUDProgressBar.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\HuskInfection.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\Jobs\Job.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\Jobs\JobPrefab.cs" />
@@ -1340,20 +1336,13 @@
<Compile Include="$(MSBuildThisFileDirectory)Source\Events\TaskManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\FrameCounter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\CargoManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\CrewManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\GameMode.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\GameModePreset.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\MissionMode.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\SinglePlayerMode.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\TraitorManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\BasicTutorial.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\EditorTutorial.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\TutorialMode.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\TutorialType.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameSession.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\HireManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\InfoTextManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\ShiftSummary.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSettings.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\IPropertyObject.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Items\CharacterInventory.cs" />

View File

@@ -1,9 +1,10 @@
using Microsoft.Xna.Framework;
using Barotrauma.Particles;
using System;
using System.Xml.Linq;
using System.Collections.Generic;
#if CLIENT
using Barotrauma.Particles;
#endif
namespace Barotrauma
{
@@ -49,9 +50,11 @@ namespace Barotrauma
public readonly float TargetForce;
#if CLIENT
private Sound sound;
private ParticleEmitterPrefab particleEmitterPrefab;
#endif
public readonly float Stun;
@@ -95,11 +98,13 @@ namespace Barotrauma
Stun = ToolBox.GetAttributeFloat(element, "stun", 0.0f);
#if CLIENT
string soundPath = ToolBox.GetAttributeString(element, "sound", "");
if (!string.IsNullOrWhiteSpace(soundPath))
{
sound = Sound.Load(soundPath);
}
#endif
Range = ToolBox.GetAttributeFloat(element, "range", 0.0f);
@@ -113,9 +118,11 @@ namespace Barotrauma
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
#if CLIENT
case "particleemitter":
particleEmitterPrefab = new ParticleEmitterPrefab(subElement);
break;
#endif
case "statuseffect":
statusEffects.Add(StatusEffect.Load(subElement));
break;

View File

@@ -1,14 +1,12 @@
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Joints;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Networking;
using Barotrauma.Particles;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Microsoft.Xna.Framework;
namespace Barotrauma
{
@@ -17,26 +15,6 @@ namespace Barotrauma
public static List<Character> CharacterList = new List<Character>();
public static bool DisableControls;
//the Character that the player is currently controlling
private static Character controlled;
public static Character Controlled
{
get { return controlled; }
set
{
if (controlled == value) return;
controlled = value;
CharacterHUD.Reset();
if (controlled != null)
{
controlled.Enabled = true;
}
}
}
private bool enabled = true;
public bool Enabled
@@ -97,8 +75,6 @@ namespace Barotrauma
protected Item closestItem;
private Character closestCharacter, selectedCharacter;
private Dictionary<object, HUDProgressBar> hudProgressBars;
private bool isDead;
private CauseOfDeath lastAttackCauseOfDeath;
private CauseOfDeath causeOfDeath;
@@ -113,8 +89,6 @@ namespace Barotrauma
private float bleeding;
private List<CharacterSound> sounds;
private float attackCoolDown;
public Entity ViewTarget
@@ -337,12 +311,7 @@ namespace Barotrauma
GameMain.Server.CreateEntityEvent(this, new object[] { NetEntityEvent.Type.Status });
}
}
public Dictionary<object, HUDProgressBar> HUDProgressBars
{
get { return hudProgressBars; }
}
public HuskInfection huskInfection;
public float HuskInfectionState
{
@@ -540,18 +509,11 @@ namespace Barotrauma
: base(null)
{
keys = new Key[Enum.GetNames(typeof(InputType)).Length];
for (int i = 0; i < Enum.GetNames(typeof(InputType)).Length; i++)
{
keys[i] = new Key(GameMain.Config.KeyBind((InputType)i));
}
ConfigPath = file;
selectedItems = new Item[2];
hudProgressBars = new Dictionary<object, HUDProgressBar>();
IsRemotePlayer = isRemotePlayer;
oxygen = 100.0f;
@@ -570,7 +532,9 @@ namespace Barotrauma
XDocument doc = ToolBox.TryLoadXml(file);
if (doc == null || doc.Root == null) return;
InitProjSpecific(doc);
SpeciesName = ToolBox.GetAttributeString(doc.Root, "name", "Unknown");
IsHumanoid = ToolBox.GetAttributeBool(doc.Root, "humanoid", false);
@@ -599,16 +563,7 @@ namespace Barotrauma
drowningTime = ToolBox.GetAttributeFloat(doc.Root, "drowningtime", 10.0f);
soundInterval = ToolBox.GetAttributeFloat(doc.Root, "soundinterval", 10.0f);
var soundElements = doc.Root.Elements("sound").ToList();
sounds = new List<CharacterSound>();
foreach (XElement soundElement in soundElements)
{
sounds.Add(new CharacterSound(soundElement));
}
if (file == humanConfigFile)
{
if (Info.PickedItemIDs.Any())
@@ -1275,14 +1230,6 @@ namespace Barotrauma
}
}
public static void AddAllToGUIUpdateList()
{
for (int i = 0; i < CharacterList.Count; i++)
{
CharacterList[i].AddToGUIUpdateList();
}
}
public static void UpdateAll(Camera cam, float deltaTime)
{
if (GameMain.Client == null)
@@ -1315,14 +1262,6 @@ namespace Barotrauma
}
}
public virtual void AddToGUIUpdateList()
{
if (controlled == this)
{
CharacterHUD.AddToGUIUpdateList(this);
}
}
public virtual void Update(Camera cam, float deltaTime)
{
if (GameMain.Client != null && this == Controlled && !isSynced) return;
@@ -1388,21 +1327,7 @@ namespace Barotrauma
}
}
if (controlled == this)
{
Lights.LightManager.ViewTarget = this;
CharacterHUD.Update(deltaTime, this);
foreach (HUDProgressBar progressBar in hudProgressBars.Values)
{
progressBar.Update(deltaTime);
}
foreach (var pb in hudProgressBars.Where(pb => pb.Value.FadeTimer<=0.0f).ToList())
{
hudProgressBars.Remove(pb.Key);
}
}
UpdateControlled(deltaTime);
if (Stun > 0.0f)
{
@@ -1522,10 +1447,12 @@ namespace Barotrauma
float prevOxygen = oxygen;
Oxygen += deltaTime * (oxygenAvailable < 30.0f ? -5.0f : 10.0f);
#if CLIENT
if (prevOxygen > 0.0f && Oxygen <= 0.0f && controlled == this)
{
SoundPlayer.PlaySound("drown");
}
#endif
PressureProtection -= deltaTime * 100.0f;
@@ -1569,152 +1496,15 @@ namespace Barotrauma
speechBubbleColor = color;
}
public void Draw(SpriteBatch spriteBatch)
{
if (!Enabled) return;
AnimController.Draw(spriteBatch);
}
public void DrawHUD(SpriteBatch spriteBatch, Camera cam)
{
CharacterHUD.Draw(spriteBatch, this, cam);
}
public virtual void DrawFront(SpriteBatch spriteBatch, Camera cam)
{
if (!Enabled) return;
if (GameMain.DebugDraw)
{
AnimController.DebugDraw(spriteBatch);
if (aiTarget != null) aiTarget.Draw(spriteBatch);
}
/*if (memPos != null && memPos.Count > 0 && controlled == this)
{
PosInfo serverPos = memPos.Last();
Vector2 remoteVec = ConvertUnits.ToDisplayUnits(serverPos.Position);
if (Submarine != null)
{
remoteVec += Submarine.DrawPosition;
}
remoteVec.Y = -remoteVec.Y;
PosInfo localPos = memLocalPos.Find(m => m.ID == serverPos.ID);
int mpind = memLocalPos.FindIndex(lp => lp.ID == localPos.ID);
PosInfo localPos1 = mpind > 0 ? memLocalPos[mpind - 1] : null;
PosInfo localPos2 = mpind < memLocalPos.Count-1 ? memLocalPos[mpind + 1] : null;
Vector2 localVec = ConvertUnits.ToDisplayUnits(localPos.Position);
Vector2 localVec1 = localPos1 != null ? ConvertUnits.ToDisplayUnits(((PosInfo)localPos1).Position) : Vector2.Zero;
Vector2 localVec2 = localPos2 != null ? ConvertUnits.ToDisplayUnits(((PosInfo)localPos2).Position) : Vector2.Zero;
if (Submarine != null)
{
localVec += Submarine.DrawPosition;
localVec1 += Submarine.DrawPosition;
localVec2 += Submarine.DrawPosition;
}
localVec.Y = -localVec.Y;
localVec1.Y = -localVec1.Y;
localVec2.Y = -localVec2.Y;
//GUI.DrawLine(spriteBatch, remoteVec, localVec, Color.Yellow, 0, 10);
if (localPos1 != null) GUI.DrawLine(spriteBatch, remoteVec, localVec1, Color.Lime, 0, 2);
if (localPos2 != null) GUI.DrawLine(spriteBatch, remoteVec + Vector2.One, localVec2 + Vector2.One, Color.Red, 0, 2);
}
Vector2 mouseDrawPos = CursorWorldPosition;
mouseDrawPos.Y = -mouseDrawPos.Y;
GUI.DrawLine(spriteBatch, mouseDrawPos - new Vector2(0, 5), mouseDrawPos + new Vector2(0, 5), Color.Red, 0, 10);
Vector2 closestItemPos = closestItem != null ? closestItem.DrawPosition : Vector2.Zero;
closestItemPos.Y = -closestItemPos.Y;
GUI.DrawLine(spriteBatch, closestItemPos - new Vector2(0, 5), closestItemPos + new Vector2(0, 5), Color.Lime, 0, 10);*/
if (this == controlled || GUI.DisableHUD) return;
Vector2 pos = DrawPosition;
pos.Y = -pos.Y;
if (speechBubbleTimer > 0.0f)
{
GUI.SpeechBubbleIcon.Draw(spriteBatch, pos - Vector2.UnitY * 100.0f,
speechBubbleColor * Math.Min(speechBubbleTimer, 1.0f), 0.0f,
Math.Min((float)speechBubbleTimer, 1.0f));
}
if (this == controlled) return;
if (info != null)
{
Vector2 namePos = new Vector2(pos.X, pos.Y - 110.0f - (5.0f / cam.Zoom)) - GUI.Font.MeasureString(Info.Name) * 0.5f / cam.Zoom;
Color nameColor = Color.White;
if (Character.Controlled != null && TeamID != Character.Controlled.TeamID)
{
nameColor = Color.Red;
}
GUI.Font.DrawString(spriteBatch, Info.Name, namePos + new Vector2(1.0f / cam.Zoom, 1.0f / cam.Zoom), Color.Black, 0.0f, Vector2.Zero, 1.0f / cam.Zoom, SpriteEffects.None, 0.001f);
GUI.Font.DrawString(spriteBatch, Info.Name, namePos, nameColor, 0.0f, Vector2.Zero, 1.0f / cam.Zoom, SpriteEffects.None, 0.0f);
if (GameMain.DebugDraw)
{
GUI.Font.DrawString(spriteBatch, ID.ToString(), namePos - new Vector2(0.0f, 20.0f), Color.White);
}
}
if (isDead) return;
if (health < maxHealth * 0.98f)
{
Vector2 healthBarPos = new Vector2(pos.X - 50, DrawPosition.Y + 100.0f);
GUI.DrawProgressBar(spriteBatch, healthBarPos, new Vector2(100.0f, 15.0f), health / maxHealth, Color.Lerp(Color.Red, Color.Green, health / maxHealth) * 0.8f);
}
}
/// <summary>
/// Creates a progress bar that's "linked" to the specified object (or updates an existing one if there's one already linked to the object)
/// The progress bar will automatically fade out after 1 sec if the method hasn't been called during that time
/// </summary>
public HUDProgressBar UpdateHUDProgressBar(object linkedObject, Vector2 worldPosition, float progress, Color emptyColor, Color fullColor)
{
if (controlled != this) return null;
HUDProgressBar progressBar = null;
if (!hudProgressBars.TryGetValue(linkedObject, out progressBar))
{
progressBar = new HUDProgressBar(worldPosition, Submarine, emptyColor, fullColor);
hudProgressBars.Add(linkedObject, progressBar);
}
progressBar.WorldPosition = worldPosition;
progressBar.FadeTimer = Math.Max(progressBar.FadeTimer, 1.0f);
progressBar.Progress = progress;
return progressBar;
}
public void PlaySound(CharacterSound.SoundType soundType)
{
if (sounds == null || sounds.Count == 0) return;
var matchingSounds = sounds.FindAll(s => s.Type == soundType);
if (matchingSounds.Count == 0) return;
var selectedSound = matchingSounds[Rand.Int(matchingSounds.Count)];
selectedSound.Sound.Play(1.0f, selectedSound.Range, AnimController.WorldPosition);
}
public virtual void AddDamage(CauseOfDeath causeOfDeath, float amount, IDamageable attacker)
{
Health = health-amount;
if (amount > 0.0f)
{
lastAttackCauseOfDeath = causeOfDeath;
#if CLIENT
if (controlled == this) CharacterHUD.TakeDamage(amount);
#endif
}
if (health <= minHealth) Kill(causeOfDeath);
}
@@ -1820,19 +1610,7 @@ namespace Barotrauma
// limb.Damage = 100.0f;
}
SoundPlayer.PlaySound("implode", 1.0f, 150.0f, WorldPosition);
for (int i = 0; i < 10; i++)
{
Particle p = GameMain.ParticleManager.CreateParticle("waterblood",
ConvertUnits.ToDisplayUnits(centerOfMass) + Rand.Vector(5.0f),
Rand.Vector(10.0f));
if (p != null) p.Size *= 2.0f;
GameMain.ParticleManager.CreateParticle("bubbles",
ConvertUnits.ToDisplayUnits(centerOfMass) + Rand.Vector(5.0f),
new Vector2(Rand.Range(-50f, 50f), Rand.Range(-100f, 50f)));
}
ImplodeFX();
foreach (var joint in AnimController.limbJoints)
{
@@ -1852,6 +1630,7 @@ namespace Barotrauma
if (GameMain.NetworkMember != null)
{
#if CLIENT
if (Character.controlled == this)
{
string chatMessage = InfoTextManager.GetInfoText("Self_CauseOfDeath." + causeOfDeath.ToString());
@@ -1861,6 +1640,7 @@ namespace Barotrauma
GameMain.LightManager.LosEnabled = false;
controlled = null;
}
#endif
if (GameMain.Server != null)
GameMain.Server.CreateEntityEvent(this, new object[] { NetEntityEvent.Type.Status });
@@ -1871,8 +1651,10 @@ namespace Barotrauma
GameServer.Log(Name+" has died (Cause of death: "+causeOfDeath+")", ServerLog.MessageType.Attack);
if (OnDeath != null) OnDeath(this, causeOfDeath);
#if CLIENT
PlaySound(CharacterSound.SoundType.Die);
#endif
isDead = true;
@@ -1935,7 +1717,15 @@ namespace Barotrauma
CharacterList.Remove(this);
#if CLIENT
if (controlled == this) controlled = null;
if (GameMain.GameSession?.CrewManager != null &&
GameMain.GameSession.CrewManager.characters.Contains(this))
{
GameMain.GameSession.CrewManager.characters.Remove(this);
}
#endif
if (GameMain.Client != null && GameMain.Client.Character == this) GameMain.Client.Character = null;
@@ -1948,12 +1738,6 @@ namespace Barotrauma
if (selectedItems[0] != null) selectedItems[0].Drop(this);
if (selectedItems[1] != null) selectedItems[1].Drop(this);
if (GameMain.GameSession?.CrewManager != null &&
GameMain.GameSession.CrewManager.characters.Contains(this))
{
GameMain.GameSession.CrewManager.characters.Remove(this);
}
foreach (Character c in CharacterList)
{
if (c.closestCharacter == this) c.closestCharacter = null;

View File

@@ -1,5 +1,4 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.IO;
@@ -10,7 +9,7 @@ namespace Barotrauma
{
public enum Gender { None, Male, Female };
class CharacterInfo
partial class CharacterInfo
{
public string Name;
@@ -211,66 +210,6 @@ namespace Barotrauma
}
}
public GUIFrame CreateInfoFrame(Rectangle rect)
{
GUIFrame frame = new GUIFrame(rect, Color.Transparent);
frame.Padding = new Vector4(10.0f,10.0f,10.0f,10.0f);
return CreateInfoFrame(frame);
}
public GUIFrame CreateInfoFrame(GUIFrame frame)
{
new GUIImage(new Rectangle(0,0,30,30), HeadSprite, Alignment.TopLeft, frame);
ScalableFont font = frame.Rect.Width<280 ? GUI.SmallFont : GUI.Font;
int x = 0, y = 0;
new GUITextBlock(new Rectangle(x+60, y, 200, 20), Name, "", frame, font);
y += 20;
if (Job!=null)
{
new GUITextBlock(new Rectangle(x + 60, y, 200, 20), Job.Name, "", frame, font);
y += 30;
var skills = Job.Skills;
skills.Sort((s1, s2) => -s1.Level.CompareTo(s2.Level));
new GUITextBlock(new Rectangle(x, y, 200, 20), "Skills:", "", frame, font);
y += 20;
foreach (Skill skill in skills)
{
Color textColor = Color.White * (0.5f + skill.Level/200.0f);
new GUITextBlock(new Rectangle(x, y, 200, 20), skill.Name, Color.Transparent, textColor, Alignment.Left, "", frame).Font = font;
new GUITextBlock(new Rectangle(x, y, 200, 20), skill.Level.ToString(), Color.Transparent, textColor, Alignment.Right, "", frame).Font = font;
y += 20;
}
}
return frame;
}
public GUIFrame CreateCharacterFrame(GUIComponent parent, string text, object userData)
{
GUIFrame frame = new GUIFrame(new Rectangle(0, 0, 0, 40), Color.Transparent, "ListBoxElement", parent);
frame.UserData = userData;
GUITextBlock textBlock = new GUITextBlock(
new Rectangle(40, 0, 0, 25),
text,
null, null,
Alignment.Left, Alignment.Left,
"", frame, false);
textBlock.Font = GUI.SmallFont;
textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
new GUIImage(new Rectangle(-5, -5, 0, 0), HeadSprite, Alignment.Left, frame);
return frame;
}
public void UpdateCharacterItems()
{
pickedItems.Clear();

View File

@@ -6,7 +6,7 @@ using System.Linq;
namespace Barotrauma
{
class JobPrefab
partial class JobPrefab
{
public static List<JobPrefab> List;
@@ -102,52 +102,6 @@ namespace Barotrauma
return List[Rand.Int(List.Count)];
}
public GUIFrame CreateInfoFrame()
{
int width = 500, height = 400;
GUIFrame backFrame = new GUIFrame(Rectangle.Empty, Color.Black*0.5f);
backFrame.Padding = Vector4.Zero;
GUIFrame frame = new GUIFrame(new Rectangle(GameMain.GraphicsWidth / 2 - width / 2, GameMain.GraphicsHeight / 2 - height / 2, width, height), "", backFrame);
frame.Padding = new Vector4(30.0f, 30.0f, 30.0f, 30.0f);
new GUITextBlock(new Rectangle(0,0,100,20), Name, "", Alignment.TopLeft, Alignment.TopLeft, frame, false, GUI.LargeFont);
var descriptionBlock = new GUITextBlock(new Rectangle(0, 40, 0, 0), Description, "", Alignment.TopLeft, Alignment.TopLeft, frame, true, GUI.SmallFont);
new GUITextBlock(new Rectangle(0, 40 + descriptionBlock.Rect.Height + 20, 100, 20), "Skills: ", "", Alignment.TopLeft, Alignment.TopLeft, frame, false, GUI.LargeFont);
int y = 40 + descriptionBlock.Rect.Height + 50;
foreach (SkillPrefab skill in Skills)
{
string skillDescription = Skill.GetLevelName((int)skill.LevelRange.X);
string skillDescription2 = Skill.GetLevelName((int)skill.LevelRange.Y);
if (skillDescription2!= skillDescription)
{
skillDescription += "/"+skillDescription2;
}
new GUITextBlock(new Rectangle(0, y, 100, 20),
" - " + skill.Name + ": " + skillDescription, "", Alignment.TopLeft, Alignment.TopLeft, frame, false, GUI.SmallFont);
y += 20;
}
new GUITextBlock(new Rectangle(250, 40 + descriptionBlock.Rect.Height + 20, 0, 20), "Items: ", "", Alignment.TopLeft, Alignment.TopLeft, frame, false, GUI.LargeFont);
y = 40 + descriptionBlock.Rect.Height + 50;
foreach (string itemName in ItemNames)
{
new GUITextBlock(new Rectangle(250, y, 100, 20),
" - " + itemName, "", Alignment.TopLeft, Alignment.TopLeft, frame, false, GUI.SmallFont);
y += 20;
}
return backFrame;
}
public static void LoadAll(List<string> filePaths)
{
List = new List<JobPrefab>();

View File

@@ -4,7 +4,7 @@ using FarseerPhysics;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Joints;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
//using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Items.Components;
using System.Collections.Generic;
using Barotrauma.Lights;
@@ -19,7 +19,7 @@ namespace Barotrauma
LeftLeg, RightLeg, LeftFoot, RightFoot, Head, Torso, Tail, Legs, RightThigh, LeftThigh, Waist
};
class Limb
partial class Limb
{
private const float LimbDensity = 15;
private const float LimbAngularDamping = 7;
@@ -54,7 +54,6 @@ namespace Barotrauma
private readonly Vector2 armorSector;
private readonly float armorValue;
Sound hitSound;
//a timer for delaying when a hitsound/attacksound can be played again
public float soundTimer;
public const float SoundInterval = 0.4f;
@@ -109,12 +108,7 @@ namespace Barotrauma
}
public bool Disabled { get; set; }
public Sound HitSound
{
get { return hitSound; }
}
public Vector2 LinearVelocity
{
get { return body.LinearVelocity; }
@@ -313,9 +307,11 @@ namespace Barotrauma
case "attack":
attack = new Attack(subElement);
break;
#if CLIENT
case "sound":
hitSound = Sound.Load(ToolBox.GetAttributeString(subElement, "file", ""));
break;
#endif
}
}
}
@@ -335,8 +331,6 @@ namespace Barotrauma
public AttackResult AddDamage(Vector2 position, DamageType damageType, float amount, float bleedingAmount, bool playSound)
{
DamageSoundType damageSoundType = (damageType == DamageType.Blunt) ? DamageSoundType.LimbBlunt : DamageSoundType.LimbSlash;
bool hitArmor = false;
float totalArmorValue = 0.0f;
@@ -355,8 +349,15 @@ namespace Barotrauma
totalArmorValue += wearable.WearableComponent.ArmorValue;
}
}
//Bleeding += bleedingAmount;
//Damage += amount;
#if CLIENT
float bloodAmount = hitArmor || bleedingAmount <= 0.0f ? 0 : (int)Math.Min((int)(amount * 2.0f), 20);
DamageSoundType damageSoundType = (damageType == DamageType.Blunt) ? DamageSoundType.LimbBlunt : DamageSoundType.LimbSlash;
if (hitArmor)
{
totalArmorValue = Math.Max(totalArmorValue, 0.0f);
@@ -371,11 +372,6 @@ namespace Barotrauma
SoundPlayer.PlayDamageSound(damageSoundType, amount, position);
}
//Bleeding += bleedingAmount;
//Damage += amount;
float bloodAmount = hitArmor || bleedingAmount<=0.0f ? 0 : (int)Math.Min((int)(amount * 2.0f), 20);
for (int i = 0; i < bloodAmount; i++)
{
Vector2 particleVel = SimPosition - position;
@@ -390,6 +386,7 @@ namespace Barotrauma
{
GameMain.ParticleManager.CreateParticle("waterblood", WorldPosition, Vector2.Zero, 0.0f, character.AnimController.CurrentHull);
}
#endif
damage += Math.Max(amount,bleedingAmount) / character.MaxHealth * 100.0f;
@@ -479,77 +476,6 @@ namespace Barotrauma
}
}
public void Draw(SpriteBatch spriteBatch)
{
float brightness = 1.0f - (burnt / 100.0f) * 0.5f;
Color color = new Color(brightness, brightness, brightness);
body.Dir = Dir;
bool hideLimb = wearingItems.Any(w => w != null && w.HideLimb);
if (!hideLimb)
{
body.Draw(spriteBatch, sprite, color, null, scale);
}
else
{
body.UpdateDrawPosition();
}
if (LightSource != null)
{
LightSource.Position = body.DrawPosition;
}
foreach (WearableSprite wearable in wearingItems)
{
SpriteEffects spriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
Vector2 origin = wearable.Sprite.Origin;
if (body.Dir == -1.0f) origin.X = wearable.Sprite.SourceRect.Width - origin.X;
float depth = sprite.Depth - 0.000001f;
if (wearable.DepthLimb != LimbType.None)
{
Limb depthLimb = character.AnimController.GetLimb(wearable.DepthLimb);
if (depthLimb != null)
{
depth = depthLimb.sprite.Depth - 0.000001f;
}
}
wearable.Sprite.Draw(spriteBatch,
new Vector2(body.DrawPosition.X, -body.DrawPosition.Y),
color, origin,
-body.DrawRotation,
scale, spriteEffect, depth);
}
if (damage > 0.0f && damagedSprite != null && !hideLimb)
{
SpriteEffects spriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
float depth = sprite.Depth - 0.0000015f;
damagedSprite.Draw(spriteBatch,
new Vector2(body.DrawPosition.X, -body.DrawPosition.Y),
color * Math.Min(damage / 50.0f, 1.0f), sprite.Origin,
-body.DrawRotation,
1.0f, spriteEffect, depth);
}
if (!GameMain.DebugDraw) return;
if (pullJoint != null)
{
Vector2 pos = ConvertUnits.ToDisplayUnits(pullJoint.WorldAnchorB);
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 5, 5), Color.Red, true);
}
}
public void Remove()
{
if (sprite != null)
@@ -574,11 +500,13 @@ namespace Barotrauma
body = null;
}
#if CLIENT
if (hitSound != null)
{
hitSound.Remove();
hitSound = null;
}
#endif
}
}
}

View File

@@ -1,13 +1,15 @@
using Barotrauma.Particles;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
#if CLIENT
using Barotrauma.Particles;
#endif
namespace Barotrauma
{
class StatusEffect
partial class StatusEffect
{
[Flags]
public enum TargetType
@@ -20,6 +22,12 @@ namespace Barotrauma
private List<RelatedItem> requiredItems;
#if CLIENT
private List<ParticleEmitterPrefab> particleEmitters;
private Sound sound;
#endif
public string[] propertyNames;
private object[] propertyEffects;
@@ -37,12 +45,8 @@ namespace Barotrauma
private Explosion explosion;
private List<ParticleEmitterPrefab> particleEmitters;
public readonly float FireSize;
private Sound sound;
public TargetType Targets
{
get { return targetTypes; }
@@ -71,7 +75,10 @@ namespace Barotrauma
protected StatusEffect(XElement element)
{
requiredItems = new List<RelatedItem>();
#if CLIENT
particleEmitters = new List<ParticleEmitterPrefab>();
#endif
IEnumerable<XAttribute> attributes = element.Attributes();
List<XAttribute> propertyAttributes = new List<XAttribute>();
@@ -122,12 +129,14 @@ namespace Barotrauma
targetNames.Add(names[i].Trim());
}
break;
case "sound":
sound = Sound.Load(attribute.Value.ToString());
break;
case "duration":
duration = ToolBox.GetAttributeFloat(attribute, 0.0f);
break;
#if CLIENT
case "sound":
sound = Sound.Load(attribute.Value.ToString());
break;
#endif
default:
propertyAttributes.Add(attribute);
break;
@@ -160,9 +169,6 @@ namespace Barotrauma
case "useitem":
useItem = true;
break;
case "particleemitter":
particleEmitters.Add(new ParticleEmitterPrefab(subElement));
break;
case "requireditem":
case "requireditems":
RelatedItem newRequiredItem = RelatedItem.Load(subElement);
@@ -171,6 +177,11 @@ namespace Barotrauma
requiredItems.Add(newRequiredItem);
break;
#if CLIENT
case "particleemitter":
particleEmitters.Add(new ParticleEmitterPrefab(subElement));
break;
#endif
}
}
}
@@ -214,8 +225,10 @@ namespace Barotrauma
}
protected void Apply(float deltaTime, Entity entity, List<IPropertyObject> targets)
{
{
#if CLIENT
if (sound != null) sound.Play(1.0f, 1000.0f, entity.WorldPosition);
#endif
if (useItem)
{
@@ -264,12 +277,14 @@ namespace Barotrauma
var fire = new FireSource(entity.WorldPosition, hull);
fire.Size = new Vector2(FireSize, fire.Size.Y);
}
}
#if CLIENT
foreach (ParticleEmitterPrefab emitter in particleEmitters)
{
emitter.Emit(entity.WorldPosition, hull);
}
#endif
}
private IEnumerable<object> ApplyToPropertyOverDuration(float duration, ObjectProperty property, object value)

View File

@@ -27,152 +27,12 @@ namespace Barotrauma
}
}
static class DebugConsole
static partial class DebugConsole
{
const int MaxMessages = 200;
public static List<ColoredText> Messages = new List<ColoredText>();
static bool isOpen;
static GUIFrame frame;
static GUIListBox listBox;
static GUITextBox textBox;
//used for keeping track of the message entered when pressing up/down
static int selectedIndex;
public static bool IsOpen
{
get
{
return isOpen;
}
}
public static void Init(GameWindow window)
{
int x = 20, y = 20;
int width = 800, height = 500;
frame = new GUIFrame(new Rectangle(x, y, width, height), new Color(0.4f, 0.4f, 0.4f, 0.8f));
frame.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
listBox = new GUIListBox(new Rectangle(0, 0, 0, frame.Rect.Height - 40), Color.Black, "", frame);
//listBox.Color = Color.Black * 0.7f;
textBox = new GUITextBox(new Rectangle(0,0,0,20), Color.Black, Color.White, Alignment.BottomLeft, Alignment.Left, "", frame);
//textBox.Color = Color.Black * 0.7f;
//messages already added before initialization -> add them to the listbox
List<ColoredText> unInitializedMessages = new List<ColoredText>(Messages);
Messages.Clear();
foreach (ColoredText msg in unInitializedMessages)
{
NewMessage(msg.Text, msg.Color);
}
NewMessage("Press F3 to open/close the debug console", Color.Cyan);
NewMessage("Enter \"help\" for a list of available console commands", Color.Cyan);
}
public static void AddToGUIUpdateList()
{
if (isOpen)
{
frame.AddToGUIUpdateList();
}
}
public static void Update(GameMain game, float deltaTime)
{
if (PlayerInput.KeyHit(Keys.F3))
{
isOpen = !isOpen;
if (isOpen)
{
textBox.Select();
AddToGUIUpdateList();
}
else
{
GUIComponent.ForceMouseOn(null);
textBox.Deselect();
}
//keyboardDispatcher.Subscriber = (isOpen) ? textBox : null;
}
if (isOpen)
{
frame.Update(deltaTime);
Character.DisableControls = true;
if (PlayerInput.KeyHit(Keys.Up))
{
SelectMessage(-1);
}
else if (PlayerInput.KeyHit(Keys.Down))
{
SelectMessage(1);
}
//textBox.Update(deltaTime);
if (PlayerInput.KeyDown(Keys.Enter) && textBox.Text != "")
{
ExecuteCommand(textBox.Text, game);
textBox.Text = "";
//selectedIndex = messages.Count;
}
}
}
private static void SelectMessage(int direction)
{
int messageCount = listBox.children.Count;
if (messageCount == 0) return;
direction = Math.Min(Math.Max(-1, direction), 1);
selectedIndex += direction;
if (selectedIndex < 0) selectedIndex = messageCount - 1;
selectedIndex = selectedIndex % messageCount;
textBox.Text = (listBox.children[selectedIndex] as GUITextBlock).Text;
}
public static void Draw(SpriteBatch spriteBatch)
{
if (!isOpen) return;
frame.Draw(spriteBatch);
}
private static bool IsCommandPermitted(string command, GameClient client)
{
switch (command)
{
case "kick":
return client.HasPermission(ClientPermissions.Kick);
case "ban":
case "banip":
return client.HasPermission(ClientPermissions.Ban);
case "netstats":
case "help":
case "dumpids":
case "admin":
return true;
default:
return false;
}
}
public static void ExecuteCommand(string command, GameMain game)
{
if (string.IsNullOrWhiteSpace(command)) return;
@@ -180,15 +40,17 @@ namespace Barotrauma
if (!commands[0].ToLowerInvariant().Equals("admin"))
{
NewMessage(textBox.Text, Color.White);
NewMessage(InputText, Color.White);
}
#if !DEBUG
#if CLIENT
if (GameMain.Client != null && !IsCommandPermitted(commands[0].ToLowerInvariant(), GameMain.Client))
{
ThrowError("You're not permitted to use the command \"" + commands[0].ToLowerInvariant()+"\"!");
return;
}
#endif
#endif
switch (commands[0].ToLowerInvariant())
@@ -304,8 +166,9 @@ namespace Barotrauma
if (commands[1].ToLowerInvariant()=="human")
{
spawnedCharacter = Character.Create(Character.HumanConfigFile, spawnPosition);
spawnedCharacter = Character.Create(Character.HumanConfigFile, spawnPosition);
#if CLIENT
if (GameMain.GameSession != null)
{
SinglePlayerMode mode = GameMain.GameSession.gameMode as SinglePlayerMode;
@@ -316,6 +179,7 @@ namespace Barotrauma
GameMain.GameSession.CrewManager.SelectCharacter(null, Character.Controlled);
}
}
#endif
}
else
{
@@ -418,90 +282,6 @@ namespace Barotrauma
}
}
break;
case "startclient":
if (commands.Length == 1) return;
if (GameMain.Client == null)
{
GameMain.NetworkMember = new GameClient("Name");
GameMain.Client.ConnectToServer(commands[1]);
}
break;
case "mainmenuscreen":
case "mainmenu":
case "menu":
GameMain.GameSession = null;
List<Character> characters = new List<Character>(Character.CharacterList);
foreach (Character c in characters)
{
c.Remove();
}
GameMain.MainMenuScreen.Select();
break;
case "gamescreen":
case "game":
GameMain.GameScreen.Select();
break;
case "editmapscreen":
case "editmap":
case "edit":
if (commands.Length>1)
{
Submarine.Load(string.Join(" ", commands.Skip(1)), true);
}
GameMain.EditMapScreen.Select();
break;
case "test":
Submarine.Load("aegir mark ii", true);
GameMain.DebugDraw = true;
GameMain.LightManager.LosEnabled = false;
GameMain.EditMapScreen.Select();
break;
case "editcharacter":
case "editchar":
GameMain.EditCharacterScreen.Select();
break;
case "controlcharacter":
case "control":
{
if (commands.Length < 2) break;
var character = FindMatchingCharacter(commands, true);
if (character != null)
{
Character.Controlled = character;
}
}
break;
case "setclientcharacter":
{
if (GameMain.Server == null) break;
int separatorIndex = Array.IndexOf(commands, ";");
if (separatorIndex == -1 || commands.Length < 4)
{
ThrowError("Invalid parameters. The command should be formatted as \"setclientcharacter [client] ; [character]\"");
break;
}
string[] commandsLeft = commands.Take(separatorIndex).ToArray();
string[] commandsRight = commands.Skip(separatorIndex).ToArray();
string clientName = String.Join(" ", commandsLeft.Skip(1));
var client = GameMain.Server.ConnectedClients.Find(c => c.name == clientName);
if (client == null)
{
ThrowError("Client \"" + clientName + "\" not found.");
}
var character = FindMatchingCharacter(commandsRight, false);
GameMain.Server.SetClientCharacter(client, character);
}
break;
case "teleportcharacter":
case "teleport":
var tpCharacter = FindMatchingCharacter(commands, false);
@@ -638,20 +418,6 @@ namespace Barotrauma
reactorItem.CreateServerEvent(reactor);
}
break;
case "shake":
GameMain.GameScreen.Cam.Shake = 10.0f;
break;
case "losenabled":
case "los":
case "drawlos":
GameMain.LightManager.LosEnabled = !GameMain.LightManager.LosEnabled;
break;
case "lighting":
case "lightingenabled":
case "light":
case "lights":
GameMain.LightManager.LightingEnabled = !GameMain.LightManager.LightingEnabled;
break;
case "oxygen":
case "air":
foreach (Hull hull in Hull.hullList)
@@ -659,99 +425,7 @@ namespace Barotrauma
hull.OxygenPercentage = 100.0f;
}
break;
case "tutorial":
TutorialMode.StartTutorial(Tutorials.TutorialType.TutorialTypes[0]);
break;
case "editortutorial":
GameMain.EditMapScreen.Select();
GameMain.EditMapScreen.StartTutorial();
break;
case "lobbyscreen":
case "lobby":
GameMain.LobbyScreen.Select();
break;
case "savemap":
case "savesub":
case "save":
if (commands.Length < 2) break;
if (GameMain.EditMapScreen.CharacterMode)
{
GameMain.EditMapScreen.ToggleCharacterMode();
}
string fileName = string.Join(" ", commands.Skip(1));
if (fileName.Contains("../"))
{
DebugConsole.ThrowError("Illegal symbols in filename (../)");
return;
}
if (Submarine.SaveCurrent(System.IO.Path.Combine(Submarine.SavePath, fileName + ".sub")))
{
NewMessage("Sub saved", Color.Green);
//Submarine.Loaded.First().CheckForErrors();
}
break;
case "loadmap":
case "loadsub":
case "load":
if (commands.Length < 2) break;
Submarine.Load(string.Join(" ", commands.Skip(1)), true);
break;
case "cleansub":
for (int i = MapEntity.mapEntityList.Count - 1; i >= 0; i--)
{
MapEntity me = MapEntity.mapEntityList[i];
if (me.SimPosition.Length()>2000.0f)
{
DebugConsole.NewMessage("Removed "+me.Name+" (simposition "+me.SimPosition+")", Color.Orange);
MapEntity.mapEntityList.RemoveAt(i);
}
else if (me.MoveWithLevel)
{
DebugConsole.NewMessage("Removed " + me.Name + " (MoveWithLevel==true)", Color.Orange);
MapEntity.mapEntityList.RemoveAt(i);
}
else if (me is Item)
{
Item item = me as Item;
var wire = item.GetComponent<Wire>();
if (wire == null) continue;
if (wire.GetNodes().Count > 0 && !wire.Connections.Any(c => c != null))
{
wire.Item.Drop(null);
DebugConsole.NewMessage("Dropped wire (ID: "+wire.Item.ID+") - attached on wall but no connections found", Color.Orange);
}
}
}
break;
case "messagebox":
if (commands.Length < 3) break;
new GUIMessageBox(commands[1], commands[2]);
break;
case "debugdraw":
GameMain.DebugDraw = !GameMain.DebugDraw;
break;
case "disablehud":
case "hud":
GUI.DisableHUD = !GUI.DisableHUD;
GameMain.Instance.IsMouseVisible = !GameMain.Instance.IsMouseVisible;
break;
case "followsub":
Camera.FollowSub = !Camera.FollowSub;
break;
case "drawaitargets":
case "showaitargets":
AITarget.ShowAITargets = !AITarget.ShowAITargets;
break;
case "killmonsters":
foreach (Character c in Character.CharacterList)
{
@@ -764,143 +438,9 @@ namespace Barotrauma
GameMain.Server.ShowNetStats = !GameMain.Server.ShowNetStats;
break;
#if DEBUG
case "spamevents":
foreach (Item item in Item.ItemList)
{
for (int i = 0; i<item.components.Count; i++)
{
if (item.components[i] is IServerSerializable)
{
GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ComponentState, i });
}
var itemContainer = item.GetComponent<ItemContainer>();
if (itemContainer != null)
{
GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.InventoryState });
}
GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.Status });
item.NeedsPositionUpdate = true;
}
}
foreach (Character c in Character.CharacterList)
{
GameMain.Server.CreateEntityEvent(c, new object[] { NetEntityEvent.Type.Status });
}
foreach (Structure wall in Structure.WallList)
{
GameMain.Server.CreateEntityEvent(wall);
}
break;
case "spamchatmessages":
int msgCount = 1000;
if (commands.Length > 1) int.TryParse(commands[1], out msgCount);
int msgLength = 50;
if (commands.Length > 2) int.TryParse(commands[2], out msgLength);
for (int i = 0; i < msgCount; i++)
{
if (GameMain.Server != null)
{
GameMain.Server.SendChatMessage(ToolBox.RandomSeed(msgLength), ChatMessageType.Default);
}
else
{
GameMain.Client.SendChatMessage(ToolBox.RandomSeed(msgLength));
}
}
break;
#endif
case "cleanbuild":
GameMain.Config.MusicVolume = 0.5f;
GameMain.Config.SoundVolume = 0.5f;
DebugConsole.NewMessage("Music and sound volume set to 0.5", Color.Green);
GameMain.Config.GraphicsWidth = 0;
GameMain.Config.GraphicsHeight = 0;
GameMain.Config.WindowMode = WindowMode.Fullscreen;
DebugConsole.NewMessage("Resolution set to 0 x 0 (screen resolution will be used)", Color.Green);
DebugConsole.NewMessage("Fullscreen enabled", Color.Green);
GameSettings.VerboseLogging = false;
if (GameMain.Config.MasterServerUrl != "http://www.undertowgames.com/baromaster")
{
DebugConsole.ThrowError("MasterServerUrl \""+GameMain.Config.MasterServerUrl+"\"!");
}
GameMain.Config.Save("config.xml");
var saveFiles = System.IO.Directory.GetFiles(SaveUtil.SaveFolder);
foreach (string saveFile in saveFiles)
{
System.IO.File.Delete(saveFile);
DebugConsole.NewMessage("Deleted "+saveFile, Color.Green);
}
if (System.IO.Directory.Exists(System.IO.Path.Combine(SaveUtil.SaveFolder, "temp")))
{
System.IO.Directory.Delete(System.IO.Path.Combine(SaveUtil.SaveFolder, "temp"), true);
DebugConsole.NewMessage("Deleted temp save folder", Color.Green);
}
if (System.IO.Directory.Exists(ServerLog.SavePath))
{
var logFiles = System.IO.Directory.GetFiles(ServerLog.SavePath);
foreach (string logFile in logFiles)
{
System.IO.File.Delete(logFile);
DebugConsole.NewMessage("Deleted "+logFile, Color.Green);
}
}
if (System.IO.File.Exists("filelist.xml"))
{
System.IO.File.Delete("filelist.xml");
DebugConsole.NewMessage("Deleted filelist", Color.Green);
}
if (System.IO.File.Exists("Submarines/TutorialSub.sub"))
{
System.IO.File.Delete("Submarines/TutorialSub.sub");
DebugConsole.NewMessage("Deleted TutorialSub from the submarine folder", Color.Green);
}
if (System.IO.File.Exists(GameServer.SettingsFile))
{
System.IO.File.Delete(GameServer.SettingsFile);
DebugConsole.NewMessage("Deleted server settings", Color.Green);
}
if (System.IO.File.Exists(GameServer.ClientPermissionsFile))
{
System.IO.File.Delete(GameServer.ClientPermissionsFile);
DebugConsole.NewMessage("Deleted client permission file", Color.Green);
}
if (System.IO.File.Exists("crashreport.txt"))
{
System.IO.File.Delete("crashreport.txt");
DebugConsole.NewMessage("Deleted crashreport.txt", Color.Green);
}
if (!System.IO.File.Exists("Content/Map/TutorialSub.sub"))
{
DebugConsole.ThrowError("TutorialSub.sub not found!");
}
break;
default:
NewMessage("Command not found", Color.Red);
if (!ExecProjSpecific(commands)) NewMessage("Command not found", Color.Red);
break;
}
}
@@ -963,6 +503,7 @@ namespace Barotrauma
Messages.RemoveRange(0, Messages.Count - MaxMessages);
}
#if CLIENT
//listbox not created yet, don't attempt to add
if (listBox == null) return;
@@ -986,6 +527,7 @@ namespace Barotrauma
}
selectedIndex = listBox.children.Count;
#endif
}
public static void Log(string message)
@@ -1001,7 +543,9 @@ namespace Barotrauma
}
System.Diagnostics.Debug.WriteLine(error);
NewMessage(error, Color.Red);
#if CLIENT
isOpen = true;
#endif
}
}
}

View File

@@ -5,7 +5,7 @@ using System.Xml.Linq;
namespace Barotrauma
{
class GameSession
partial class GameSession
{
public enum InfoFrameTab { Crew, Mission, ManagePlayers };
@@ -16,17 +16,13 @@ namespace Barotrauma
//two locations used as the start and end in the MP mode
private Location[] dummyLocations;
private InfoFrameTab selectedTab;
private GUIButton infoButton;
private GUIFrame infoFrame;
private string saveFile;
private Submarine submarine;
#if CLIENT
public CrewManager CrewManager;
private ShiftSummary shiftSummary;
#endif
private Mission currentMission;
@@ -44,16 +40,7 @@ namespace Barotrauma
{
get { return level; }
}
public Map Map
{
get
{
SinglePlayerMode mode = (gameMode as SinglePlayerMode);
return (mode == null) ? null : mode.Map;
}
}
public Location StartLocation
{
get
@@ -94,26 +81,23 @@ namespace Barotrauma
{
get { return saveFile; }
}
public ShiftSummary ShiftSummary
{
get { return shiftSummary; }
}
public GameSession(Submarine submarine, string saveFile, GameModePreset gameModePreset = null, string missionType="")
{
Submarine.MainSub = submarine;
GameMain.GameSession = this;
CrewManager = new CrewManager();
TaskManager = new TaskManager(this);
this.saveFile = saveFile;
#if CLIENT
CrewManager = new CrewManager();
infoButton = new GUIButton(new Rectangle(10, 10, 100, 20), "Info", "", null);
infoButton.OnClicked = ToggleInfoFrame;
#endif
if (gameModePreset != null) gameMode = gameModePreset.Instantiate(missionType);
this.submarine = submarine;
@@ -125,17 +109,19 @@ namespace Barotrauma
Submarine.MainSub = submarine;
GameMain.GameSession = this;
CrewManager = new CrewManager();
selectedSub.Name = ToolBox.GetAttributeString(doc.Root, "submarine", selectedSub.Name);
#if CLIENT
CrewManager = new CrewManager();
foreach (XElement subElement in doc.Root.Elements())
{
if (subElement.Name.ToString().ToLowerInvariant() != "gamemode") continue;
gameMode = new SinglePlayerMode(subElement);
}
#endif
}
private void CreateDummyLocations()
@@ -168,7 +154,9 @@ namespace Barotrauma
public void StartShift(Level level, bool reloadSub = true, bool loadSecondSub = false)
{
#if CLIENT
GameMain.LightManager.LosEnabled = GameMain.NetworkMember == null || GameMain.NetworkMember.CharacterInfo != null;
#endif
this.level = level;
@@ -198,8 +186,10 @@ namespace Barotrauma
level.Generate();
submarine.SetPosition(submarine.FindSpawnPos(level.StartPosition - new Vector2(0.0f, 2000.0f)));
#if CLIENT
GameMain.GameScreen.BackgroundCreatureManager.SpawnSprites(80);
#endif
}
if (gameMode.Mission != null)
@@ -207,8 +197,6 @@ namespace Barotrauma
currentMission = gameMode.Mission;
}
shiftSummary = new ShiftSummary(this);
if (gameMode!=null) gameMode.Start();
if (gameMode.Mission != null) Mission.Start(Level.Loaded);
@@ -219,8 +207,12 @@ namespace Barotrauma
Entity.Spawner = new EntitySpawner();
#if CLIENT
shiftSummary = new ShiftSummary(this);
GameMain.GameScreen.ColorFade(Color.Black, Color.TransparentBlack, 5.0f);
SoundPlayer.SwitchMusic();
#endif
}
public void EndShift(string endMessage)
@@ -238,6 +230,7 @@ namespace Barotrauma
GameMain.LobbyScreen.Select();
}
#if CLIENT
if (shiftSummary != null)
{
GUIFrame summaryFrame = shiftSummary.CreateSummaryFrame(endMessage);
@@ -245,6 +238,7 @@ namespace Barotrauma
var okButton = new GUIButton(new Rectangle(0, 0, 100, 30), "Ok", Alignment.BottomRight, "", summaryFrame.children[0]);
okButton.OnClicked = (GUIButton button, object obj) => { GUIMessageBox.MessageBoxes.Remove(summaryFrame); return true; };
}
#endif
TaskManager.EndShift();
@@ -253,182 +247,19 @@ namespace Barotrauma
StatusEffect.StopAll();
}
public void KillCharacter(Character character)
{
#if CLIENT
CrewManager.KillCharacter(character);
#endif
}
public void ReviveCharacter(Character character)
{
#if CLIENT
CrewManager.ReviveCharacter(character);
#endif
}
public bool LoadPrevious(GUIButton button, object obj)
{
Submarine.Unload();
SaveUtil.LoadGame(saveFile);
GameMain.LobbyScreen.Select();
return true;
}
private bool ToggleInfoFrame(GUIButton button, object obj)
{
if (infoFrame == null)
{
if (CrewManager != null && CrewManager.CrewCommander!= null && CrewManager.CrewCommander.IsOpen)
{
CrewManager.CrewCommander.ToggleGUIFrame();
}
CreateInfoFrame();
SelectInfoFrameTab(null, selectedTab);
}
else
{
infoFrame = null;
}
return true;
}
public void CreateInfoFrame()
{
int width = 600, height = 400;
infoFrame = new GUIFrame(
Rectangle.Empty, Color.Black * 0.8f, null);
var innerFrame = new GUIFrame(
new Rectangle(GameMain.GraphicsWidth / 2 - width / 2, GameMain.GraphicsHeight / 2 - height / 2, width, height), "", infoFrame);
innerFrame.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
var crewButton = new GUIButton(new Rectangle(0, -30, 100, 20), "Crew", "", innerFrame);
crewButton.UserData = InfoFrameTab.Crew;
crewButton.OnClicked = SelectInfoFrameTab;
var missionButton = new GUIButton(new Rectangle(100, -30, 100, 20), "Mission", "", innerFrame);
missionButton.UserData = InfoFrameTab.Mission;
missionButton.OnClicked = SelectInfoFrameTab;
if (GameMain.Server != null)
{
var manageButton = new GUIButton(new Rectangle(200, -30, 130, 20), "Manage players", "", innerFrame);
manageButton.UserData = InfoFrameTab.ManagePlayers;
manageButton.OnClicked = SelectInfoFrameTab;
}
var closeButton = new GUIButton(new Rectangle(0, 0, 80, 20), "Close", Alignment.BottomCenter, "", innerFrame);
closeButton.OnClicked = ToggleInfoFrame;
}
private bool SelectInfoFrameTab(GUIButton button, object userData)
{
selectedTab = (InfoFrameTab)userData;
CreateInfoFrame();
switch (selectedTab)
{
case InfoFrameTab.Crew:
CrewManager.CreateCrewFrame(CrewManager.characters, infoFrame.children[0] as GUIFrame);
break;
case InfoFrameTab.Mission:
CreateMissionInfo(infoFrame.children[0] as GUIFrame);
break;
case InfoFrameTab.ManagePlayers:
GameMain.Server.ManagePlayersFrame(infoFrame.children[0] as GUIFrame);
break;
}
return true;
}
private void CreateMissionInfo(GUIFrame infoFrame)
{
if (Mission == null)
{
new GUITextBlock(new Rectangle(0,0,0,50), "No mission", "", infoFrame, true);
return;
}
new GUITextBlock(new Rectangle(0, 0, 0, 40), Mission.Name, "", infoFrame, GUI.LargeFont);
new GUITextBlock(new Rectangle(0, 50, 0, 20), "Reward: "+Mission.Reward, "", infoFrame, true);
new GUITextBlock(new Rectangle(0, 70, 0, 50), Mission.Description, "", infoFrame, true);
}
public void AddToGUIUpdateList()
{
infoButton.AddToGUIUpdateList();
if (gameMode != null) gameMode.AddToGUIUpdateList();
if (infoFrame != null) infoFrame.AddToGUIUpdateList();
}
public void Update(float deltaTime)
{
TaskManager.Update(deltaTime);
if (GUI.DisableHUD) return;
//guiRoot.Update(deltaTime);
infoButton.Update(deltaTime);
if (gameMode != null) gameMode.Update(deltaTime);
if (Mission != null) Mission.Update(deltaTime);
if (infoFrame != null)
{
infoFrame.Update(deltaTime);
if (CrewManager != null && CrewManager.CrewCommander != null && CrewManager.CrewCommander.IsOpen)
{
infoFrame = null;
}
}
}
public void Draw(SpriteBatch spriteBatch)
{
if (GUI.DisableHUD) return;
infoButton.Draw(spriteBatch);
if (gameMode != null) gameMode.Draw(spriteBatch);
if (infoFrame != null) infoFrame.Draw(spriteBatch);
}
public void Save(string filePath)
{
XDocument doc = new XDocument(
new XElement("Gamesession"));
var now = DateTime.Now;
doc.Root.Add(new XAttribute("savetime", now.ToShortTimeString() + ", " + now.ToShortDateString()));
doc.Root.Add(new XAttribute("submarine", submarine==null ? "" : submarine.Name));
doc.Root.Add(new XAttribute("mapseed", Map.Seed));
((SinglePlayerMode)gameMode).Save(doc.Root);
try
{
doc.Save(filePath);
}
catch
{
DebugConsole.ThrowError("Saving gamesession to \"" + filePath + "\" failed!");
}
}
}
}

View File

@@ -1,6 +1,4 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -9,51 +7,10 @@ using System.Xml.Linq;
namespace Barotrauma
{
public enum WindowMode
public partial class GameSettings
{
Windowed, Fullscreen, BorderlessWindowed
}
public class GameSettings
{
private GUIFrame settingsFrame;
private GUIButton applyButton;
private float soundVolume, musicVolume;
private WindowMode windowMode;
private KeyOrMouse[] keyMapping;
private bool unsavedSettings;
public GUIFrame SettingsFrame
{
get
{
if (settingsFrame == null) CreateSettingsFrame();
return settingsFrame;
}
}
public KeyOrMouse KeyBind(InputType inputType)
{
return keyMapping[(int)inputType];
}
public int GraphicsWidth { get; set; }
public int GraphicsHeight { get; set; }
public bool VSyncEnabled { get; set; }
//public bool FullScreenEnabled { get; set; }
public WindowMode WindowMode
{
get { return windowMode; }
set { windowMode = value; }
}
public ContentPackage SelectedContentPackage { get; set; }
public string MasterServerUrl { get; set; }
@@ -62,46 +19,6 @@ namespace Barotrauma
public static bool VerboseLogging { get; set; }
public bool EnableSplashScreen { get; set; }
public bool UnsavedSettings
{
get
{
return unsavedSettings;
}
private set
{
unsavedSettings = value;
if (applyButton != null)
{
//applyButton.Selected = unsavedSettings;
applyButton.Enabled = unsavedSettings;
applyButton.Text = unsavedSettings ? "Apply*" : "Apply";
}
}
}
public float SoundVolume
{
get { return soundVolume; }
set
{
soundVolume = MathHelper.Clamp(value, 0.0f, 1.0f);
Sounds.SoundManager.MasterVolume = soundVolume;
}
}
public float MusicVolume
{
get { return musicVolume; }
set
{
musicVolume = MathHelper.Clamp(value, 0.0f, 1.0f);
SoundPlayer.MusicVolume = musicVolume;
}
}
public GameSettings(string filePath)
{
ContentPackage.LoadAll(ContentPackage.Folder);
@@ -117,9 +34,6 @@ namespace Barotrauma
{
DebugConsole.ThrowError("No config file found");
GraphicsWidth = 1024;
GraphicsHeight = 678;
MasterServerUrl = "";
SelectedContentPackage = ContentPackage.list.Any() ? ContentPackage.list[0] : new ContentPackage("");
@@ -127,53 +41,15 @@ namespace Barotrauma
return;
}
XElement graphicsMode = doc.Root.Element("graphicsmode");
GraphicsWidth = ToolBox.GetAttributeInt(graphicsMode, "width", 0);
GraphicsHeight = ToolBox.GetAttributeInt(graphicsMode, "height", 0);
VSyncEnabled = ToolBox.GetAttributeBool(graphicsMode, "vsync", true);
if (GraphicsWidth==0 || GraphicsHeight==0)
{
GraphicsWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
GraphicsHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
}
//FullScreenEnabled = ToolBox.GetAttributeBool(graphicsMode, "fullscreen", true);
var windowModeStr = ToolBox.GetAttributeString(graphicsMode, "displaymode", "Fullscreen");
if (!Enum.TryParse<WindowMode>(windowModeStr, out windowMode))
{
windowMode = WindowMode.Fullscreen;
}
MasterServerUrl = ToolBox.GetAttributeString(doc.Root, "masterserverurl", "");
AutoCheckUpdates = ToolBox.GetAttributeBool(doc.Root, "autocheckupdates", true);
WasGameUpdated = ToolBox.GetAttributeBool(doc.Root, "wasgameupdated", false);
SoundVolume = ToolBox.GetAttributeFloat(doc.Root, "soundvolume", 1.0f);
MusicVolume = ToolBox.GetAttributeFloat(doc.Root, "musicvolume", 0.3f);
VerboseLogging = ToolBox.GetAttributeBool(doc.Root, "verboselogging", false);
EnableSplashScreen = ToolBox.GetAttributeBool(doc.Root, "enablesplashscreen", true);
InitProjSpecific(doc);
keyMapping = new KeyOrMouse[Enum.GetNames(typeof(InputType)).Length];
keyMapping[(int)InputType.Up] = new KeyOrMouse(Keys.W);
keyMapping[(int)InputType.Down] = new KeyOrMouse(Keys.S);
keyMapping[(int)InputType.Left] = new KeyOrMouse(Keys.A);
keyMapping[(int)InputType.Right] = new KeyOrMouse(Keys.D);
keyMapping[(int)InputType.Run] = new KeyOrMouse(Keys.LeftShift);
keyMapping[(int)InputType.Chat] = new KeyOrMouse(Keys.Tab);
keyMapping[(int)InputType.CrewOrders] = new KeyOrMouse(Keys.C);
keyMapping[(int)InputType.Select] = new KeyOrMouse(Keys.E);
keyMapping[(int)InputType.Use] = new KeyOrMouse(0);
keyMapping[(int)InputType.Aim] = new KeyOrMouse(1);
foreach (XElement subElement in doc.Root.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
@@ -186,332 +62,9 @@ namespace Barotrauma
if (SelectedContentPackage == null) SelectedContentPackage = new ContentPackage(path);
break;
case "keymapping":
foreach (XAttribute attribute in subElement.Attributes())
{
InputType inputType;
if (Enum.TryParse(attribute.Name.ToString(), true, out inputType))
{
int mouseButton;
if (int.TryParse(attribute.Value.ToString(), out mouseButton))
{
keyMapping[(int)inputType] = new KeyOrMouse(mouseButton);
}
else
{
Keys key;
if (Enum.TryParse(attribute.Value.ToString(), true, out key))
{
keyMapping[(int)inputType] = new KeyOrMouse(key);
}
}
}
}
break;
}
}
foreach (InputType inputType in Enum.GetValues(typeof(InputType)))
{
if (keyMapping[(int)inputType]==null)
{
DebugConsole.ThrowError("Key binding for the input type \"" + inputType + " not set!");
keyMapping[(int)inputType] = new KeyOrMouse(Keys.D1);
}
}
UnsavedSettings = false;
}
public void Save(string filePath)
{
UnsavedSettings = false;
XDocument doc = new XDocument();
if (doc.Root == null)
{
doc.Add(new XElement("config"));
}
doc.Root.Add(
new XAttribute("masterserverurl", MasterServerUrl),
new XAttribute("autocheckupdates", AutoCheckUpdates),
new XAttribute("musicvolume", musicVolume),
new XAttribute("soundvolume", soundVolume),
new XAttribute("verboselogging", VerboseLogging),
new XAttribute("enablesplashscreen", EnableSplashScreen));
if (WasGameUpdated)
{
doc.Root.Add(new XAttribute("wasgameupdated", true));
}
XElement gMode = doc.Root.Element("graphicsmode");
if (gMode == null)
{
gMode = new XElement("graphicsmode");
doc.Root.Add(gMode);
}
if (GraphicsWidth==0 || GraphicsHeight==0)
{
gMode.ReplaceAttributes(new XAttribute("displaymode", windowMode));
}
else
{
gMode.ReplaceAttributes(
new XAttribute("width", GraphicsWidth),
new XAttribute("height", GraphicsHeight),
new XAttribute("vsync", VSyncEnabled),
new XAttribute("displaymode", windowMode));
}
if (SelectedContentPackage != null)
{
doc.Root.Add(new XElement("contentpackage",
new XAttribute("path", SelectedContentPackage.Path)));
}
var keyMappingElement = new XElement("keymapping");
doc.Root.Add(keyMappingElement);
for (int i = 0; i<keyMapping.Length;i++)
{
if (keyMapping[i].MouseButton==null)
{
keyMappingElement.Add(new XAttribute(((InputType)i).ToString(), keyMapping[i].Key));
}
else
{
keyMappingElement.Add(new XAttribute(((InputType)i).ToString(), keyMapping[i].MouseButton));
}
}
doc.Save(filePath);
}
private bool ChangeSoundVolume(GUIScrollBar scrollBar, float barScroll)
{
UnsavedSettings = true;
SoundVolume = barScroll;
return true;
}
private bool ChangeMusicVolume(GUIScrollBar scrollBar, float barScroll)
{
UnsavedSettings = true;
MusicVolume = barScroll;
return true;
}
public void ResetSettingsFrame()
{
settingsFrame = null;
}
private void CreateSettingsFrame()
{
settingsFrame = new GUIFrame(new Rectangle(0, 0, 500, 500), null, Alignment.Center, "");
new GUITextBlock(new Rectangle(0, -30, 0, 30), "Settings", "", Alignment.TopCenter, Alignment.TopCenter, settingsFrame, false, GUI.LargeFont);
int x = 0, y = 10;
new GUITextBlock(new Rectangle(0, y, 20, 20), "Resolution", "", Alignment.TopLeft, Alignment.TopLeft, settingsFrame);
var resolutionDD = new GUIDropDown(new Rectangle(0, y + 20, 180, 20), "", "", settingsFrame);
resolutionDD.OnSelected = SelectResolution;
var supportedModes = new List<DisplayMode>();
foreach (DisplayMode mode in GraphicsAdapter.DefaultAdapter.SupportedDisplayModes)
{
if (supportedModes.FirstOrDefault(m => m.Width == mode.Width && m.Height == mode.Height) != null) continue;
resolutionDD.AddItem(mode.Width + "x" + mode.Height, mode);
supportedModes.Add(mode);
if (GraphicsWidth == mode.Width && GraphicsHeight == mode.Height) resolutionDD.SelectItem(mode);
}
if (resolutionDD.SelectedItemData == null)
{
resolutionDD.SelectItem(GraphicsAdapter.DefaultAdapter.SupportedDisplayModes.Last());
}
y += 50;
//var fullScreenTick = new GUITickBox(new Rectangle(x, y, 20, 20), "Fullscreen", Alignment.TopLeft, settingsFrame);
//fullScreenTick.OnSelected = ToggleFullScreen;
//fullScreenTick.Selected = FullScreenEnabled;
new GUITextBlock(new Rectangle(x, y, 20, 20), "Display mode", "", Alignment.TopLeft, Alignment.TopLeft, settingsFrame);
var displayModeDD = new GUIDropDown(new Rectangle(x, y + 20, 180, 20), "", "", settingsFrame);
displayModeDD.AddItem("Fullscreen", WindowMode.Fullscreen);
displayModeDD.AddItem("Windowed", WindowMode.Windowed);
displayModeDD.AddItem("Borderless windowed", WindowMode.BorderlessWindowed);
displayModeDD.SelectItem(GameMain.Config.WindowMode);
displayModeDD.OnSelected = (guiComponent, obj) => { GameMain.Config.WindowMode = (WindowMode)guiComponent.UserData; return true; };
y += 70;
GUITickBox vsyncTickBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Enable vertical sync",Alignment.CenterY | Alignment.Left,settingsFrame);
vsyncTickBox.OnSelected = (GUITickBox box) =>
{
VSyncEnabled = !VSyncEnabled;
GameMain.GraphicsDeviceManager.SynchronizeWithVerticalRetrace = VSyncEnabled;
GameMain.GraphicsDeviceManager.ApplyChanges();
UnsavedSettings = true;
return true;
};
vsyncTickBox.Selected = VSyncEnabled;
y += 70;
new GUITextBlock(new Rectangle(0, y, 100, 20), "Sound volume:", "", settingsFrame);
GUIScrollBar soundScrollBar = new GUIScrollBar(new Rectangle(0, y + 20, 150, 20), "", 0.1f, settingsFrame);
soundScrollBar.BarScroll = SoundVolume;
soundScrollBar.OnMoved = ChangeSoundVolume;
soundScrollBar.Step = 0.05f;
new GUITextBlock(new Rectangle(0, y + 40, 100, 20), "Music volume:", "", settingsFrame);
GUIScrollBar musicScrollBar = new GUIScrollBar(new Rectangle(0, y + 60, 150, 20), "", 0.1f, settingsFrame);
musicScrollBar.BarScroll = MusicVolume;
musicScrollBar.OnMoved = ChangeMusicVolume;
musicScrollBar.Step = 0.05f;
x = 200;
y = 10;
new GUITextBlock(new Rectangle(x, y, 20, 20), "Content package", "", Alignment.TopLeft, Alignment.TopLeft, settingsFrame);
var contentPackageDD = new GUIDropDown(new Rectangle(x, y + 20, 200, 20), "", "", settingsFrame);
foreach (ContentPackage contentPackage in ContentPackage.list)
{
contentPackageDD.AddItem(contentPackage.Name, contentPackage);
if (SelectedContentPackage == contentPackage) contentPackageDD.SelectItem(contentPackage);
}
y += 50;
new GUITextBlock(new Rectangle(x, y, 100, 20), "Controls:", "", settingsFrame);
y += 30;
var inputNames = Enum.GetNames(typeof(InputType));
for (int i = 0; i< inputNames.Length; i++)
{
new GUITextBlock(new Rectangle(x, y, 100, 18), inputNames[i]+": ", "", Alignment.TopLeft, Alignment.CenterLeft, settingsFrame);
var keyBox = new GUITextBox(new Rectangle(x + 100, y, 120, 18), null,null, Alignment.TopLeft, Alignment.CenterLeft, "", settingsFrame);
keyBox.Text = keyMapping[i].ToString();
keyBox.UserData = i;
keyBox.OnSelected += KeyBoxSelected;
keyBox.SelectedColor = Color.Gold * 0.3f;
y += 20;
}
applyButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Apply", Alignment.BottomRight, "", settingsFrame);
applyButton.OnClicked = ApplyClicked;
}
private void KeyBoxSelected(GUITextBox textBox, Keys key)
{
textBox.Text = "";
CoroutineManager.StartCoroutine(WaitForKeyPress(textBox));
}
private bool MarkUnappliedChanges(GUIButton button, object obj)
{
UnsavedSettings = true;
return true;
}
private bool SelectResolution(GUIComponent selected, object userData)
{
DisplayMode mode = selected.UserData as DisplayMode;
if (mode == null) return false;
if (GraphicsWidth == mode.Width && GraphicsHeight == mode.Height) return false;
GraphicsWidth = mode.Width;
GraphicsHeight = mode.Height;
//GameMain.Graphics.PreferredBackBufferWidth = GraphicsWidth;
//GameMain.Graphics.PreferredBackBufferHeight = GraphicsHeight;
//GameMain.Graphics.ApplyChanges();
//CoroutineManager.StartCoroutine(GameMain.Instance.Load());
UnsavedSettings = true;
return true;
}
private IEnumerable<object> WaitForKeyPress(GUITextBox keyBox)
{
yield return CoroutineStatus.Running;
while (keyBox.Selected && PlayerInput.GetKeyboardState.GetPressedKeys().Length==0
&& !PlayerInput.LeftButtonClicked() && !PlayerInput.RightButtonClicked())
{
if (Screen.Selected != GameMain.MainMenuScreen && !GUI.SettingsMenuOpen) yield return CoroutineStatus.Success;
yield return CoroutineStatus.Running;
}
UnsavedSettings = true;
int keyIndex = (int)keyBox.UserData;
if (PlayerInput.LeftButtonClicked())
{
keyMapping[keyIndex] = new KeyOrMouse(0);
keyBox.Text = "Mouse1";
}
else if (PlayerInput.LeftButtonClicked())
{
keyMapping[keyIndex] = new KeyOrMouse(1);
keyBox.Text = "Mouse2";
}
else if (PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0)
{
Keys key = PlayerInput.GetKeyboardState.GetPressedKeys()[0];
keyMapping[keyIndex] = new KeyOrMouse(key);
keyBox.Text = key.ToString("G");
}
else
{
yield return CoroutineStatus.Success;
}
keyBox.Deselect();
yield return CoroutineStatus.Success;
}
private bool ApplyClicked(GUIButton button, object userData)
{
Save("config.xml");
settingsFrame.Flash(Color.Green);
if (GameMain.GraphicsWidth != GameMain.Config.GraphicsWidth || GameMain.GraphicsHeight != GameMain.Config.GraphicsHeight)
{
new GUIMessageBox("Restart required", "You need to restart the game for the resolution changes to take effect.");
}
return true;
}
}
}

View File

@@ -16,7 +16,7 @@ namespace Barotrauma
None = 0, Any = 1, RightHand = 2, LeftHand = 4, Head = 8, Torso = 16, Legs = 32, Face=64
};
class CharacterInventory : Inventory
partial class CharacterInventory : Inventory
{
private static Texture2D icons;
@@ -26,81 +26,26 @@ namespace Barotrauma
InvSlotType.Head, InvSlotType.Torso, InvSlotType.Legs, InvSlotType.LeftHand, InvSlotType.RightHand, InvSlotType.Face,
InvSlotType.Any, InvSlotType.Any, InvSlotType.Any, InvSlotType.Any, InvSlotType.Any,
InvSlotType.Any, InvSlotType.Any, InvSlotType.Any, InvSlotType.Any, InvSlotType.Any};
public Vector2[] SlotPositions;
private GUIButton[] useOnSelfButton;
public CharacterInventory(int capacity, Character character)
: base(character, capacity)
{
this.character = character;
useOnSelfButton = new GUIButton[2];
if (icons == null) icons = TextureLoader.FromFile("Content/UI/inventoryIcons.png");
SlotPositions = new Vector2[limbSlots.Length];
int rectWidth = 40, rectHeight = 40;
int spacing = 10;
for (int i = 0; i < SlotPositions.Length; i++)
{
switch (i)
{
//head, torso, legs
case 0:
case 1:
case 2:
SlotPositions[i] = new Vector2(
spacing,
GameMain.GraphicsHeight - (spacing + rectHeight) * (3 - i));
break;
//lefthand, righthand
case 3:
case 4:
SlotPositions[i] = new Vector2(
spacing * 2 + rectWidth + (spacing + rectWidth) * (i - 2),
GameMain.GraphicsHeight - (spacing + rectHeight)*3);
useOnSelfButton[i - 3] = new GUIButton(
new Rectangle((int) SlotPositions[i].X, (int) (SlotPositions[i].Y - spacing - rectHeight),
rectWidth, rectHeight), "Use", "")
{
UserData = i,
OnClicked = UseItemOnSelf
};
break;
case 5:
SlotPositions[i] = new Vector2(
spacing * 2 + rectWidth + (spacing + rectWidth) * (i - 5),
GameMain.GraphicsHeight - (spacing + rectHeight) * 3);
break;
default:
SlotPositions[i] = new Vector2(
spacing * 2 + rectWidth + (spacing + rectWidth) * ((i - 6)%5),
GameMain.GraphicsHeight - (spacing + rectHeight) * ((i>10) ? 2 : 1));
break;
}
}
InitProjSpecific();
}
private bool UseItemOnSelf(GUIButton button, object obj)
private bool UseItemOnSelf(int slotIndex)
{
if (!(obj is int)) return false;
int slotIndex = (int)obj;
if (Items[slotIndex] == null) return false;
#if CLIENT
if (GameMain.Client != null)
{
GameMain.Client.CreateEntityEvent(Items[slotIndex], new object[] { NetEntityEvent.Type.ApplyStatusEffect });
return true;
}
#endif
if (GameMain.Server != null)
{

View File

@@ -1,19 +1,26 @@
using System.Xml.Linq;
using Microsoft.Xna.Framework;
#if CLIENT
using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Particles;
#endif
namespace Barotrauma.Items.Components
{
class Propulsion : ItemComponent
{
enum UsableIn
{
Air,Water,Both
};
private float force;
private string particles;
private float useState;
private ParticlePrefab.DrawTargetType usableIn;
private UsableIn usableIn;
[HasDefaultValue(0.0f, false)]
public float Force
@@ -21,13 +28,15 @@ namespace Barotrauma.Items.Components
get { return force; }
set { force = value; }
}
#if CLIENT
[HasDefaultValue("", false)]
public string Particles
{
get { return particles; }
set { particles = value; }
}
#endif
public Propulsion(Item item, XElement element)
: base(item,element)
@@ -35,14 +44,14 @@ namespace Barotrauma.Items.Components
switch (ToolBox.GetAttributeString(element, "usablein", "both").ToLowerInvariant())
{
case "air":
usableIn = ParticlePrefab.DrawTargetType.Air;
usableIn = UsableIn.Air;
break;
case "water":
usableIn = ParticlePrefab.DrawTargetType.Water;
usableIn = UsableIn.Water;
break;
case "both":
default:
usableIn = ParticlePrefab.DrawTargetType.Both;
usableIn = UsableIn.Both;
break;
}
}
@@ -58,11 +67,11 @@ namespace Barotrauma.Items.Components
if (character.AnimController.InWater)
{
if (usableIn == ParticlePrefab.DrawTargetType.Air) return true;
if (usableIn == UsableIn.Air) return true;
}
else
{
if (usableIn == ParticlePrefab.DrawTargetType.Water) return true;
if (usableIn == UsableIn.Water) return true;
}
Vector2 dir = Vector2.Normalize(character.CursorPosition - character.Position);
@@ -82,13 +91,14 @@ namespace Barotrauma.Items.Components
if (character.SelectedItems[0] == item) character.AnimController.GetLimb(LimbType.RightHand).body.ApplyForce(propulsion);
if (character.SelectedItems[1] == item) character.AnimController.GetLimb(LimbType.LeftHand).body.ApplyForce(propulsion);
#if CLIENT
if (!string.IsNullOrWhiteSpace(particles))
{
GameMain.ParticleManager.CreateParticle(particles, item.WorldPosition,
item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi), 0.0f, item.CurrentHull);
}
#endif
return true;
}

View File

@@ -13,7 +13,9 @@ namespace Barotrauma.Items.Components
{
interface IDrawableComponent
{
#if CLIENT
void Draw(SpriteBatch spriteBatch, bool editing);
#endif
}
class ItemSound

View File

@@ -1,87 +1,8 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
class ItemLabel : ItemComponent, IDrawableComponent
partial class ItemLabel : ItemComponent, IDrawableComponent
{
private GUITextBlock textBlock;
[HasDefaultValue("", true), Editable(100)]
public string Text
{
get { return textBlock.Text.Replace("\n", ""); }
set
{
if (value == TextBlock.Text || item.Rect.Width < 5) return;
if (textBlock.Rect.Width != item.Rect.Width || textBlock.Rect.Height != item.Rect.Height)
{
textBlock = null;
}
TextBlock.Text = value;
}
}
private Color textColor;
[Editable, HasDefaultValue("0.0,0.0,0.0,1.0", true)]
public string TextColor
{
get { return ToolBox.Vector4ToString(textColor.ToVector4()); }
set
{
textColor = new Color(ToolBox.ParseToVector4(value));
if (textBlock != null) textBlock.TextColor = textColor;
}
}
[Editable, HasDefaultValue(1.0f, true)]
public float TextScale
{
get { return textBlock == null ? 1.0f : textBlock.TextScale; }
set
{
if (textBlock != null) textBlock.TextScale = MathHelper.Clamp(value, 0.1f, 10.0f);
}
}
private GUITextBlock TextBlock
{
get
{
if (textBlock == null)
{
textBlock = new GUITextBlock(new Rectangle(item.Rect.X,-item.Rect.Y,item.Rect.Width, item.Rect.Height), "",
Color.Transparent, textColor,
Alignment.TopLeft, Alignment.Center,
null, null, true);
textBlock.Font = GUI.SmallFont;
textBlock.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
textBlock.TextDepth = item.Sprite.Depth - 0.0001f;
textBlock.TextScale = TextScale;
}
return textBlock;
}
}
public override void Move(Vector2 amount)
{
textBlock.Rect = new Rectangle(item.Rect.X, -item.Rect.Y, item.Rect.Width, item.Rect.Height);
}
public ItemLabel(Item item, XElement element)
: base(item, element)
{
}
public void Draw(SpriteBatch spriteBatch, bool editing = false)
{
var drawPos = new Vector2(
item.DrawPosition.X - item.Rect.Width/2.0f,
-(item.DrawPosition.Y + item.Rect.Height/2.0f));
textBlock.Draw(spriteBatch, drawPos - textBlock.Rect.Location.ToVector2());
}
}
}

View File

@@ -9,12 +9,10 @@ using System.Xml.Linq;
namespace Barotrauma
{
class FixRequirement
partial class FixRequirement
{
string name;
private static GUIFrame frame;
List<Skill> requiredSkills;
List<string> requiredItems;
@@ -46,7 +44,7 @@ namespace Barotrauma
}
}
public bool CanBeFixed(Character character, GUIComponent reqFrame = null)
public bool CanBeFixed(Character character)
{
if (character == null) return false;
@@ -57,13 +55,6 @@ namespace Barotrauma
bool itemFound = (item != null);
if (!itemFound) success = false;
if (reqFrame != null)
{
GUIComponent component = reqFrame.children.Find(c => c.UserData as string == itemName);
GUITextBlock text = component as GUITextBlock;
if (text != null) text.TextColor = itemFound ? Color.LightGreen : Color.Red;
}
}
foreach (Skill skill in requiredSkills)
@@ -72,160 +63,9 @@ namespace Barotrauma
bool sufficientSkill = characterSkill >= skill.Level;
if (!sufficientSkill) success = false;
if (reqFrame != null)
{
GUIComponent component = reqFrame.children.Find(c => c.UserData as Skill == skill);
GUITextBlock text = component as GUITextBlock;
if (text != null) text.TextColor = sufficientSkill ? Color.LightGreen : Color.Red;
}
}
return success;
}
private static void CreateGUIFrame(Item item)
{
int width = 400, height = 500;
int y = 0;
frame = new GUIFrame(new Rectangle(0, 0, width, height), null, Alignment.Center, "");
frame.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
frame.UserData = item;
new GUITextBlock(new Rectangle(0,0,200,20), "Attempting to fix " + item.Name, "", frame);
y = y + 40;
foreach (FixRequirement requirement in item.FixRequirements)
{
GUIFrame reqFrame = new GUIFrame(
new Rectangle(0, y, 0, 20 + Math.Max(requirement.requiredItems.Count, requirement.requiredSkills.Count) * 15),
Color.Transparent, null, frame);
reqFrame.UserData = requirement;
var fixButton = new GUIButton(new Rectangle(0, 0, 50, 20), "Fix", "", reqFrame);
fixButton.OnClicked = FixButtonPressed;
fixButton.UserData = requirement;
var tickBox = new GUITickBox(new Rectangle(70, 0, 20,20), requirement.name, Alignment.Left, reqFrame);
tickBox.Enabled = false;
int y2 = 20;
foreach (string itemName in requirement.requiredItems)
{
var itemBlock = new GUITextBlock(new Rectangle(30, y2, 200, 15), itemName, "", reqFrame);
itemBlock.Font = GUI.SmallFont;
itemBlock.UserData = itemName;
y2 += 15;
}
y2 = 20;
foreach (Skill skill in requirement.requiredSkills)
{
var skillBlock = new GUITextBlock(new Rectangle(0, y2, 200, 15), skill.Name + " - " + skill.Level, "", Alignment.Right, Alignment.TopLeft, reqFrame);
skillBlock.Font = GUI.SmallFont;
skillBlock.UserData = skill;
y2 += 15;
}
y += reqFrame.Rect.Height;
}
}
private static bool FixButtonPressed(GUIButton button, object obj)
{
FixRequirement requirement = obj as FixRequirement;
if (requirement == null) return true;
Item item = frame.UserData as Item;
if (item == null) return true;
if (!requirement.CanBeFixed(Character.Controlled, button.Parent)) return true;
if (GameMain.Client != null)
{
GameMain.Client.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.Repair, item.FixRequirements.IndexOf(requirement)});
}
else if (GameMain.Server != null)
{
GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.Status });
requirement.Fixed = true;
}
else
{
requirement.Fixed = true;
}
return true;
}
private static void UpdateGUIFrame(Item item, Character character)
{
if (frame == null) return;
bool unfixedFound = false;
foreach (GUIComponent child in frame.children)
{
FixRequirement requirement = child.UserData as FixRequirement;
if (requirement == null) continue;
if (requirement.Fixed)
{
child.Color = Color.LightGreen * 0.3f;
child.GetChild<GUITickBox>().Selected = true;
}
else
{
bool canBeFixed = requirement.CanBeFixed(character, child);
unfixedFound = true;
//child.GetChild<GUITickBox>().Selected = canBeFixed;
GUITickBox tickBox = child.GetChild<GUITickBox>();
if (tickBox.Selected)
{
tickBox.Selected = canBeFixed;
requirement.Fixed = canBeFixed;
}
child.Color = Color.Red * 0.2f;
//tickBox.State = GUIComponent.ComponentState.None;
}
}
if (!unfixedFound)
{
item.Condition = 100.0f;
frame = null;
}
}
public static void DrawHud(SpriteBatch spriteBatch, Item item, Character character)
{
if (frame == null) return;
frame.Draw(spriteBatch);
}
public static void AddToGUIUpdateList()
{
if (frame == null) return;
frame.AddToGUIUpdateList();
}
public static void UpdateHud(Item item, Character character)
{
if (frame == null || frame.UserData != item)
{
CreateGUIFrame(item);
}
UpdateGUIFrame(item, character);
if (frame == null) return;
frame.Update((float)Timing.Step);
}
}
}

View File

@@ -1,8 +1,6 @@
using System.Linq;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Barotrauma.Networking;
using System;
using System.Collections.Generic;
@@ -10,65 +8,26 @@ using Barotrauma.Items.Components;
namespace Barotrauma
{
class InventorySlot
partial class InventorySlot
{
public Rectangle Rect;
public GUIComponent.ComponentState State;
public bool Disabled;
public bool IsHighlighted
{
get
{
return State == GUIComponent.ComponentState.Hover;
}
}
public Color Color;
public Color BorderHighlightColor;
private CoroutineHandle BorderHighlightCoroutine;
public InventorySlot(Rectangle rect)
{
Rect = rect;
#if CLIENT
State = GUIComponent.ComponentState.None;
Color = Color.White * 0.4f;
#endif
}
public void ShowBorderHighlight(Color color, float fadeInDuration, float fadeOutDuration)
{
if (BorderHighlightCoroutine != null)
{
BorderHighlightCoroutine = null;
}
BorderHighlightCoroutine = CoroutineManager.StartCoroutine(UpdateBorderHighlight(color, fadeInDuration, fadeOutDuration));
}
private IEnumerable<object> UpdateBorderHighlight(Color color, float fadeInDuration, float fadeOutDuration)
{
float t = 0.0f;
while (t < fadeInDuration + fadeOutDuration)
{
BorderHighlightColor = (t < fadeInDuration) ?
Color.Lerp(Color.Transparent, color, t / fadeInDuration) :
Color.Lerp(color, Color.Transparent, (t - fadeInDuration) / fadeOutDuration);
t += CoroutineManager.DeltaTime;
yield return CoroutineStatus.Running;
}
yield return CoroutineStatus.Success;
}
}
class Inventory : IServerSerializable, IClientSerializable
partial class Inventory : IServerSerializable, IClientSerializable
{
public static InventorySlot draggingSlot;
public static Item draggingItem;
@@ -86,8 +45,6 @@ namespace Barotrauma
protected int capacity;
private Vector2 centerPos;
protected int selectedSlot = -1;
protected InventorySlot[] slots;
@@ -101,14 +58,18 @@ namespace Barotrauma
private float syncItemsDelay;
private CoroutineHandle syncItemsCoroutine;
private Vector2 centerPos;
public Vector2 CenterPos
{
get { return centerPos; }
set
{
centerPos = value;
#if CLIENT
centerPos.X *= GameMain.GraphicsWidth;
centerPos.Y *= GameMain.GraphicsHeight;
#endif
}
}
@@ -195,7 +156,9 @@ namespace Barotrauma
}
else
{
#if CLIENT
if (slots != null && createNetworkEvent) slots[i].ShowBorderHighlight(Color.Red, 0.1f, 0.9f);
#endif
return false;
}
}
@@ -213,7 +176,9 @@ namespace Barotrauma
Items[i] = item;
item.ParentInventory = this;
#if CLIENT
if (slots != null) slots[i].ShowBorderHighlight(Color.White, 0.1f, 0.4f);
#endif
if (item.body != null)
{
@@ -232,10 +197,12 @@ namespace Barotrauma
{
GameMain.Server.CreateEntityEvent(Owner as IServerSerializable, new object[] { NetEntityEvent.Type.InventoryState });
}
#if CLIENT
else if (GameMain.Client != null)
{
GameMain.Client.CreateEntityEvent(Owner as IClientSerializable, new object[] { NetEntityEvent.Type.InventoryState });
}
#endif
}
public Item FindItem(string itemName)
@@ -311,79 +278,13 @@ namespace Barotrauma
}
public virtual void Draw(SpriteBatch spriteBatch, bool subInventory = false)
{
if (slots == null || isSubInventory != subInventory) return;
for (int i = 0; i < capacity; i++)
{
if (slots[i].Disabled) continue;
//don't draw the item if it's being dragged out of the slot
bool drawItem = draggingItem == null || draggingItem != Items[i] || slots[i].IsHighlighted;
DrawSlot(spriteBatch, slots[i], Items[i], drawItem);
}
if (draggingItem != null &&
(draggingSlot == null || (!draggingSlot.Rect.Contains(PlayerInput.MousePosition) && draggingItem.ParentInventory == this)))
{
Rectangle dragRect = new Rectangle(
(int)PlayerInput.MousePosition.X - 10,
(int)PlayerInput.MousePosition.Y - 10,
40, 40);
DrawSlot(spriteBatch, new InventorySlot(dragRect), draggingItem);
}
for (int i = 0; i < capacity; i++)
{
if (slots[i].IsHighlighted && !slots[i].Disabled && Items[i] != null)
{
string toolTip = "";
if (GameMain.DebugDraw)
{
toolTip = Items[i].ToString();
}
else
{
toolTip = string.IsNullOrEmpty(Items[i].Description) ?
Items[i].Name :
Items[i].Name + '\n' + Items[i].Description;
}
DrawToolTip(spriteBatch, toolTip, slots[i].Rect);
break;
}
}
}
protected void DrawToolTip(SpriteBatch spriteBatch, string toolTip, Rectangle highlightedSlot)
{
int maxWidth = 300;
toolTip = ToolBox.WrapText(toolTip, maxWidth, GUI.Font);
Vector2 textSize = GUI.Font.MeasureString(toolTip);
Vector2 rectSize = textSize * 1.2f;
Vector2 pos = new Vector2(highlightedSlot.Right, highlightedSlot.Y-rectSize.Y);
pos.X = (int)(pos.X + 3);
pos.Y = (int)pos.Y;
GUI.DrawRectangle(spriteBatch, pos, rectSize, Color.Black * 0.8f, true);
GUI.Font.DrawString(spriteBatch, toolTip,
new Vector2((int)(pos.X + rectSize.X * 0.5f), (int)(pos.Y + rectSize.Y * 0.5f)),
Color.White, 0.0f,
new Vector2((int)(textSize.X * 0.5f), (int)(textSize.Y * 0.5f)),
1.0f, SpriteEffects.None, 0.0f);
}
protected void UpdateSlot(InventorySlot slot, int slotIndex, Item item, bool isSubSlot)
{
bool mouseOn = slot.Rect.Contains(PlayerInput.MousePosition) && !Locked;
#if CLIENT
slot.State = GUIComponent.ComponentState.None;
#endif
if (!(this is CharacterInventory) && !mouseOn && selectedSlot==slotIndex)
{
@@ -393,7 +294,9 @@ namespace Barotrauma
if (mouseOn &&
(draggingItem!=null || selectedSlot==slotIndex || selectedSlot==-1))
{
#if CLIENT
slot.State = GUIComponent.ComponentState.Hover;
#endif
if (!isSubSlot && selectedSlot == -1)
{
@@ -420,11 +323,15 @@ namespace Barotrauma
//selectedSlot = slotIndex;
if (TryPutItem(draggingItem, slotIndex, true))
{
#if CLIENT
if (slots != null) slots[slotIndex].ShowBorderHighlight(Color.White, 0.1f, 0.4f);
#endif
}
else
{
#if CLIENT
if (slots != null) slots[slotIndex].ShowBorderHighlight(Color.Red, 0.1f, 0.9f);
#endif
}
draggingItem = null;
draggingSlot = null;
@@ -460,83 +367,11 @@ namespace Barotrauma
container.Inventory.isSubInventory = true;
#if CLIENT
slots[slotIndex].State = GUIComponent.ComponentState.Hover;
container.Inventory.Update(deltaTime, true);
}
public void DrawSubInventory(SpriteBatch spriteBatch, int slotIndex)
{
var item = Items[slotIndex];
if (item == null) return;
var container = item.GetComponent<ItemContainer>();
if (container == null) return;
if (container.Inventory.slots == null || !container.Inventory.isSubInventory) return;
int itemCapacity = container.Capacity;
#if DEBUG
System.Diagnostics.Debug.Assert(slotIndex >= 0 && slotIndex < Items.Length);
#else
if (slotIndex < 0 || slotIndex >= Items.Length) return;
#endif
var slot = slots[slotIndex];
Rectangle containerRect = new Rectangle(slot.Rect.X - 5, slot.Rect.Y - (40 + 10) * itemCapacity - 5,
slot.Rect.Width + 10, slot.Rect.Height + (40 + 10) * itemCapacity + 10);
GUI.DrawRectangle(spriteBatch, new Rectangle(containerRect.X, containerRect.Y, containerRect.Width, containerRect.Height - slot.Rect.Height - 5), Color.Black * 0.8f, true);
GUI.DrawRectangle(spriteBatch, containerRect, Color.White);
container.Inventory.Draw(spriteBatch, true);
if (!containerRect.Contains(PlayerInput.MousePosition))
{
if (draggingItem == null || draggingItem.Container != item) selectedSlot = -1;
}
}
protected void DrawSlot(SpriteBatch spriteBatch, InventorySlot slot, Item item, bool drawItem=true)
{
Rectangle rect = slot.Rect;
GUI.DrawRectangle(spriteBatch, rect, (slot.IsHighlighted ? Color.Red * 0.4f : slot.Color), true);
if (item != null && drawItem)
{
if (item.Condition < 100.0f)
{
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X, rect.Bottom - 8, rect.Width, 8), Color.Black*0.8f, true);
GUI.DrawRectangle(spriteBatch,
new Rectangle(rect.X, rect.Bottom - 8, (int)(rect.Width * item.Condition / 100.0f), 8),
Color.Lerp(Color.Red, Color.Green, item.Condition / 100.0f)*0.8f, true);
}
var containedItems = item.ContainedItems;
if (containedItems != null && containedItems.Length == 1 && containedItems[0].Condition < 100.0f)
{
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X, rect.Y, rect.Width, 8), Color.Black*0.8f, true);
GUI.DrawRectangle(spriteBatch,
new Rectangle(rect.X, rect.Y, (int)(rect.Width * containedItems[0].Condition / 100.0f), 8),
Color.Lerp(Color.Red, Color.Green, containedItems[0].Condition / 100.0f)*0.8f, true);
}
}
GUI.DrawRectangle(spriteBatch, rect, (slot.IsHighlighted ? Color.Red * 0.4f : slot.Color), false);
if (slot.BorderHighlightColor != Color.Transparent)
{
Rectangle highlightRect = slot.Rect;
highlightRect.Inflate(3,3);
GUI.DrawRectangle(spriteBatch, highlightRect, slot.BorderHighlightColor, false, 0, 5);
}
if (item == null || !drawItem) return;
item.Sprite.Draw(spriteBatch, new Vector2(rect.X + rect.Width / 2, rect.Y + rect.Height / 2), item.Color);
container.Inventory.Update(deltaTime, true);
}
public void ClientWrite(NetBuffer msg, object[] extraData = null)

View File

@@ -34,6 +34,15 @@ namespace Barotrauma
//the position and dimensions of the entity
protected Rectangle rect;
//is the mouse inside the rect
protected bool isHighlighted;
public bool IsHighlighted
{
get { return isHighlighted; }
set { isHighlighted = value; }
}
private static bool resizing;
private int resizeDirX, resizeDirY;

View File

@@ -43,7 +43,7 @@ namespace Barotrauma
}
}
class Structure : MapEntity, IDamageable, IServerSerializable
partial class Structure : MapEntity, IDamageable, IServerSerializable
{
public static int wallSectionSize = 96;
public static List<Structure> WallList = new List<Structure>();
@@ -517,91 +517,6 @@ namespace Barotrauma
return true;
}
public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true)
{
if (prefab.sprite == null) return;
Draw(spriteBatch, editing, back, null);
}
public override void DrawDamage(SpriteBatch spriteBatch, Effect damageEffect)
{
Draw(spriteBatch, false, false, damageEffect);
}
private void Draw(SpriteBatch spriteBatch, bool editing, bool back = true, Effect damageEffect = null)
{
if (prefab.sprite == null) return;
Color color = (isHighlighted) ? Color.Orange : Color.White;
if (IsSelected && editing)
{
color = Color.Red;
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X, -rect.Y, rect.Width, rect.Height), color);
}
Vector2 drawOffset = Submarine == null ? Vector2.Zero : Submarine.DrawPosition;
float depth = prefab.sprite.Depth;
depth -= (ID % 255) * 0.000001f;
if (back && damageEffect == null)
{
if (prefab.BackgroundSprite != null)
{
prefab.BackgroundSprite.DrawTiled(
spriteBatch,
new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)),
new Vector2(rect.Width, rect.Height),
color, Point.Zero);
}
}
SpriteEffects oldEffects = prefab.sprite.effects;
prefab.sprite.effects ^= SpriteEffects;
if (back == prefab.sprite.Depth > 0.5f || editing)
{
for (int i = 0; i < sections.Length; i++)
{
if (damageEffect != null)
{
float newCutoff = Math.Min((sections[i].damage / prefab.MaxHealth), 0.65f);
if (Math.Abs(newCutoff - Submarine.DamageEffectCutoff) > 0.01f)
{
damageEffect.Parameters["aCutoff"].SetValue(newCutoff);
damageEffect.Parameters["cCutoff"].SetValue(newCutoff * 1.2f);
damageEffect.CurrentTechnique.Passes[0].Apply();
Submarine.DamageEffectCutoff = newCutoff;
}
}
Point textureOffset = new Point(
Math.Abs(rect.Location.X - sections[i].rect.Location.X),
Math.Abs(rect.Location.Y - sections[i].rect.Location.Y));
if (flippedX && isHorizontal)
{
textureOffset.X = rect.Width - textureOffset.X - sections[i].rect.Width;
}
prefab.sprite.DrawTiled(
spriteBatch,
new Vector2(sections[i].rect.X + drawOffset.X, -(sections[i].rect.Y + drawOffset.Y)),
new Vector2(sections[i].rect.Width, sections[i].rect.Height),
color,
textureOffset, depth);
}
}
prefab.sprite.effects = oldEffects;
}
private bool OnWallCollision(Fixture f1, Fixture f2, Contact contact)
{
if (prefab.IsPlatform)
@@ -632,10 +547,12 @@ namespace Barotrauma
if (impact < 10.0f) return true;
#if CLIENT
SoundPlayer.PlayDamageSound(DamageSoundType.StructureBlunt, impact,
new Vector2(
sections[section].rect.X + sections[section].rect.Width / 2,
sections[section].rect.Y - sections[section].rect.Height / 2));
#endif
AddDamage(section, impact);
}
@@ -685,6 +602,7 @@ namespace Barotrauma
var section = sections[sectionIndex];
#if CLIENT
float particleAmount = Math.Min(Health - section.damage, damage) * Rand.Range(0.01f, 1.0f);
particleAmount = Math.Min(particleAmount + Rand.Range(-5,1), 100);
@@ -695,10 +613,11 @@ namespace Barotrauma
Rand.Range(section.rect.Y - section.rect.Height, section.rect.Y));
if (Submarine != null) particlePos += Submarine.DrawPosition;
var particle = GameMain.ParticleManager.CreateParticle("shrapnel", particlePos, Rand.Vector(Rand.Range(1.0f, 50.0f)));
if (particle == null) break;
}
#endif
if (GameMain.Client == null) SetDamage(sectionIndex, section.damage + damage);
}
@@ -753,18 +672,20 @@ namespace Barotrauma
int i = FindSectionIndex(transformedPos);
if (i == -1) return new AttackResult(0.0f, 0.0f);
GameMain.ParticleManager.CreateParticle("dustcloud", SectionPosition(i), 0.0f, 0.0f);
float damageAmount = attack.GetStructureDamage(deltaTime);
AddDamage(i, damageAmount);
#if CLIENT
GameMain.ParticleManager.CreateParticle("dustcloud", SectionPosition(i), 0.0f, 0.0f);
if (playSound && !SectionBodyDisabled(i))
{
DamageSoundType damageSoundType = (attack.DamageType == DamageType.Blunt) ? DamageSoundType.StructureBlunt : DamageSoundType.StructureSlash;
SoundPlayer.PlayDamageSound(damageSoundType, damageAmount, worldPosition);
}
AddDamage(i, damageAmount);
#endif
return new AttackResult(damageAmount, 0.0f);
}
@@ -928,39 +849,6 @@ namespace Barotrauma
CreateSections();
}
public override XElement Save(XElement parentElement)
{
XElement element = new XElement("Structure");
element.Add(new XAttribute("name", prefab.Name),
new XAttribute("ID", ID),
new XAttribute("rect",
(int)(rect.X - Submarine.HiddenSubPosition.X) + "," +
(int)(rect.Y - Submarine.HiddenSubPosition.Y) + "," +
rect.Width + "," + rect.Height));
for (int i = 0; i < sections.Length; i++)
{
if (sections[i].damage == 0.0f) continue;
var sectionElement =
new XElement("section",
new XAttribute("i", i),
new XAttribute("damage", sections[i].damage));
if (sections[i].gap!=null)
{
sectionElement.Add(new XAttribute("gap", sections[i].gap.ID));
}
element.Add(sectionElement);
}
parentElement.Add(element);
return element;
}
public static void Load(XElement element, Submarine submarine)
{
string rectString = ToolBox.GetAttributeString(element, "rect", "0,0,0,0");

View File

@@ -6,7 +6,7 @@ using System.Collections.Generic;
namespace Barotrauma
{
class StructurePrefab : MapEntityPrefab
partial class StructurePrefab : MapEntityPrefab
{
//public static List<StructurePrefab> list = new List<StructurePrefab>();
@@ -188,38 +188,5 @@ namespace Barotrauma
if (PlayerInput.RightButtonHeld()) selected = null;
}
public override void DrawPlacing(SpriteBatch spriteBatch, Camera cam)
{
Vector2 position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub);
//Vector2 placeSize = size;
Rectangle newRect = new Rectangle((int)position.X, (int)position.Y, (int)size.X, (int)size.Y);
if (placePosition == Vector2.Zero)
{
if (PlayerInput.LeftButtonHeld())
placePosition = Submarine.MouseToWorldGrid(cam, Submarine.MainSub);
newRect.X = (int)position.X;
newRect.Y = (int)position.Y;
//sprite.Draw(spriteBatch, new Vector2(position.X, -position.Y), placeSize, Color.White);
}
else
{
Vector2 placeSize = size;
if (resizeHorizontal) placeSize.X = position.X - placePosition.X;
if (resizeVertical) placeSize.Y = placePosition.Y - position.Y;
newRect = Submarine.AbsRect(placePosition, placeSize);
}
sprite.DrawTiled(spriteBatch, new Vector2(newRect.X, -newRect.Y), new Vector2(newRect.Width, newRect.Height), Color.White);
GUI.DrawRectangle(spriteBatch, new Rectangle(newRect.X - GameMain.GraphicsWidth, -newRect.Y, newRect.Width + GameMain.GraphicsWidth * 2, newRect.Height), Color.White);
GUI.DrawRectangle(spriteBatch, new Rectangle(newRect.X, -newRect.Y - GameMain.GraphicsHeight, newRect.Width, newRect.Height + GameMain.GraphicsHeight * 2), Color.White);
}
}
}

View File

@@ -4,8 +4,8 @@ using System.Linq;
using System.Xml.Linq;
using FarseerPhysics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
//using Microsoft.Xna.Framework.Graphics;
//using Microsoft.Xna.Framework.Input;
using System.Collections.ObjectModel;
using Barotrauma.Items.Components;
using FarseerPhysics.Dynamics;
@@ -13,16 +13,12 @@ using FarseerPhysics.Dynamics;
namespace Barotrauma
{
public enum SpawnType { Path, Human, Enemy, Cargo };
class WayPoint : MapEntity
partial class WayPoint : MapEntity
{
public static List<WayPoint> WayPointList = new List<WayPoint>();
public static bool ShowWayPoints = true, ShowSpawnPoints = true;
private static Texture2D iconTexture;
private const int IconSize = 32;
private static int[] iconIndices = { 3, 0, 1, 2 };
protected SpawnType spawnType;
//characters spawning at the waypoint will be given an ID card with these tags
@@ -102,10 +98,12 @@ namespace Barotrauma
linkedTo = new ObservableCollection<MapEntity>();
idCardTags = new string[0];
#if CLIENT
if (iconTexture==null)
{
iconTexture = Sprite.LoadTexture("Content/Map/waypointIcons.png");
}
#endif
InsertToList();
WayPointList.Add(this);
@@ -125,203 +123,13 @@ namespace Barotrauma
public override bool IsMouseOn(Vector2 position)
{
#if CLIENT
if (IsHidden()) return false;
#endif
return base.IsMouseOn(position);
}
public override void Draw(SpriteBatch spriteBatch, bool editing, bool back=true)
{
if (!editing && !GameMain.DebugDraw) return;
if (IsHidden()) return;
//Rectangle drawRect =
// Submarine == null ? rect : new Rectangle((int)(Submarine.DrawPosition.X + rect.X), (int)(Submarine.DrawPosition.Y + rect.Y), rect.Width, rect.Height);
Vector2 drawPos = Position;
if (Submarine!=null) drawPos += Submarine.DrawPosition;
drawPos.Y = -drawPos.Y;
Color clr = currentHull == null ? Color.Blue : Color.White;
if (IsSelected) clr = Color.Red;
if (isHighlighted) clr = Color.DarkRed;
int iconX = iconIndices[(int)spawnType]*IconSize % iconTexture.Width;
int iconY = (int)(Math.Floor(iconIndices[(int)spawnType]*IconSize / (float)iconTexture.Width))*IconSize;
int iconSize = ConnectedGap == null && Ladders == null ? IconSize : (int)(IconSize * 1.5f);
spriteBatch.Draw(iconTexture,
new Rectangle((int)(drawPos.X - iconSize/2), (int)(drawPos.Y - iconSize/2), iconSize, iconSize),
new Rectangle(iconX, iconY, IconSize,IconSize), clr);
//GUI.DrawRectangle(spriteBatch, new Rectangle(drawRect.X, -drawRect.Y, rect.Width, rect.Height), clr, true);
//GUI.SmallFont.DrawString(spriteBatch, Position.ToString(), new Vector2(Position.X, -Position.Y), Color.White);
foreach (MapEntity e in linkedTo)
{
GUI.DrawLine(spriteBatch,
drawPos,
new Vector2(e.DrawPosition.X, -e.DrawPosition.Y),
Color.Green);
}
}
private bool IsHidden()
{
if (spawnType == SpawnType.Path)
{
return (!GameMain.DebugDraw && !ShowWayPoints);
}
else
{
return (!GameMain.DebugDraw && !ShowSpawnPoints);
}
}
public override void UpdateEditing(Camera cam)
{
if (editingHUD == null || editingHUD.UserData != this)
{
editingHUD = CreateEditingHUD();
}
editingHUD.Update((float)Timing.Step);
if (PlayerInput.LeftButtonClicked())
{
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
foreach (MapEntity e in mapEntityList)
{
if (e.GetType() != typeof(WayPoint)) continue;
if (e == this) continue;
if (!Submarine.RectContains(e.Rect, position)) continue;
linkedTo.Add(e);
e.linkedTo.Add(this);
}
}
}
public override void DrawEditing(SpriteBatch spriteBatch, Camera cam)
{
if (editingHUD != null) editingHUD.Draw(spriteBatch);
}
private bool ChangeSpawnType(GUIButton button, object obj)
{
GUITextBlock spawnTypeText = button.Parent as GUITextBlock;
spawnType += (int)button.UserData;
if (spawnType > SpawnType.Cargo) spawnType = SpawnType.Human;
if (spawnType < SpawnType.Human) spawnType = SpawnType.Cargo;
spawnTypeText.Text = spawnType.ToString();
return true;
}
private bool EnterIDCardTags(GUITextBox textBox, string text)
{
IdCardTags = text.Split(',');
textBox.Text = text;
textBox.Color = Color.Green;
textBox.Deselect();
return true;
}
private bool EnterAssignedJob(GUITextBox textBox, string text)
{
string trimmedName = text.ToLowerInvariant().Trim();
assignedJob = JobPrefab.List.Find(jp => jp.Name.ToLowerInvariant() == trimmedName);
if (assignedJob !=null && trimmedName!="none")
{
textBox.Color = Color.Green;
textBox.Text = (assignedJob == null) ? "None" : assignedJob.Name;
}
textBox.Deselect();
return true;
}
private bool TextBoxChanged(GUITextBox textBox, string text)
{
textBox.Color = Color.Red;
return true;
}
private GUIComponent CreateEditingHUD(bool inGame = false)
{
int width = 500;
int height = spawnType == SpawnType.Path ? 100 : 140;
int x = GameMain.GraphicsWidth / 2 - width / 2, y = 10;
editingHUD = new GUIFrame(new Rectangle(x, y, width, height), Color.Black * 0.5f);
editingHUD.Padding = new Vector4(10, 10, 0, 0);
editingHUD.UserData = this;
if (spawnType == SpawnType.Path)
{
new GUITextBlock(new Rectangle(0, 0, 100, 20), "Editing waypoint", "", editingHUD);
new GUITextBlock(new Rectangle(0, 20, 100, 20), "Hold space to link to another waypoint", "", editingHUD);
}
else
{
new GUITextBlock(new Rectangle(0, 0, 100, 20), "Editing spawnpoint", "", editingHUD);
new GUITextBlock(new Rectangle(0, 25, 100, 20), "Spawn type: ", "", editingHUD);
var spawnTypeText = new GUITextBlock(new Rectangle(0, 25, 200, 20), spawnType.ToString(), "", Alignment.Right, Alignment.TopLeft, editingHUD);
var button = new GUIButton(new Rectangle(-30,0,20,20), "-", Alignment.Right, "", spawnTypeText);
button.UserData = -1;
button.OnClicked = ChangeSpawnType;
button = new GUIButton(new Rectangle(0, 0, 20, 20), "+", Alignment.Right, "", spawnTypeText);
button.UserData = 1;
button.OnClicked = ChangeSpawnType;
y = 40 + 20;
new GUITextBlock(new Rectangle(0, y, 100, 20), "ID Card tags:", Color.Transparent, Color.White, Alignment.TopLeft, null, editingHUD);
GUITextBox propertyBox = new GUITextBox(new Rectangle(100, y, 200, 20), "", editingHUD);
propertyBox.Text = string.Join(", ", idCardTags);
propertyBox.OnEnterPressed = EnterIDCardTags;
propertyBox.OnTextChanged = TextBoxChanged;
propertyBox.ToolTip = "Characters spawning at this spawnpoint will have the specified tags added to their ID card. You can, for example, use these tags to limit access to some parts of the sub.";
y = y + 30;
new GUITextBlock(new Rectangle(0, y, 100, 20), "Assigned job:", Color.Transparent, Color.White, Alignment.TopLeft, null, editingHUD);
propertyBox = new GUITextBox(new Rectangle(100, y, 200, 20), "", editingHUD);
propertyBox.Text = (assignedJob == null) ? "None" : assignedJob.Name;
propertyBox.OnEnterPressed = EnterAssignedJob;
propertyBox.OnTextChanged = TextBoxChanged;
propertyBox.ToolTip = "Only characters with the specified job will spawn at this spawnpoint.";
}
//GUI.Font.DrawString(spriteBatch, "Spawnpoint: " + spawnType.ToString() + " +/-", new Vector2(x, y + 40), Color.Black);
y = y + 30;
return editingHUD;
}
public static void GenerateSubWaypoints(Submarine submarine)
{
if (!Hull.hullList.Any())
@@ -747,42 +555,6 @@ namespace Barotrauma
}
}
public override XElement Save(XElement parentElement)
{
if (MoveWithLevel) return null;
XElement element = new XElement("WayPoint");
element.Add(new XAttribute("ID", ID),
new XAttribute("x", (int)(rect.X - Submarine.HiddenSubPosition.X)),
new XAttribute("y", (int)(rect.Y - Submarine.HiddenSubPosition.Y)),
new XAttribute("spawn", spawnType));
if (idCardTags.Length > 0)
{
element.Add(new XAttribute("idcardtags", string.Join(",", idCardTags)));
}
if (assignedJob != null) element.Add(new XAttribute("job", assignedJob.Name));
if (ConnectedGap != null) element.Add(new XAttribute("gap", ConnectedGap.ID));
if (Ladders != null) element.Add(new XAttribute("ladders", Ladders.Item.ID));
parentElement.Add(element);
if (linkedTo != null)
{
int i = 0;
foreach (MapEntity e in linkedTo)
{
element.Add(new XAttribute("linkedto" + i, e.ID));
i += 1;
}
}
return element;
}
public static void Load(XElement element, Submarine submarine)
{
Rectangle rect = new Rectangle(

View File

@@ -39,13 +39,10 @@ namespace Barotrauma.Networking
private IRestResponse masterServerResponse;
private ServerLog log;
private GUIButton showLogButton;
private bool initiatedStartGame;
private CoroutineHandle startGameCoroutine;
private GUIScrollBar clientListScrollBar;
public TraitorManager TraitorManager;
private ServerEntityEventManager entityEventManager;
@@ -122,40 +119,7 @@ namespace Barotrauma.Networking
config.EnableMessageType(NetIncomingMessageType.ConnectionApproval);
//----------------------------------------
var endRoundButton = new GUIButton(new Rectangle(GameMain.GraphicsWidth - 170, 20, 150, 20), "End round", Alignment.TopLeft, "", inGameHUD);
endRoundButton.OnClicked = (btn, userdata) => { EndGame(); return true; };
log = new ServerLog(name);
showLogButton = new GUIButton(new Rectangle(GameMain.GraphicsWidth - 170 - 170, 20, 150, 20), "Server Log", Alignment.TopLeft, "", inGameHUD);
showLogButton.OnClicked = (GUIButton button, object userData) =>
{
if (log.LogFrame == null)
{
log.CreateLogFrame();
}
else
{
log.LogFrame = null;
GUIComponent.KeyboardDispatcher.Subscriber = null;
}
return true;
};
GUIButton settingsButton = new GUIButton(new Rectangle(GameMain.GraphicsWidth - 170 - 170 - 170, 20, 150, 20), "Settings", Alignment.TopLeft, "", inGameHUD);
settingsButton.OnClicked = ToggleSettingsFrame;
settingsButton.UserData = "settingsButton";
entityEventManager = new ServerEntityEventManager(this);
whitelist = new WhiteList();
banList = new BanList();
LoadSettings();
LoadClientPermissions();
//----------------------------------------
InitProjSpecific();
CoroutineManager.StartCoroutine(StartServer(isPublic));
}
@@ -181,6 +145,7 @@ namespace Barotrauma.Networking
System.Net.Sockets.SocketException socketException = e as System.Net.Sockets.SocketException;
#if CLIENT
if (socketException != null && socketException.SocketErrorCode == System.Net.Sockets.SocketError.AddressAlreadyInUse)
{
new GUIMessageBox("Starting the server failed", e.Message + ". Are you trying to run multiple servers on the same port?");
@@ -189,6 +154,7 @@ namespace Barotrauma.Networking
{
new GUIMessageBox("Starting the server failed", e.Message);
}
#endif
error = true;
}
@@ -197,26 +163,27 @@ namespace Barotrauma.Networking
{
if (server != null) server.Shutdown("Error while starting the server");
#if CLIENT
GameMain.NetworkMember = null;
#elif SERVER
Environment.Exit(-1);
#endif
yield return CoroutineStatus.Success;
}
if (config.EnableUPnP)
{
server.UPnP.ForwardPort(config.Port, "barotrauma");
GUIMessageBox upnpBox = new GUIMessageBox("Please wait...", "Attempting UPnP port forwarding", new string[] {"Cancel"} );
upnpBox.Buttons[0].OnClicked = upnpBox.Close;
InitUPnP();
//DateTime upnpTimeout = DateTime.Now + new TimeSpan(0,0,5);
while (server.UPnP.Status == UPnPStatus.Discovering
&& GUIMessageBox.VisibleBox == upnpBox)// && upnpTimeout>DateTime.Now)
while (DiscoveringUPnP())// && upnpTimeout>DateTime.Now)
{
yield return null;
}
upnpBox.Close(null,null);
FinishUPnP();
#if CLIENT
if (server.UPnP.Status == UPnPStatus.NotAvailable)
{
new GUIMessageBox("Error", "UPnP not available");
@@ -225,6 +192,7 @@ namespace Barotrauma.Networking
{
new GUIMessageBox("Error", "UPnP discovery timed out");
}
#endif
}
if (isPublic)
@@ -430,7 +398,7 @@ namespace Barotrauma.Networking
if (startGameCoroutine != null && !CoroutineManager.IsCoroutineRunning(startGameCoroutine))
{
if (autoRestart) AutoRestartTimer = Math.Max(AutoRestartInterval, 5.0f);
GameMain.NetLobbyScreen.StartButton.Enabled = true;
GameMain.NetLobbyScreen.StartButtonEnabled = true;
GameMain.NetLobbyScreen.LastUpdateID++;
@@ -441,9 +409,9 @@ namespace Barotrauma.Networking
else if (autoRestart && Screen.Selected == GameMain.NetLobbyScreen && connectedClients.Count>0)
{
AutoRestartTimer -= deltaTime;
if (AutoRestartTimer < 0.0f && GameMain.NetLobbyScreen.StartButton.Enabled)
if (AutoRestartTimer < 0.0f && GameMain.NetLobbyScreen.StartButtonEnabled)
{
StartGameClicked(null,null);
StartGame();
}
}
@@ -930,7 +898,7 @@ namespace Barotrauma.Networking
outmsg.Write(GameMain.NetLobbyScreen.LastUpdateID);
outmsg.Write(GameMain.NetLobbyScreen.GetServerName());
outmsg.Write(GameMain.NetLobbyScreen.ServerMessage.Text);
outmsg.Write(GameMain.NetLobbyScreen.ServerMessageText);
outmsg.Write(c.lastRecvGeneralUpdate < 1);
if (c.lastRecvGeneralUpdate < 1)
@@ -938,10 +906,10 @@ namespace Barotrauma.Networking
isInitialUpdate = true;
ClientWriteInitial(c, outmsg);
}
outmsg.Write((GameMain.NetLobbyScreen.SubList.SelectedData as Submarine).Name);
outmsg.Write((GameMain.NetLobbyScreen.SubList.SelectedData as Submarine).MD5Hash.ToString());
outmsg.Write((GameMain.NetLobbyScreen.ShuttleList.SelectedData as Submarine).Name);
outmsg.Write((GameMain.NetLobbyScreen.ShuttleList.SelectedData as Submarine).MD5Hash.ToString());
outmsg.Write(GameMain.NetLobbyScreen.SelectedSub.Name);
outmsg.Write(GameMain.NetLobbyScreen.SelectedSub.MD5Hash.ToString());
outmsg.Write(GameMain.NetLobbyScreen.SelectedShuttle.Name);
outmsg.Write(GameMain.NetLobbyScreen.SelectedShuttle.MD5Hash.ToString());
outmsg.Write(Voting.AllowSubVoting);
outmsg.Write(Voting.AllowModeVoting);
@@ -950,7 +918,7 @@ namespace Barotrauma.Networking
outmsg.WriteRangedInteger(0, Mission.MissionTypes.Count - 1, (GameMain.NetLobbyScreen.MissionTypeIndex));
outmsg.Write((byte)GameMain.NetLobbyScreen.ModeList.SelectedIndex);
outmsg.Write((byte)GameMain.NetLobbyScreen.SelectedModeIndex);
outmsg.Write(GameMain.NetLobbyScreen.LevelSeed);
outmsg.Write(AutoRestart);
@@ -1015,8 +983,8 @@ namespace Barotrauma.Networking
c.chatMsgQueue[i].ServerWrite(outmsg, c);
}
}
public bool StartGameClicked(GUIButton button, object obj)
public bool StartGame()
{
Submarine selectedSub = null;
Submarine selectedShuttle = GameMain.NetLobbyScreen.SelectedShuttle;
@@ -1033,13 +1001,17 @@ namespace Barotrauma.Networking
if (selectedSub == null)
{
#if CLIENT
GameMain.NetLobbyScreen.SubList.Flash();
#endif
return false;
}
if (selectedShuttle == null)
{
#if CLIENT
GameMain.NetLobbyScreen.ShuttleList.Flash();
#endif
return false;
}
@@ -1048,7 +1020,9 @@ namespace Barotrauma.Networking
if (selectedMode == null)
{
#if CLIENT
GameMain.NetLobbyScreen.ModeList.Flash();
#endif
return false;
}
@@ -1059,7 +1033,7 @@ namespace Barotrauma.Networking
private IEnumerable<object> InitiateStartGame(Submarine selectedSub, Submarine selectedShuttle, GameModePreset selectedMode)
{
GameMain.NetLobbyScreen.StartButton.Enabled = false;
GameMain.NetLobbyScreen.StartButtonEnabled = false;
if (connectedClients.Any())
{
@@ -1086,19 +1060,23 @@ namespace Barotrauma.Networking
if (fileSender.ActiveTransfers.Count > 0)
{
#if CLIENT
var msgBox = new GUIMessageBox("", "Waiting for file transfers to finish before starting the round...", new string[] { "Start now" });
msgBox.Buttons[0].OnClicked += msgBox.Close;
#endif
float waitForTransfersTimer = 20.0f;
while (fileSender.ActiveTransfers.Count > 0 && waitForTransfersTimer > 0.0f)
{
waitForTransfersTimer -= CoroutineManager.UnscaledDeltaTime;
#if CLIENT
//message box close, break and start the round immediately
if (!GUIMessageBox.MessageBoxes.Contains(msgBox))
{
break;
}
#endif
yield return CoroutineStatus.Running;
}
@@ -1116,9 +1094,11 @@ namespace Barotrauma.Networking
entityEventManager.Clear();
GameMain.NetLobbyScreen.StartButton.Enabled = false;
GameMain.NetLobbyScreen.StartButtonEnabled = false;
#if CLIENT
GUIMessageBox.CloseAll();
#endif
roundStartSeed = DateTime.Now.Millisecond;
Rand.SetSyncedSeed(roundStartSeed);
@@ -1261,7 +1241,7 @@ namespace Barotrauma.Networking
AddChatMessage("Press TAB to chat. Use ''r;'' to talk through the radio.", ChatMessageType.Server);
GameMain.NetLobbyScreen.StartButton.Enabled = true;
GameMain.NetLobbyScreen.StartButtonEnabled = true;
gameStarted = true;
initiatedStartGame = false;
@@ -1350,7 +1330,9 @@ namespace Barotrauma.Networking
Character.Controlled = null;
myCharacter = null;
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
#if CLIENT
GameMain.LightManager.LosEnabled = false;
#endif
entityEventManager.Clear();
foreach (Client c in connectedClients)
@@ -1486,7 +1468,9 @@ namespace Barotrauma.Networking
client.Connection.Disconnect(targetmsg);
GameMain.NetLobbyScreen.RemovePlayer(client.name);
#if CLIENT
GameMain.NetLobbyScreen.RemovePlayer(client.name);
#endif
connectedClients.Remove(client);
UpdateVoteStatus();
@@ -1744,85 +1728,12 @@ namespace Barotrauma.Networking
return message;
}
public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
{
base.Draw(spriteBatch);
if (settingsFrame != null)
{
settingsFrame.Draw(spriteBatch);
}
else if (log.LogFrame!=null)
{
log.LogFrame.Draw(spriteBatch);
}
if (!ShowNetStats) return;
GUI.Font.DrawString(spriteBatch, "Unique Events: " + entityEventManager.UniqueEvents.Count, new Vector2(10, 50), Color.White);
int width = 200, height = 300;
int x = GameMain.GraphicsWidth - width, y = (int)(GameMain.GraphicsHeight * 0.3f);
if (clientListScrollBar == null)
{
clientListScrollBar = new GUIScrollBar(new Rectangle(x + width - 10, y, 10, height), "", 1.0f);
}
GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black * 0.7f, true);
GUI.Font.DrawString(spriteBatch, "Network statistics:", new Vector2(x + 10, y + 10), Color.White);
GUI.SmallFont.DrawString(spriteBatch, "Connections: "+server.ConnectionsCount, new Vector2(x + 10, y + 30), Color.White);
GUI.SmallFont.DrawString(spriteBatch, "Received bytes: " + MathUtils.GetBytesReadable(server.Statistics.ReceivedBytes), new Vector2(x + 10, y + 45), Color.White);
GUI.SmallFont.DrawString(spriteBatch, "Received packets: " + server.Statistics.ReceivedPackets, new Vector2(x + 10, y + 60), Color.White);
GUI.SmallFont.DrawString(spriteBatch, "Sent bytes: " + MathUtils.GetBytesReadable(server.Statistics.SentBytes), new Vector2(x + 10, y + 75), Color.White);
GUI.SmallFont.DrawString(spriteBatch, "Sent packets: " + server.Statistics.SentPackets, new Vector2(x + 10, y + 90), Color.White);
int resentMessages = 0;
int clientListHeight = connectedClients.Count * 40;
float scrollBarHeight = (height - 110) / (float)Math.Max(clientListHeight, 110);
if (clientListScrollBar.BarSize != scrollBarHeight)
{
clientListScrollBar.BarSize = scrollBarHeight;
}
int startY = y + 110;
y = (startY - (int)(clientListScrollBar.BarScroll * (clientListHeight-(height - 110))));
foreach (Client c in connectedClients)
{
Color clientColor = c.Connection.AverageRoundtripTime > 0.3f ? Color.Red : Color.White;
if (y >= startY && y < startY + height - 120)
{
GUI.SmallFont.DrawString(spriteBatch, c.name + " ("+c.Connection.RemoteEndPoint.Address.ToString()+")", new Vector2(x + 10, y), clientColor);
GUI.SmallFont.DrawString(spriteBatch, "Ping: " + (int)(c.Connection.AverageRoundtripTime * 1000.0f) + " ms", new Vector2(x+20, y+10), clientColor);
}
if (y + 25 >= startY && y < startY + height - 130) GUI.SmallFont.DrawString(spriteBatch, "Resent messages: " + c.Connection.Statistics.ResentMessages, new Vector2(x + 20, y + 20), clientColor);
resentMessages += (int)c.Connection.Statistics.ResentMessages;
y += 40;
}
clientListScrollBar.Update(1.0f / 60.0f);
clientListScrollBar.Draw(spriteBatch);
netStats.AddValue(NetStats.NetStatType.ResentMessages, Math.Max(resentMessages, 0));
netStats.AddValue(NetStats.NetStatType.SentBytes, server.Statistics.SentBytes);
netStats.AddValue(NetStats.NetStatType.ReceivedBytes, server.Statistics.ReceivedBytes);
netStats.Draw(spriteBatch, new Rectangle(200,0,800,200), this);
}
private void FileTransferChanged(FileSender.FileTransferOut transfer)
{
Client recipient = connectedClients.Find(c => c.Connection == transfer.Connection);
#if CLIENT
UpdateFileTransferIndicator(recipient);
#endif
}
public void SendCancelTransferMsg(FileSender.FileTransferOut transfer)
@@ -1834,42 +1745,6 @@ namespace Barotrauma.Networking
server.SendMessage(msg, transfer.Connection, NetDeliveryMethod.ReliableOrdered, transfer.SequenceChannel);
}
private void UpdateFileTransferIndicator(Client client)
{
var transfers = fileSender.ActiveTransfers.FindAll(t => t.Connection == client.Connection);
var clientNameBox = GameMain.NetLobbyScreen.PlayerList.FindChild(client.name);
var clientInfo = clientNameBox.FindChild("filetransfer");
if (clientInfo == null)
{
clientNameBox.ClearChildren();
clientInfo = new GUIFrame(new Rectangle(0, 0, 180, 0), Color.Transparent, Alignment.TopRight, null, clientNameBox);
clientInfo.UserData = "filetransfer";
}
else if (transfers.Count == 0)
{
clientInfo.Parent.RemoveChild(clientInfo);
}
clientInfo.ClearChildren();
var progressBar = new GUIProgressBar(new Rectangle(0, 4, 160, clientInfo.Rect.Height - 8), Color.Green, "", 0.0f, Alignment.Left, clientInfo);
progressBar.IsHorizontal = true;
progressBar.ProgressGetter = () => { return transfers.Sum(t => t.Progress) / transfers.Count; };
var textBlock = new GUITextBlock(new Rectangle(0, 2, 160, 0), "", "", Alignment.TopLeft, Alignment.Left | Alignment.CenterY, clientInfo, true, GUI.SmallFont);
textBlock.TextGetter = () =>
{ return MathUtils.GetBytesReadable(transfers.Sum(t => t.SentOffset)) + " / " + MathUtils.GetBytesReadable(transfers.Sum(t => t.Data.Length)); };
var cancelButton = new GUIButton(new Rectangle(-5, 0, 14, 0), "X", Alignment.Right, "", clientInfo);
cancelButton.OnClicked = (GUIButton button, object userdata) =>
{
transfers.ForEach(t => fileSender.CancelTransfer(t));
return true;
};
}
public void UpdateVoteStatus()
{
if (server.Connections.Count == 0|| connectedClients.Count == 0) return;
@@ -1920,30 +1795,7 @@ namespace Barotrauma.Networking
SaveClientPermissions();
}
public override bool SelectCrewCharacter(Character character, GUIComponent crewFrame)
{
if (character == null) return false;
var characterFrame = crewFrame.FindChild("selectedcharacter");
if (character != myCharacter)
{
var banButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Ban", Alignment.BottomRight, "", characterFrame);
banButton.UserData = character.Name;
banButton.OnClicked += GameMain.NetLobbyScreen.BanPlayer;
var rangebanButton = new GUIButton(new Rectangle(0, -25, 100, 20), "Ban range", Alignment.BottomRight, "", characterFrame);
rangebanButton.UserData = character.Name;
rangebanButton.OnClicked += GameMain.NetLobbyScreen.BanPlayerRange;
var kickButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Kick", Alignment.BottomLeft, "", characterFrame);
kickButton.UserData = character.Name;
kickButton.OnClicked += GameMain.NetLobbyScreen.KickPlayer;
}
return true;
}
public void SetClientCharacter(Client client, Character newCharacter)
{
if (client == null) return;

View File

@@ -8,7 +8,7 @@ using System.Text;
namespace Barotrauma
{
class Voting
partial class Voting
{
private bool allowSubVoting, allowModeVoting;
@@ -16,83 +16,6 @@ namespace Barotrauma
public bool AllowEndVoting = true;
public bool AllowSubVoting
{
get { return allowSubVoting; }
set
{
if (value == allowSubVoting) return;
allowSubVoting = value;
GameMain.NetLobbyScreen.SubList.Enabled = value || GameMain.Server != null;
GameMain.NetLobbyScreen.InfoFrame.FindChild("subvotes").Visible = value;
if (GameMain.Server != null)
{
UpdateVoteTexts(GameMain.Server.ConnectedClients, VoteType.Sub);
GameMain.Server.UpdateVoteStatus();
}
else
{
GameMain.NetLobbyScreen.SubList.Deselect();
}
}
}
public bool AllowModeVoting
{
get { return allowModeVoting; }
set
{
if (value == allowModeVoting) return;
allowModeVoting = value;
GameMain.NetLobbyScreen.ModeList.Enabled = value || GameMain.Server != null;
GameMain.NetLobbyScreen.InfoFrame.FindChild("modevotes").Visible = value;
if (GameMain.Server != null)
{
UpdateVoteTexts(GameMain.Server.ConnectedClients, VoteType.Mode);
GameMain.Server.UpdateVoteStatus();
}
else
{
GameMain.NetLobbyScreen.ModeList.Deselect();
}
}
}
public void UpdateVoteTexts(List<Client> clients, VoteType voteType)
{
GUIListBox listBox = (voteType == VoteType.Sub) ?
GameMain.NetLobbyScreen.SubList : GameMain.NetLobbyScreen.ModeList;
foreach (GUIComponent comp in listBox.children)
{
GUITextBlock voteText = comp.FindChild("votes") as GUITextBlock;
if (voteText != null) comp.RemoveChild(voteText);
}
List<Pair<object, int>> voteList = GetVoteList(voteType, clients);
foreach (Pair<object, int> votable in voteList)
{
SetVoteText(listBox, votable.First, votable.Second);
}
}
private void SetVoteText(GUIListBox listBox, object userData, int votes)
{
if (userData == null) return;
foreach (GUIComponent comp in listBox.children)
{
if (comp.UserData != userData) continue;
GUITextBlock voteText = comp.FindChild("votes") as GUITextBlock;
if (voteText == null)
{
voteText = new GUITextBlock(new Rectangle(0, 0, 30, 0), "", "", Alignment.Right, Alignment.Right, comp);
voteText.UserData = "votes";
}
voteText.Text = votes == 0 ? "" : votes.ToString();
}
}
private List<Pair<object, int>> GetVoteList(VoteType voteType, List<Client> voters)
{
List<Pair<object, int>> voteList = new List<Pair<object, int>>();
@@ -146,44 +69,10 @@ namespace Barotrauma
GameMain.NetworkMember.EndVoteCount = 0;
GameMain.NetworkMember.EndVoteMax = 0;
#if CLIENT
UpdateVoteTexts(connectedClients, VoteType.Mode);
UpdateVoteTexts(connectedClients, VoteType.Sub);
}
public void ClientWrite(NetBuffer msg, VoteType voteType, object data)
{
if (GameMain.Server != null) return;
msg.Write((byte)voteType);
switch (voteType)
{
case VoteType.Sub:
Submarine sub = data as Submarine;
if (sub == null) return;
msg.Write(sub.Name);
break;
case VoteType.Mode:
GameModePreset gameMode = data as GameModePreset;
if (gameMode == null) return;
msg.Write(gameMode.Name);
break;
case VoteType.EndRound:
if (!(data is bool)) return;
msg.Write((bool)data);
break;
case VoteType.Kick:
Client votedClient = data as Client;
if (votedClient == null) return;
msg.Write(votedClient.ID);
break;
}
msg.WritePadBits();
#endif
}
public void ServerRead(NetIncomingMessage inc, Client sender)
@@ -283,48 +172,5 @@ namespace Barotrauma
msg.WritePadBits();
}
public void ClientRead(NetIncomingMessage inc)
{
if (GameMain.Server != null) return;
AllowSubVoting = inc.ReadBoolean();
if (allowSubVoting)
{
foreach (Submarine sub in Submarine.SavedSubmarines)
{
SetVoteText(GameMain.NetLobbyScreen.SubList, sub, 0);
}
int votableCount = inc.ReadByte();
for (int i = 0; i < votableCount; i++)
{
int votes = inc.ReadByte();
string subName = inc.ReadString();
Submarine sub = Submarine.SavedSubmarines.Find(sm => sm.Name == subName);
SetVoteText(GameMain.NetLobbyScreen.SubList, sub, votes);
}
}
AllowModeVoting = inc.ReadBoolean();
if (allowModeVoting)
{
int votableCount = inc.ReadByte();
for (int i = 0; i < votableCount; i++)
{
int votes = inc.ReadByte();
string modeName = inc.ReadString();
GameModePreset mode = GameModePreset.list.Find(m => m.Name == modeName);
SetVoteText(GameMain.NetLobbyScreen.ModeList, mode, votes);
}
}
AllowEndVoting = inc.ReadBoolean();
if (AllowEndVoting)
{
GameMain.NetworkMember.EndVoteCount = inc.ReadByte();
GameMain.NetworkMember.EndVoteMax = inc.ReadByte();
}
AllowVoteKick = inc.ReadBoolean();
inc.ReadPadBits();
}
}
}