Renamed project folders from Subsurface to Barotrauma

This commit is contained in:
Regalis
2017-06-04 15:00:53 +03:00
parent ad03c8bf0d
commit 94c6a8ea1b
697 changed files with 157 additions and 211 deletions
+97
View File
@@ -0,0 +1,97 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Barotrauma
{
class BlurEffect
{
public readonly Effect Effect;
public BlurEffect(Effect effect, float dx, float dy)
{
Effect = effect;
SetParameters(dx, dy);
}
/// <summary>
/// Computes sample weightings and texture coordinate offsets
/// for one pass of a separable gaussian blur filter.
/// </summary>
public void SetParameters(float dx, float dy)
{
EffectParameter weightsParameter = Effect.Parameters["SampleWeights"];
EffectParameter offsetsParameter = Effect.Parameters["SampleOffsets"];
// Look up how many samples our gaussian blur effect supports.
int sampleCount = weightsParameter.Elements.Count;
// Create temporary arrays for computing our filter settings.
float[] sampleWeights = new float[sampleCount];
Vector2[] sampleOffsets = new Vector2[sampleCount];
sampleWeights[0] = ComputeGaussian(0);
sampleOffsets[0] = new Vector2(0);
float totalWeights = sampleWeights[0];
// Add pairs of additional sample taps, positioned
// along a line in both directions from the center.
for (int i = 0; i < sampleCount / 2; i++)
{
// Store weights for the positive and negative taps.
float weight = ComputeGaussian(i + 1);
sampleWeights[i * 2 + 1] = weight;
sampleWeights[i * 2 + 2] = weight;
totalWeights += weight * 2;
// To get the maximum amount of blurring from a limited number of
// pixel shader samples, we take advantage of the bilinear filtering
// hardware inside the texture fetch unit. If we position our texture
// coordinates exactly halfway between two texels, the filtering unit
// will average them for us, giving two samples for the price of one.
// This allows us to step in units of two texels per sample, rather
// than just one at a time. The 1.5 offset kicks things off by
// positioning us nicely in between two texels.
float sampleOffset = i * 2 + 1.5f;
Vector2 delta = new Vector2(dx, dy) * sampleOffset;
// Store texture coordinate offsets for the positive and negative taps.
sampleOffsets[i * 2 + 1] = delta;
sampleOffsets[i * 2 + 2] = -delta;
}
// Normalize the list of sample weightings, so they will always sum to one.
for (int i = 0; i < sampleWeights.Length; i++)
{
sampleWeights[i] /= totalWeights;
}
weightsParameter.SetValue(sampleWeights);
offsetsParameter.SetValue(sampleOffsets);
}
/// <summary>
/// Evaluates a single point on the gaussian falloff curve.
/// Used for setting up the blur filter weightings.
/// </summary>
float ComputeGaussian(float n)
{
float theta = 2.0f;
return (float)((1.0 / Math.Sqrt(2 * Math.PI * theta)) *
Math.Exp(-(n * n) / (2 * theta * theta)));
}
}
}
@@ -0,0 +1,326 @@
using System;
using System.Linq;
using FarseerPhysics;
using FarseerPhysics.Dynamics.Joints;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;
namespace Barotrauma
{
class EditCharacterScreen : Screen
{
Camera cam;
GUIComponent GUIpanel;
GUIButton physicsButton;
GUIListBox limbList, jointList;
GUIFrame limbPanel;
Character editingCharacter;
Limb editingLimb;
//RevoluteJoint editingJoint;
List<Texture2D> textures;
List<string> texturePaths;
private bool physicsEnabled;
public Camera Cam
{
get { return cam; }
}
public override void Select()
{
base.Select();
GameMain.DebugDraw = true;
cam = new Camera();
GUIpanel = new GUIFrame(new Rectangle(0, 0, 300, GameMain.GraphicsHeight), "");
GUIpanel.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
physicsButton = new GUIButton(new Rectangle(0, 50, 200, 25), "Physics", Alignment.Left, "", GUIpanel);
physicsButton.OnClicked += TogglePhysics;
new GUITextBlock(new Rectangle(0, 80, 0, 25), "Limbs:", "", GUIpanel);
limbList = new GUIListBox(new Rectangle(0, 110, 0, 250), Color.White * 0.7f, "", GUIpanel);
limbList.OnSelected = SelectLimb;
new GUITextBlock(new Rectangle(0, 360, 0, 25), "Joints:", "", GUIpanel);
jointList = new GUIListBox(new Rectangle(0, 390, 0, 250), Color.White * 0.7f, "", GUIpanel);
while (Character.CharacterList.Count > 1)
{
Character.CharacterList.First().Remove();
}
if (Character.CharacterList.Count == 1)
{
if (editingCharacter != Character.CharacterList[0]) UpdateLimbLists(Character.CharacterList[0]);
editingCharacter = Character.CharacterList[0];
Vector2 camPos = editingCharacter.AnimController.Limbs[0].body.SimPosition;
camPos = ConvertUnits.ToDisplayUnits(camPos);
camPos.Y = -camPos.Y;
cam.TargetPos = camPos;
if (physicsEnabled)
{
editingCharacter.Control(1.0f, cam);
}
else
{
cam.TargetPos = Vector2.Zero;
}
}
textures = new List<Texture2D>();
texturePaths = new List<string>();
foreach (Limb limb in editingCharacter.AnimController.Limbs)
{
if (limb.sprite==null || texturePaths.Contains(limb.sprite.FilePath)) continue;
textures.Add(limb.sprite.Texture);
texturePaths.Add(limb.sprite.FilePath);
}
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
public override void Update(double deltaTime)
{
cam.MoveCamera((float)deltaTime);
if (physicsEnabled)
{
Character.UpdateAnimAll((float)deltaTime);
Ragdoll.UpdateAll(cam, (float)deltaTime);
GameMain.World.Step((float)deltaTime);
}
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
{
//cam.UpdateTransform();
graphics.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteSortMode.BackToFront,
BlendState.AlphaBlend,
null, null, null, null,
cam.Transform);
Submarine.Draw(spriteBatch, true);
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.BackToFront,
BlendState.AlphaBlend,
null, null, null, null,
cam.Transform);
//if (EntityPrefab.Selected != null) EntityPrefab.Selected.UpdatePlacing(spriteBatch, cam);
//Entity.DrawSelecting(spriteBatch, cam);
if (editingCharacter!=null)
editingCharacter.Draw(spriteBatch);
spriteBatch.End();
//-------------------- HUD -----------------------------
spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, GameMain.ScissorTestEnable);
GUIpanel.Draw(spriteBatch);
EditLimb(spriteBatch);
int y = 0;
for (int i = 0; i < textures.Count; i++ )
{
int x = GameMain.GraphicsWidth - textures[i].Width;
spriteBatch.Draw(textures[i], new Vector2(x, y), Color.White);
foreach (Limb limb in editingCharacter.AnimController.Limbs)
{
if (limb.sprite == null || limb.sprite.FilePath != texturePaths[i]) continue;
Rectangle rect = limb.sprite.SourceRect;
rect.X += x;
rect.Y += y;
GUI.DrawRectangle(spriteBatch, rect, Color.Red);
Vector2 limbBodyPos = new Vector2(
rect.X + limb.sprite.Origin.X,
rect.Y + limb.sprite.Origin.Y);
DrawJoints(spriteBatch, limb, limbBodyPos);
//if (limb.BodyShapeTexture == null) continue;
//spriteBatch.Draw(limb.BodyShapeTexture, limbBodyPos,
// null, Color.White, 0.0f,
// new Vector2(limb.BodyShapeTexture.Width, limb.BodyShapeTexture.Height) / 2,
// 1.0f, SpriteEffects.None, 0.0f);
GUI.DrawLine(spriteBatch, limbBodyPos + Vector2.UnitY * 5.0f, limbBodyPos - Vector2.UnitY * 5.0f, Color.White);
GUI.DrawLine(spriteBatch, limbBodyPos + Vector2.UnitX * 5.0f, limbBodyPos - Vector2.UnitX * 5.0f, Color.White);
if (Vector2.Distance(PlayerInput.MousePosition, limbBodyPos)<5.0f && PlayerInput.LeftButtonHeld())
{
limb.sprite.Origin += PlayerInput.MouseSpeed;
}
}
y += textures[i].Height;
}
GUI.Draw((float)deltaTime, spriteBatch, cam);
//EntityPrefab.DrawList(spriteBatch, new Vector2(20,50));
//Entity.Edit(spriteBatch, cam);
spriteBatch.End();
}
private void UpdateLimbLists(Character character)
{
limbList.ClearChildren();
foreach (Limb limb in character.AnimController.Limbs)
{
GUITextBlock textBlock = new GUITextBlock(
new Rectangle(0,0,0,25),
limb.type.ToString(),
Color.Transparent,
Color.White,
Alignment.Left, null,
limbList);
textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f);
textBlock.UserData = limb;
}
jointList.ClearChildren();
foreach (RevoluteJoint joint in character.AnimController.limbJoints)
{
Limb limb1 = (Limb)(joint.BodyA.UserData);
Limb limb2 = (Limb)(joint.BodyB.UserData);
GUITextBlock textBlock = new GUITextBlock(
new Rectangle(0, 0, 0, 25),
limb1.type.ToString() + " - " + limb2.type.ToString(),
Color.Transparent,
Color.White,
Alignment.Left, null,
jointList);
textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f);
textBlock.UserData = joint;
}
}
private void DrawJoints(SpriteBatch spriteBatch, Limb limb, Vector2 limbBodyPos)
{
foreach (var joint in editingCharacter.AnimController.limbJoints)
{
Vector2 jointPos = Vector2.Zero;
if (joint.BodyA == limb.body.FarseerBody)
{
jointPos = ConvertUnits.ToDisplayUnits(joint.LocalAnchorA);
}
else if (joint.BodyB == limb.body.FarseerBody)
{
jointPos = ConvertUnits.ToDisplayUnits(joint.LocalAnchorB);
}
else
{
continue;
}
jointPos.Y = -jointPos.Y;
jointPos += limbBodyPos;
if (joint.BodyA == limb.body.FarseerBody)
{
float a1 = joint.UpperLimit - MathHelper.PiOver2;
float a2 = joint.LowerLimit - MathHelper.PiOver2;
float a3 =( a1+a2)/2.0f;
GUI.DrawLine(spriteBatch, jointPos, jointPos + new Vector2((float)Math.Cos(a1), -(float)Math.Sin(a1)) * 30.0f, Color.Green);
GUI.DrawLine(spriteBatch, jointPos, jointPos + new Vector2((float)Math.Cos(a2), -(float)Math.Sin(a2)) * 30.0f, Color.DarkGreen);
GUI.DrawLine(spriteBatch, jointPos, jointPos + new Vector2((float)Math.Cos(a3), -(float)Math.Sin(a3)) * 30.0f, Color.LightGray);
}
GUI.DrawRectangle(spriteBatch, jointPos, new Vector2(5.0f, 5.0f), Color.Red, true);
if (Vector2.Distance(PlayerInput.MousePosition, jointPos) < 6.0f)
{
GUI.DrawRectangle(spriteBatch, jointPos - new Vector2(3.0f, 3.0f), new Vector2(11.0f, 11.0f), Color.Red, false);
if (PlayerInput.LeftButtonHeld())
{
Vector2 speed = ConvertUnits.ToSimUnits(PlayerInput.MouseSpeed);
speed.Y = -speed.Y;
if (joint.BodyA == limb.body.FarseerBody)
{
joint.LocalAnchorA += speed;
}
else
{
joint.LocalAnchorB += speed;
}
}
}
}
}
private bool SelectLimb(GUIComponent component, object selection)
{
try
{
editingLimb = (Limb)selection;
limbPanel = new GUIFrame(new Rectangle(300, 0, 500, 100), Color.Gray*0.8f);
limbPanel.Padding = new Vector4(10.0f,10.0f,10.0f,10.0f);
new GUITextBlock(new Rectangle(0, 0, 200, 25), editingLimb.type.ToString(), Color.Transparent, Color.Black, Alignment.Left, null, limbPanel);
//spriteOrigin = new GUITextBlock(new Rectangle(0, 25, 200, 25), "Sprite origin: ", Color.White, Color.Black, Alignment.Left, limbPanel);
}
catch
{
return false;
}
return true;
}
private void EditLimb(SpriteBatch spriteBatch)
{
if (editingLimb == null) return;
limbPanel.Draw(spriteBatch);
}
private bool TogglePhysics(GUIButton button, object selection)
{
physicsEnabled = !physicsEnabled;
physicsButton.Text = (physicsEnabled) ? "Disable physics" : "Enable physics";
return false;
}
}
}
File diff suppressed because it is too large Load Diff
+443
View File
@@ -0,0 +1,443 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;
namespace Barotrauma
{
class GameScreen : Screen
{
private Camera cam;
private Color waterColor = new Color(0.75f, 0.8f, 0.9f, 1.0f);
readonly RenderTarget2D renderTargetBackground;
readonly RenderTarget2D renderTarget;
readonly RenderTarget2D renderTargetWater;
readonly RenderTarget2D renderTargetAir;
private BlurEffect lightBlur;
private Effect damageEffect;
private Texture2D damageStencil;
public BackgroundCreatureManager BackgroundCreatureManager;
public override Camera Cam
{
get { return cam; }
}
public GameScreen(GraphicsDevice graphics, ContentManager content)
{
cam = new Camera();
cam.Translate(new Vector2(-10.0f, 50.0f));
renderTargetBackground = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight);
renderTarget = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight);
renderTargetWater = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight);
renderTargetAir = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight);
var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.BackgroundCreaturePrefabs);
if(files.Count > 0)
BackgroundCreatureManager = new BackgroundCreatureManager(files);
else
BackgroundCreatureManager = new BackgroundCreatureManager("Content/BackgroundSprites/BackgroundCreaturePrefabs.xml");
#if LINUX
var blurEffect = content.Load<Effect>("blurshader_opengl");
damageEffect = content.Load<Effect>("damageshader_opengl");
#else
var blurEffect = content.Load<Effect>("blurshader");
damageEffect = content.Load<Effect>("damageshader");
#endif
damageStencil = TextureLoader.FromFile("Content/Map/walldamage.png");
damageEffect.Parameters["xStencil"].SetValue(damageStencil);
damageEffect.Parameters["aMultiplier"].SetValue(50.0f);
damageEffect.Parameters["cMultiplier"].SetValue(200.0f);
lightBlur = new BlurEffect(blurEffect, 0.001f, 0.001f);
}
public override void Select()
{
base.Select();
if (Character.Controlled!=null)
{
cam.Position = Character.Controlled.WorldPosition;
cam.UpdateTransform();
}
else if (Submarine.MainSub != null)
{
cam.Position = Submarine.MainSub.WorldPosition;
cam.UpdateTransform();
}
foreach (MapEntity entity in MapEntity.mapEntityList)
entity.IsHighlighted = false;
}
public override void Deselect()
{
base.Deselect();
Sounds.SoundManager.LowPassHFGain = 1.0f;
}
public override void AddToGUIUpdateList()
{
if (Character.Controlled != null && Character.Controlled.SelectedConstruction != null)
{
if (Character.Controlled.SelectedConstruction == Character.Controlled.ClosestItem)
{
Character.Controlled.SelectedConstruction.AddToGUIUpdateList();
}
}
if (GameMain.GameSession != null) GameMain.GameSession.AddToGUIUpdateList();
Character.AddAllToGUIUpdateList();
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
public override void Update(double deltaTime)
{
#if DEBUG
if (GameMain.GameSession != null && GameMain.GameSession.Level != null && GameMain.GameSession.Submarine != null &&
!DebugConsole.IsOpen)
{
var closestSub = Submarine.FindClosest(cam.WorldViewCenter);
if (closestSub == null) closestSub = GameMain.GameSession.Submarine;
Vector2 targetMovement = Vector2.Zero;
if (PlayerInput.KeyDown(Keys.I)) targetMovement.Y += 1.0f;
if (PlayerInput.KeyDown(Keys.K)) targetMovement.Y -= 1.0f;
if (PlayerInput.KeyDown(Keys.J)) targetMovement.X -= 1.0f;
if (PlayerInput.KeyDown(Keys.L)) targetMovement.X += 1.0f;
if (targetMovement != Vector2.Zero)
closestSub.ApplyForce(targetMovement * closestSub.SubBody.Body.Mass * 100.0f);
}
#endif
foreach (MapEntity e in MapEntity.mapEntityList)
{
e.IsHighlighted = false;
}
if (GameMain.GameSession != null) GameMain.GameSession.Update((float)deltaTime);
if (Level.Loaded != null) Level.Loaded.Update((float)deltaTime);
if (Character.Controlled != null && Character.Controlled.SelectedConstruction != null)
{
if (Character.Controlled.SelectedConstruction == Character.Controlled.ClosestItem)
{
Character.Controlled.SelectedConstruction.UpdateHUD(cam, Character.Controlled);
}
}
Character.UpdateAll(cam, (float)deltaTime);
BackgroundCreatureManager.Update(cam, (float)deltaTime);
GameMain.ParticleManager.Update((float)deltaTime);
StatusEffect.UpdateAll((float)deltaTime);
if (Character.Controlled != null && Lights.LightManager.ViewTarget != null)
{
cam.TargetPos = Lights.LightManager.ViewTarget.WorldPosition;
}
GameMain.LightManager.Update((float)deltaTime);
cam.MoveCamera((float)deltaTime);
foreach (Submarine sub in Submarine.Loaded)
{
sub.SetPrevTransform(sub.Position);
}
foreach (PhysicsBody pb in PhysicsBody.list)
{
pb.SetPrevTransform(pb.SimPosition, pb.Rotation);
}
MapEntity.UpdateAll(cam, (float)deltaTime);
Character.UpdateAnimAll((float)deltaTime);
Ragdoll.UpdateAll(cam, (float)deltaTime);
foreach (Submarine sub in Submarine.Loaded)
{
sub.Update((float)deltaTime);
}
GameMain.World.Step((float)deltaTime);
if (!PlayerInput.LeftButtonHeld())
{
Inventory.draggingSlot = null;
Inventory.draggingItem = null;
}
}
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
{
cam.UpdateTransform(true);
Submarine.CullEntities(cam);
DrawMap(graphics, spriteBatch);
spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, GameMain.ScissorTestEnable);
if (Character.Controlled != null && Character.Controlled.SelectedConstruction != null)
{
if (Character.Controlled.SelectedConstruction == Character.Controlled.ClosestItem)
{
Character.Controlled.SelectedConstruction.DrawHUD(spriteBatch, cam, Character.Controlled);
}
}
if (Character.Controlled != null && cam != null) Character.Controlled.DrawHUD(spriteBatch, cam);
if (GameMain.GameSession != null) GameMain.GameSession.Draw(spriteBatch);
if (Character.Controlled == null && !GUI.DisableHUD)
{
for (int i = 0; i < Submarine.MainSubs.Length; i++)
{
if (Submarine.MainSubs[i] != null)
{
Color indicatorColor = i == 0 ? Color.LightBlue * 0.5f : Color.Red * 0.5f;
DrawSubmarineIndicator(spriteBatch, Submarine.MainSubs[i], indicatorColor);
}
}
}
GUI.Draw((float)deltaTime, spriteBatch, cam);
spriteBatch.End();
}
public void DrawMap(GraphicsDevice graphics, SpriteBatch spriteBatch)
{
foreach (Submarine sub in Submarine.Loaded)
{
sub.UpdateTransform();
}
GameMain.ParticleManager.UpdateTransforms();
GameMain.LightManager.ObstructVision = Character.Controlled != null && Character.Controlled.ObstructVision;
GameMain.LightManager.UpdateLightMap(graphics, spriteBatch, cam, lightBlur.Effect);
if (Character.Controlled != null)
{
GameMain.LightManager.UpdateObstructVision(graphics, spriteBatch, cam, Character.Controlled.CursorWorldPosition);
}
//----------------------------------------------------------------------------------------
//1. draw the background, characters and the parts of the submarine that are behind them
//----------------------------------------------------------------------------------------
graphics.SetRenderTarget(renderTargetBackground);
if (Level.Loaded == null)
{
graphics.Clear(new Color(11, 18, 26, 255));
}
else
{
Level.Loaded.DrawBack(graphics, spriteBatch, cam, BackgroundCreatureManager);
}
spriteBatch.Begin(SpriteSortMode.BackToFront,
BlendState.AlphaBlend,
null, null, null, null,
cam.Transform);
Submarine.DrawBack(spriteBatch, false, s => s is Structure);
spriteBatch.End();
graphics.SetRenderTarget(renderTarget);
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.Opaque);
spriteBatch.Draw(renderTargetBackground, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White);
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.BackToFront,
BlendState.AlphaBlend,
null, null, null, null,
cam.Transform);
Submarine.DrawBack(spriteBatch, false, s => !(s is Structure));
foreach (Character c in Character.CharacterList) c.Draw(spriteBatch);
spriteBatch.End();
//----------------------------------------------------------------------------------------
//draw the rendertarget and particles that are only supposed to be drawn in water into renderTargetWater
graphics.SetRenderTarget(renderTargetWater);
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.Opaque);
spriteBatch.Draw(renderTarget, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), waterColor);
spriteBatch.End();
#if LINUX
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.NonPremultiplied,
null, DepthStencilState.DepthRead, null, null,
cam.Transform);
#else
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.AlphaBlend,
null, DepthStencilState.DepthRead, null, null,
cam.Transform);
#endif
GameMain.ParticleManager.Draw(spriteBatch, true, Particles.ParticleBlendState.AlphaBlend);
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.Additive,
null, DepthStencilState.Default, null, null,
cam.Transform);
GameMain.ParticleManager.Draw(spriteBatch, true, Particles.ParticleBlendState.Additive);
spriteBatch.End();
//----------------------------------------------------------------------------------------
//draw the rendertarget and particles that are only supposed to be drawn in air into renderTargetAir
graphics.SetRenderTarget(renderTargetAir);
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.Opaque);
spriteBatch.Draw(renderTarget, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White);
spriteBatch.End();
#if LINUX
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.NonPremultiplied,
null, DepthStencilState.DepthRead, null, null,
cam.Transform);
#else
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.AlphaBlend,
null, DepthStencilState.DepthRead, null, null,
cam.Transform);
#endif
GameMain.ParticleManager.Draw(spriteBatch, false, Particles.ParticleBlendState.AlphaBlend);
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.Additive,
null, DepthStencilState.DepthRead, null, null,
cam.Transform);
GameMain.ParticleManager.Draw(spriteBatch, false, Particles.ParticleBlendState.Additive);
spriteBatch.End();
if (Character.Controlled != null && GameMain.LightManager.LosEnabled)
{
graphics.SetRenderTarget(renderTarget);
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.Opaque, null, null, null, lightBlur.Effect);
spriteBatch.Draw(renderTargetBackground, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White);
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.BackToFront,
BlendState.AlphaBlend, SamplerState.LinearWrap,
null, null, null,
cam.Transform);
Submarine.DrawDamageable(spriteBatch, null, false);
Submarine.DrawFront(spriteBatch, false, s => s is Structure);
spriteBatch.End();
GameMain.LightManager.DrawLOS(spriteBatch, lightBlur.Effect, true);
}
graphics.SetRenderTarget(null);
//----------------------------------------------------------------------------------------
//2. pass the renderTarget to the water shader to do the water effect
//----------------------------------------------------------------------------------------
Hull.renderer.RenderBack(spriteBatch, renderTargetWater);
Array.Clear(Hull.renderer.vertices, 0, Hull.renderer.vertices.Length);
Hull.renderer.PositionInBuffer = 0;
foreach (Hull hull in Hull.hullList)
{
hull.Render(graphics, cam);
}
Hull.renderer.Render(graphics, cam, renderTargetAir, Cam.ShaderTransform);
//----------------------------------------------------------------------------------------
//3. draw the sections of the map that are on top of the water
//----------------------------------------------------------------------------------------
spriteBatch.Begin(SpriteSortMode.BackToFront,
BlendState.AlphaBlend, SamplerState.LinearWrap,
null, null, null,
cam.Transform);
Submarine.DrawFront(spriteBatch, false, null);
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Immediate,
BlendState.NonPremultiplied, SamplerState.LinearWrap,
null, null,
damageEffect,
cam.Transform);
Submarine.DrawDamageable(spriteBatch, damageEffect, false);
spriteBatch.End();
GameMain.LightManager.DrawLightMap(spriteBatch, lightBlur.Effect);
spriteBatch.Begin(SpriteSortMode.BackToFront,
BlendState.AlphaBlend, SamplerState.LinearWrap,
null, null, null,
cam.Transform);
if (Level.Loaded != null) Level.Loaded.DrawFront(spriteBatch);
foreach (Character c in Character.CharacterList) c.DrawFront(spriteBatch,cam);
spriteBatch.End();
if (Character.Controlled != null && GameMain.LightManager.LosEnabled)
{
GameMain.LightManager.DrawLOS(spriteBatch, lightBlur.Effect,false);
spriteBatch.Begin(SpriteSortMode.Immediate,
BlendState.AlphaBlend, SamplerState.LinearWrap, DepthStencilState.None, RasterizerState.CullNone, null);
float r = Math.Min(CharacterHUD.damageOverlayTimer * 0.5f, 0.5f);
spriteBatch.Draw(renderTarget, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight),
Color.Lerp(GameMain.LightManager.AmbientLight*0.5f, Color.Red, r));
spriteBatch.End();
}
}
}
}
+546
View File
@@ -0,0 +1,546 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
namespace Barotrauma
{
class LobbyScreen : Screen
{
enum PanelTab { Crew = 0, Map = 1, Store = 3 }
private GUIFrame topPanel;
private GUIFrame[] bottomPanel;
private GUIButton startButton;
private int selectedRightPanel;
private GUIListBox characterList, hireList;
private GUIListBox selectedItemList;
private GUIListBox storeItemList;
private SinglePlayerMode gameMode;
private GUIFrame previewFrame;
private GUIButton buyButton;
private Level selectedLevel;
float mapZoom = 3.0f;
private string CostTextGetter()
{
return "Cost: "+selectedItemCost.ToString()+" credits";
}
private int selectedItemCost
{
get
{
int cost = 0;
foreach (GUIComponent child in selectedItemList.children)
{
MapEntityPrefab ep = child.UserData as MapEntityPrefab;
if (ep == null) continue;
cost += ep.Price;
}
return cost;
}
}
private CrewManager CrewManager
{
get { return GameMain.GameSession.CrewManager; }
}
public LobbyScreen()
{
Rectangle panelRect = new Rectangle(
40, 40,
GameMain.GraphicsWidth - 80,
100);
topPanel = new GUIFrame(panelRect, "");
topPanel.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
GUITextBlock moneyText = new GUITextBlock(new Rectangle(0, 0, 0, 25), "", "",
Alignment.BottomLeft, Alignment.BottomLeft, topPanel);
moneyText.TextGetter = GetMoney;
GUIButton button = new GUIButton(new Rectangle(-240, 0, 100, 30), "Map", null, Alignment.BottomRight, "", topPanel);
button.UserData = PanelTab.Map;
button.OnClicked = SelectRightPanel;
SelectRightPanel(button, button.UserData);
button = new GUIButton(new Rectangle(-120, 0, 100, 30), "Crew", null, Alignment.BottomRight, "", topPanel);
button.UserData = PanelTab.Crew;
button.OnClicked = SelectRightPanel;
button = new GUIButton(new Rectangle(0, 0, 100, 30), "Store", null, Alignment.BottomRight, "", topPanel);
button.UserData = PanelTab.Store;
button.OnClicked = SelectRightPanel;
//---------------------------------------------------------------
//---------------------------------------------------------------
panelRect = new Rectangle(
40,
panelRect.Bottom + 40,
panelRect.Width,
GameMain.GraphicsHeight - 120 - panelRect.Height);
bottomPanel = new GUIFrame[4];
bottomPanel[(int)PanelTab.Crew] = new GUIFrame(panelRect, "");
bottomPanel[(int)PanelTab.Crew].Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
//new GUITextBlock(new Rectangle(0, 0, 200, 25), "Crew:", Color.Transparent, Color.White, Alignment.Left, "", bottomPanel[(int)PanelTab.Crew]);
int crewColumnWidth = Math.Min(300, (panelRect.Width - 40) / 2);
new GUITextBlock(new Rectangle(0, 0, 100, 20), "Crew:", "", bottomPanel[(int)PanelTab.Crew], GUI.LargeFont);
characterList = new GUIListBox(new Rectangle(0, 40, crewColumnWidth, 0), "", bottomPanel[(int)PanelTab.Crew]);
characterList.OnSelected = SelectCharacter;
//---------------------------------------
bottomPanel[(int)PanelTab.Map] = new GUIFrame(panelRect, "");
bottomPanel[(int)PanelTab.Map].Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
startButton = new GUIButton(new Rectangle(0, 0, 100, 30), "Start",
Alignment.BottomRight, "", bottomPanel[(int)PanelTab.Map]);
startButton.OnClicked = StartShift;
startButton.Enabled = false;
//---------------------------------------
bottomPanel[(int)PanelTab.Store] = new GUIFrame(panelRect, "");
bottomPanel[(int)PanelTab.Store].Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
int sellColumnWidth = (panelRect.Width - 40) / 2 - 20;
selectedItemList = new GUIListBox(new Rectangle(0, 30, sellColumnWidth, 400), Color.White * 0.7f, "", bottomPanel[(int)PanelTab.Store]);
selectedItemList.OnSelected = DeselectItem;
var costText = new GUITextBlock(new Rectangle(0, 0, 100, 25), "Cost: ", "", Alignment.BottomLeft, Alignment.TopLeft, bottomPanel[(int)PanelTab.Store]);
costText.TextGetter = CostTextGetter;
buyButton = new GUIButton(new Rectangle(selectedItemList.Rect.Width - 100, 0, 100, 25), "Buy", Alignment.Bottom, "", bottomPanel[(int)PanelTab.Store]);
buyButton.OnClicked = BuyItems;
storeItemList = new GUIListBox(new Rectangle(0, 30, sellColumnWidth, 400), Color.White * 0.7f, Alignment.TopRight, "", bottomPanel[(int)PanelTab.Store]);
storeItemList.OnSelected = SelectItem;
int x = selectedItemList.Rect.Width + 40;
foreach (MapEntityCategory category in Enum.GetValues(typeof(MapEntityCategory)))
{
var items = MapEntityPrefab.list.FindAll(ep => ep.Price>0.0f && ep.Category.HasFlag(category));
if (!items.Any()) continue;
var categoryButton = new GUIButton(new Rectangle(x, 0, 100, 20), category.ToString(), "", bottomPanel[(int)PanelTab.Store]);
categoryButton.UserData = category;
categoryButton.OnClicked = SelectItemCategory;
if (category==MapEntityCategory.Equipment)
{
SelectItemCategory(categoryButton, category);
}
x += 110;
}
}
public override void Select()
{
base.Select();
gameMode = GameMain.GameSession.gameMode as SinglePlayerMode;
UpdateCharacterLists();
}
private void UpdateLocationTab(Location location)
{
topPanel.RemoveChild(topPanel.FindChild("locationtitle"));
topPanel.UserData = location;
var locationTitle = new GUITextBlock(new Rectangle(0, 0, 200, 25),
"Location: "+location.Name, Color.Transparent, Color.White, Alignment.TopLeft, "", topPanel);
locationTitle.UserData = "locationtitle";
locationTitle.Font = GUI.LargeFont;
if (hireList == null)
{
hireList = new GUIListBox(new Rectangle(0, 40, 300, 0), "", Alignment.Right, bottomPanel[(int)PanelTab.Crew]);
new GUITextBlock(new Rectangle(0, 0, 300, 20), "Hire:", "", Alignment.Right, Alignment.Left, bottomPanel[(int)PanelTab.Crew], false, GUI.LargeFont);
hireList.OnSelected = SelectCharacter;
}
if (location.HireManager == null)
{
hireList.ClearChildren();
hireList.Enabled = false;
new GUITextBlock(new Rectangle(0, 0, 0, 0), "No-one available for hire", Color.Transparent, Color.LightGray, Alignment.Center, Alignment.Center, "", hireList);
return;
}
hireList.Enabled = true;
hireList.ClearChildren();
foreach (CharacterInfo c in location.HireManager.availableCharacters)
{
var frame = c.CreateCharacterFrame(hireList, c.Name + " (" + c.Job.Name + ")", c);
new GUITextBlock(
new Rectangle(0, 0, 0, 25),
c.Salary.ToString(),
null, null,
Alignment.TopRight, "", frame);
}
}
public override void Deselect()
{
SelectLocation(null,null);
base.Deselect();
}
public void SelectLocation(Location location, LocationConnection connection)
{
GUIComponent locationPanel = bottomPanel[(int)PanelTab.Map].GetChild("selectedlocation");
if (locationPanel != null) bottomPanel[(int)PanelTab.Map].RemoveChild(locationPanel);
locationPanel = new GUIFrame(new Rectangle(0, 0, 250, 190), Color.Transparent, Alignment.TopRight, null, bottomPanel[(int)PanelTab.Map]);
locationPanel.UserData = "selectedlocation";
if (location == null) return;
new GUITextBlock(new Rectangle(0, 0, 250, 0), location.Name, "", Alignment.TopLeft, Alignment.TopCenter, locationPanel, true, GUI.LargeFont);
if (GameMain.GameSession.Map.SelectedConnection != null && GameMain.GameSession.Map.SelectedConnection.Mission != null)
{
var mission = GameMain.GameSession.Map.SelectedConnection.Mission;
new GUITextBlock(new Rectangle(0, 80, 0, 20), "Mission: "+mission.Name, "", locationPanel);
new GUITextBlock(new Rectangle(0, 100, 0, 20), "Reward: " + mission.Reward+" credits", "", locationPanel);
new GUITextBlock(new Rectangle(0, 130, 0, 0), mission.Description, "", locationPanel, true);
}
startButton.Enabled = true;
selectedLevel = connection.Level;
}
private void UpdateCharacterLists()
{
characterList.ClearChildren();
foreach (CharacterInfo c in CrewManager.characterInfos)
{
c.CreateCharacterFrame(characterList, c.Name + " ("+c.Job.Name+") ", c);
}
}
private void CreateItemFrame(MapEntityPrefab ep, GUIListBox listBox, int width)
{
GUIFrame frame = new GUIFrame(new Rectangle(0, 0, 0, 50), "ListBoxElement", listBox);
frame.UserData = ep;
frame.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
frame.ToolTip = ep.Description;
ScalableFont font = listBox.Rect.Width < 280 ? GUI.SmallFont : GUI.Font;
GUITextBlock textBlock = new GUITextBlock(
new Rectangle(50, 0, 0, 25),
ep.Name,
null,null,
Alignment.Left, Alignment.CenterX | Alignment.Left,
"", frame);
textBlock.Font = font;
textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
textBlock.ToolTip = ep.Description;
if (ep.sprite != null)
{
GUIImage img = new GUIImage(new Rectangle(0, 0, 40, 40), ep.sprite, Alignment.CenterLeft, frame);
img.Color = ep.SpriteColor;
img.Scale = Math.Min(Math.Min(40.0f / img.SourceRect.Width, 40.0f / img.SourceRect.Height), 1.0f);
}
textBlock = new GUITextBlock(
new Rectangle(width - 80, 0, 80, 25),
ep.Price.ToString(),
null, null, Alignment.TopLeft,
Alignment.TopLeft, "", frame);
textBlock.Font = font;
textBlock.ToolTip = ep.Description;
}
private bool SelectItem(GUIComponent component, object obj)
{
MapEntityPrefab prefab = obj as MapEntityPrefab;
if (prefab == null) return false;
CreateItemFrame(prefab, selectedItemList, selectedItemList.Rect.Width);
buyButton.Enabled = CrewManager.Money >= selectedItemCost;
return false;
}
private bool DeselectItem(GUIComponent component, object obj)
{
MapEntityPrefab prefab = obj as MapEntityPrefab;
if (prefab == null) return false;
selectedItemList.RemoveChild(selectedItemList.children.Find(c => c.UserData == obj));
return false;
}
private bool BuyItems(GUIButton button, object obj)
{
int cost = selectedItemCost;
if (CrewManager.Money < cost) return false;
CrewManager.Money -= cost;
for (int i = selectedItemList.children.Count-1; i>=0; i--)
{
GUIComponent child = selectedItemList.children[i];
ItemPrefab ip = child.UserData as ItemPrefab;
if (ip == null) continue;
gameMode.CargoManager.AddItem(ip);
selectedItemList.RemoveChild(child);
}
return false;
}
public override void AddToGUIUpdateList()
{
base.AddToGUIUpdateList();
topPanel.AddToGUIUpdateList();
bottomPanel[selectedRightPanel].AddToGUIUpdateList();
}
public override void Update(double deltaTime)
{
base.Update(deltaTime);
topPanel.Update((float)deltaTime);
bottomPanel[selectedRightPanel].Update((float)deltaTime);
mapZoom += PlayerInput.ScrollWheelSpeed / 1000.0f;
mapZoom = MathHelper.Clamp(mapZoom, 1.0f, 4.0f);
GameMain.GameSession.Map.Update((float)deltaTime, new Rectangle(
bottomPanel[selectedRightPanel].Rect.X + 20,
bottomPanel[selectedRightPanel].Rect.Y + 20,
bottomPanel[selectedRightPanel].Rect.Width - 310,
bottomPanel[selectedRightPanel].Rect.Height - 40), mapZoom);
}
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
{
if (characterList.CountChildren != CrewManager.characterInfos.Count)
{
UpdateCharacterLists();
}
graphics.Clear(Color.Black);
spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, GameMain.ScissorTestEnable);
Sprite backGround = GameMain.GameSession.Map.CurrentLocation.Type.Background;
spriteBatch.Draw(backGround.Texture, Vector2.Zero, null, Color.White, 0.0f, Vector2.Zero,
Math.Max((float)GameMain.GraphicsWidth / backGround.SourceRect.Width, (float)GameMain.GraphicsHeight / backGround.SourceRect.Height), SpriteEffects.None, 0.0f);
topPanel.Draw(spriteBatch);
bottomPanel[selectedRightPanel].Draw(spriteBatch);
if (selectedRightPanel == (int)PanelTab.Map)
{
GameMain.GameSession.Map.Draw(spriteBatch, new Rectangle(
bottomPanel[selectedRightPanel].Rect.X + 20,
bottomPanel[selectedRightPanel].Rect.Y + 20,
bottomPanel[selectedRightPanel].Rect.Width - 310,
bottomPanel[selectedRightPanel].Rect.Height - 40), mapZoom);
}
if (topPanel.UserData as Location != GameMain.GameSession.Map.CurrentLocation)
{
UpdateLocationTab(GameMain.GameSession.Map.CurrentLocation);
}
GUI.Draw((float)deltaTime, spriteBatch, null);
spriteBatch.End();
}
public bool SelectRightPanel(GUIButton button, object selection)
{
try
{
selectedRightPanel = (int)selection;
}
catch { return false; }
if (button != null)
{
button.Selected = true;
foreach (GUIComponent child in topPanel.children)
{
GUIButton otherButton = child as GUIButton;
if (otherButton == null || otherButton == button) continue;
otherButton.Selected = false;
}
}
return true;
}
private bool SelectItemCategory(GUIButton button, object selection)
{
if (!(selection is MapEntityCategory)) return false;
storeItemList.ClearChildren();
MapEntityCategory category = (MapEntityCategory)selection;
var items = MapEntityPrefab.list.FindAll(ep => ep.Price > 0.0f && ep.Category.HasFlag(category));
int width = storeItemList.Rect.Width;
foreach (MapEntityPrefab ep in items)
{
CreateItemFrame(ep, storeItemList, width);
}
storeItemList.children.Sort((x, y) => (x.UserData as MapEntityPrefab).Name.CompareTo((y.UserData as MapEntityPrefab).Name));
foreach (GUIComponent child in button.Parent.children)
{
var otherButton = child as GUIButton;
if (child.UserData is MapEntityCategory && otherButton != button)
{
otherButton.Selected = false;
}
}
button.Selected = true;
return true;
}
private string GetMoney()
{
return "Money: " + ((GameMain.GameSession == null) ? "0" : string.Format(CultureInfo.InvariantCulture, "{0:N0}", CrewManager.Money)) + " credits";
}
private bool SelectCharacter(GUIComponent component, object selection)
{
GUIComponent prevInfoFrame = null;
foreach (GUIComponent child in bottomPanel[selectedRightPanel].children)
{
if (!(child.UserData is CharacterInfo)) continue;
prevInfoFrame = child;
}
if (prevInfoFrame != null) bottomPanel[selectedRightPanel].RemoveChild(prevInfoFrame);
CharacterInfo characterInfo = selection as CharacterInfo;
if (characterInfo == null) return false;
characterList.Deselect();
hireList.Deselect();
if (Character.Controlled != null && characterInfo == Character.Controlled.Info) return false;
if (previewFrame == null || previewFrame.UserData != characterInfo)
{
int width = Math.Min(300, bottomPanel[(int)PanelTab.Crew].Rect.Width - hireList.Rect.Width - characterList.Rect.Width - 50);
previewFrame = new GUIFrame(new Rectangle(0, 60, width, 300),
new Color(0.0f, 0.0f, 0.0f, 0.8f),
Alignment.TopCenter, "", bottomPanel[selectedRightPanel]);
previewFrame.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
previewFrame.UserData = characterInfo;
characterInfo.CreateInfoFrame(previewFrame);
}
if (component.Parent == hireList)
{
GUIButton hireButton = new GUIButton(new Rectangle(0,0, 100, 20), "Hire", Alignment.BottomCenter, "", previewFrame);
hireButton.UserData = characterInfo;
hireButton.OnClicked = HireCharacter;
}
return true;
}
private bool HireCharacter(GUIButton button, object selection)
{
CharacterInfo characterInfo = selection as CharacterInfo;
if (characterInfo == null) return false;
if (gameMode.TryHireCharacter(GameMain.GameSession.Map.CurrentLocation.HireManager, characterInfo))
{
UpdateLocationTab(GameMain.GameSession.Map.CurrentLocation);
SelectCharacter(null,null);
}
return false;
}
private bool StartShift(GUIButton button, object selection)
{
if (GameMain.GameSession.Map.SelectedConnection == null) return false;
GameMain.Instance.ShowLoading(ShiftLoading());
return true;
}
private IEnumerable<object> ShiftLoading()
{
GameMain.GameSession.StartShift(selectedLevel, true);
GameMain.GameScreen.Select();
yield return CoroutineStatus.Success;
}
public bool QuitToMainMenu(GUIButton button, object selection)
{
GameMain.MainMenuScreen.Select();
return true;
}
}
}
+586
View File
@@ -0,0 +1,586 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Networking;
using System.Linq;
using System.Xml.Linq;
using System.IO;
namespace Barotrauma
{
class MainMenuScreen : Screen
{
public enum Tab { NewGame = 1, LoadGame = 2, HostServer = 3, Settings = 4 }
GUIFrame buttonsTab;
private GUIFrame[] menuTabs;
private GUIListBox subList;
private GUIListBox saveList;
private GUITextBox saveNameBox, seedBox;
private GUITextBox serverNameBox, portBox, passwordBox, maxPlayersBox;
private GUITickBox isPublicBox, useUpnpBox;
private GameMain game;
private Tab selectedTab;
public MainMenuScreen(GameMain game)
{
menuTabs = new GUIFrame[Enum.GetValues(typeof(Tab)).Length+1];
buttonsTab = new GUIFrame(new Rectangle(0,0,0,0), Color.Transparent, Alignment.Left | Alignment.CenterY);
buttonsTab.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
//menuTabs[(int)Tabs.Main].Padding = GUI.style.smallPadding;
int y = (int)(GameMain.GraphicsHeight * 0.3f);
Rectangle panelRect = new Rectangle(
290, y,
500, 360);
GUIButton button = new GUIButton(new Rectangle(50, y, 200, 30), "Tutorial", null, Alignment.TopLeft, Alignment.Left, "", buttonsTab);
button.Color = button.Color * 0.8f;
button.OnClicked = TutorialButtonClicked;
button = new GUIButton(new Rectangle(50, y + 60, 200, 30), "New Game", null, Alignment.TopLeft, Alignment.Left, "", buttonsTab);
button.Color = button.Color * 0.8f;
button.UserData = Tab.NewGame;
button.OnClicked = SelectTab;
button = new GUIButton(new Rectangle(50, y + 100, 200, 30), "Load Game", null, Alignment.TopLeft, Alignment.Left, "", buttonsTab);
button.Color = button.Color * 0.8f;
button.UserData = Tab.LoadGame;
button.OnClicked = SelectTab;
button = new GUIButton(new Rectangle(50, y + 160, 200, 30), "Join Server", null, Alignment.TopLeft, Alignment.Left, "", buttonsTab);
button.Color = button.Color * 0.8f;
//button.UserData = (int)Tabs.JoinServer;
button.OnClicked = JoinServerClicked;
button = new GUIButton(new Rectangle(50, y + 200, 200, 30), "Host Server", null, Alignment.TopLeft, Alignment.Left, "", buttonsTab);
button.Color = button.Color * 0.8f;
button.UserData = Tab.HostServer;
button.OnClicked = SelectTab;
button = new GUIButton(new Rectangle(50, y + 260, 200, 30), "Submarine Editor", null, Alignment.TopLeft, Alignment.Left, "", buttonsTab);
button.Color = button.Color * 0.8f;
button.OnClicked = (GUIButton btn, object userdata) => { GameMain.EditMapScreen.Select(); return true; };
button = new GUIButton(new Rectangle(50, y + 320, 200, 30), "Settings", null, Alignment.TopLeft, Alignment.Left, "", buttonsTab);
button.Color = button.Color * 0.8f;
button.UserData = Tab.Settings;
button.OnClicked = SelectTab;
button = new GUIButton(new Rectangle(0, 0, 150, 30), "Quit", Alignment.BottomRight, "", buttonsTab);
button.Color = button.Color * 0.8f;
button.OnClicked = QuitClicked;
panelRect.Y += 10;
//----------------------------------------------------------------------
menuTabs[(int)Tab.NewGame] = new GUIFrame(panelRect, "");
menuTabs[(int)Tab.NewGame].Padding = new Vector4(20.0f,20.0f,20.0f,20.0f);
//new GUITextBlock(new Rectangle(0, -20, 0, 30), "New Game", null, null, Alignment.CenterX, "", menuTabs[(int)Tabs.NewGame]);
new GUITextBlock(new Rectangle(0, 0, 0, 30), "Selected submarine:", null, null, Alignment.Left, "", menuTabs[(int)Tab.NewGame]);
subList = new GUIListBox(new Rectangle(0, 30, 230, panelRect.Height-100), "", menuTabs[(int)Tab.NewGame]);
UpdateSubList();
new GUITextBlock(new Rectangle((int)(subList.Rect.Width + 20), 0, 100, 20),
"Save name: ", "", Alignment.Left, Alignment.Left, menuTabs[(int)Tab.NewGame]);
saveNameBox = new GUITextBox(new Rectangle((int)(subList.Rect.Width + 30), 30, 180, 20),
Alignment.TopLeft, "", menuTabs[(int)Tab.NewGame]);
new GUITextBlock(new Rectangle((int)(subList.Rect.Width + 20), 60, 100, 20),
"Map Seed: ", "", Alignment.Left, Alignment.Left, menuTabs[(int)Tab.NewGame]);
seedBox = new GUITextBox(new Rectangle((int)(subList.Rect.Width + 30), 90, 180, 20),
Alignment.TopLeft, "", menuTabs[(int)Tab.NewGame]);
seedBox.Text = ToolBox.RandomSeed(8);
button = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", Alignment.BottomRight, "", menuTabs[(int)Tab.NewGame]);
button.OnClicked = (GUIButton btn, object userData) =>
{
Submarine selectedSub = subList.SelectedData as Submarine;
if (selectedSub != null && selectedSub.HasTag(SubmarineTag.Shuttle))
{
var msgBox = new GUIMessageBox("Shuttle selected",
"Most shuttles are not adequately equipped to deal with the dangers of the Europan depths. "+
"Are you sure you want to choose a shuttle as your vessel?",
new string[] {"Yes", "No"});
msgBox.Buttons[0].OnClicked = StartGame;
msgBox.Buttons[0].OnClicked += msgBox.Close;
msgBox.Buttons[1].OnClicked = msgBox.Close;
return false;
}
StartGame(btn, userData);
return true;
};
//----------------------------------------------------------------------
menuTabs[(int)Tab.LoadGame] = new GUIFrame(panelRect, "");
//menuTabs[(int)Tabs.LoadGame].Padding = GUI.style.smallPadding;
menuTabs[(int)Tab.HostServer] = new GUIFrame(panelRect, "");
//menuTabs[(int)Tabs.JoinServer].Padding = GUI.style.smallPadding;
//new GUITextBlock(new Rectangle(0, -25, 0, 30), "Host Server", "", Alignment.CenterX, Alignment.CenterX, menuTabs[(int)Tabs.HostServer], false, GUI.LargeFont);
new GUITextBlock(new Rectangle(0, 0, 100, 30), "Server Name:", "", Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tab.HostServer]);
serverNameBox = new GUITextBox(new Rectangle(160, 0, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, "", menuTabs[(int)Tab.HostServer]);
new GUITextBlock(new Rectangle(0, 50, 100, 30), "Server port:", "", Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tab.HostServer]);
portBox = new GUITextBox(new Rectangle(160, 50, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, "", menuTabs[(int)Tab.HostServer]);
portBox.Text = NetConfig.DefaultPort.ToString();
portBox.ToolTip = "Server port";
new GUITextBlock(new Rectangle(0, 100, 100, 30), "Max players:", "", Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tab.HostServer]);
maxPlayersBox = new GUITextBox(new Rectangle(195, 100, 30, 30), null, null, Alignment.TopLeft, Alignment.Center, "", menuTabs[(int)Tab.HostServer]);
maxPlayersBox.Text = "8";
maxPlayersBox.Enabled = false;
var minusPlayersBox = new GUIButton(new Rectangle(160, 100, 30, 30), "-", "", menuTabs[(int)Tab.HostServer]);
minusPlayersBox.UserData = -1;
minusPlayersBox.OnClicked = ChangeMaxPlayers;
var plusPlayersBox = new GUIButton(new Rectangle(230, 100, 30, 30), "+", "", menuTabs[(int)Tab.HostServer]);
plusPlayersBox.UserData = 1;
plusPlayersBox.OnClicked = ChangeMaxPlayers;
new GUITextBlock(new Rectangle(0, 150, 100, 30), "Password (optional):", "", Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tab.HostServer]);
passwordBox = new GUITextBox(new Rectangle(160, 150, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, "", menuTabs[(int)Tab.HostServer]);
isPublicBox = new GUITickBox(new Rectangle(10, 200, 20, 20), "Public server", Alignment.TopLeft, menuTabs[(int)Tab.HostServer]);
isPublicBox.ToolTip = "Public servers are shown in the list of available servers in the \"Join Server\" -tab";
useUpnpBox = new GUITickBox(new Rectangle(10, 250, 20, 20), "Attempt UPnP port forwarding", Alignment.TopLeft, menuTabs[(int)Tab.HostServer]);
useUpnpBox.ToolTip = "UPnP can be used for forwarding ports on your router to allow players join the server."
+ " However, UPnP isn't supported by all routers, so you may need to setup port forwards manually"
+" if players are unable to join the server (see the readme for instructions).";
GUIButton hostButton = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", Alignment.BottomRight, "", menuTabs[(int)Tab.HostServer]);
hostButton.OnClicked = HostServerClicked;
this.game = game;
}
public override void Select()
{
base.Select();
if (GameMain.NetworkMember != null)
{
GameMain.NetworkMember.Disconnect();
GameMain.NetworkMember = null;
}
Submarine.Unload();
UpdateSubList();
SelectTab(null, 0);
}
private void UpdateSubList()
{
var subsToShow = Submarine.SavedSubmarines.Where(s => !s.HasTag(SubmarineTag.HideInMenus));
subList.ClearChildren();
foreach (Submarine sub in subsToShow)
{
var textBlock = new GUITextBlock(
new Rectangle(0, 0, 0, 25),
ToolBox.LimitString(sub.Name, GUI.Font, subList.Rect.Width - 65), "ListBoxElement",
Alignment.Left, Alignment.Left, subList)
{
Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f),
ToolTip = sub.Description,
UserData = sub
};
if (sub.HasTag(SubmarineTag.Shuttle))
{
textBlock.TextColor = textBlock.TextColor * 0.85f;
var shuttleText = new GUITextBlock(new Rectangle(0, 0, 0, 25), "Shuttle", "", Alignment.Left, Alignment.CenterY | Alignment.Right, textBlock, false, GUI.SmallFont);
shuttleText.TextColor = textBlock.TextColor * 0.8f;
shuttleText.ToolTip = textBlock.ToolTip;
}
}
if (Submarine.SavedSubmarines.Count > 0) subList.Select(Submarine.SavedSubmarines[0]);
}
public bool SelectTab(GUIButton button, object obj)
{
try
{
SelectTab((Tab)obj);
}
catch
{
selectedTab = 0;
}
if (button != null) button.Selected = true;
foreach (GUIComponent child in buttonsTab.children)
{
GUIButton otherButton = child as GUIButton;
if (otherButton == null || otherButton == button) continue;
otherButton.Selected = false;
}
if (Selected != this) Select();
return true;
}
public void SelectTab(Tab tab)
{
if (GameMain.Config.UnsavedSettings)
{
var applyBox = new GUIMessageBox("Apply changes?", "Do you want to apply the settings or discard the changes?",
new string[] {"Apply", "Discard"});
applyBox.Buttons[0].OnClicked += applyBox.Close;
applyBox.Buttons[0].OnClicked += ApplySettings;
applyBox.Buttons[0].UserData = tab;
applyBox.Buttons[1].OnClicked += applyBox.Close;
applyBox.Buttons[1].OnClicked += DiscardSettings;
applyBox.Buttons[1].UserData = tab;
return;
}
selectedTab = tab;
switch (selectedTab)
{
case Tab.NewGame:
saveNameBox.Text = SaveUtil.CreateSavePath();
break;
case Tab.LoadGame:
UpdateLoadScreen();
break;
case Tab.Settings:
GameMain.Config.ResetSettingsFrame();
menuTabs[(int)Tab.Settings] = GameMain.Config.SettingsFrame;
break;
}
}
private bool ApplySettings(GUIButton button, object userData)
{
GameMain.Config.Save("config.xml");
if (userData is Tab) SelectTab((Tab)userData);
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;
}
private bool DiscardSettings(GUIButton button, object userData)
{
GameMain.Config.Load("config.xml");
if (userData is Tab) SelectTab((Tab)userData);
return true;
}
private bool TutorialButtonClicked(GUIButton button, object obj)
{
//!!!!!!!!!!!!!!!!!! placeholder
TutorialMode.StartTutorial(Tutorials.TutorialType.TutorialTypes[0]);
return true;
}
private bool JoinServerClicked(GUIButton button, object obj)
{
GameMain.ServerListScreen.Select();
return true;
}
private bool ChangeMaxPlayers(GUIButton button, object obj)
{
int currMaxPlayers = 8;
int.TryParse(maxPlayersBox.Text, out currMaxPlayers);
currMaxPlayers = (int)MathHelper.Clamp(currMaxPlayers + (int)button.UserData, 1, NetConfig.MaxPlayers);
maxPlayersBox.Text = currMaxPlayers.ToString();
return true;
}
private bool HostServerClicked(GUIButton button, object obj)
{
string name = serverNameBox.Text;
if (string.IsNullOrEmpty(name))
{
serverNameBox.Flash();
return false;
}
int port;
if (!int.TryParse(portBox.Text, out port) || port < 0 || port > 65535)
{
portBox.Text = NetConfig.DefaultPort.ToString();
portBox.Flash();
return false;
}
GameMain.NetLobbyScreen = new NetLobbyScreen();
try
{
GameMain.NetworkMember = new GameServer(name, port, isPublicBox.Selected, passwordBox.Text, useUpnpBox.Selected, int.Parse(maxPlayersBox.Text));
}
catch (Exception e)
{
DebugConsole.ThrowError("Failed to start server", e);
}
GameMain.NetLobbyScreen.IsServer = true;
//Game1.NetLobbyScreen.Select();
return true;
}
private bool QuitClicked(GUIButton button, object obj)
{
game.Exit();
return true;
}
private void UpdateLoadScreen()
{
menuTabs[(int)Tab.LoadGame].ClearChildren();
string[] saveFiles = SaveUtil.GetSaveFiles();
saveList = new GUIListBox(new Rectangle(0, 0, 200, menuTabs[(int)Tab.LoadGame].Rect.Height - 80), Color.White, "", menuTabs[(int)Tab.LoadGame]);
saveList.OnSelected = SelectSaveFile;
foreach (string saveFile in saveFiles)
{
GUITextBlock textBlock = new GUITextBlock(
new Rectangle(0, 0, 0, 25),
saveFile,
"ListBoxElement",
Alignment.Left,
Alignment.Left,
saveList);
textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f);
textBlock.UserData = saveFile;
}
var button = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", Alignment.Right | Alignment.Bottom, "", menuTabs[(int)Tab.LoadGame]);
button.OnClicked = LoadGame;
}
private bool SelectSaveFile(GUIComponent component, object obj)
{
string fileName = (string)obj;
XDocument doc = SaveUtil.LoadGameSessionDoc(fileName);
if (doc==null)
{
DebugConsole.ThrowError("Error loading save file \""+fileName+"\". The file may be corrupted.");
return false;
}
RemoveSaveFrame();
string subName = ToolBox.GetAttributeString(doc.Root, "submarine", "");
string saveTime = ToolBox.GetAttributeString(doc.Root, "savetime", "unknown");
string mapseed = ToolBox.GetAttributeString(doc.Root, "mapseed", "unknown");
GUIFrame saveFileFrame = new GUIFrame(new Rectangle((int)(saveList.Rect.Width + 20), 0, 200, 230), Color.Black*0.4f, "", menuTabs[(int)Tab.LoadGame]);
saveFileFrame.UserData = "savefileframe";
saveFileFrame.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
new GUITextBlock(new Rectangle(0,0,0,20), fileName, "", Alignment.TopLeft, Alignment.TopLeft, saveFileFrame, false, GUI.LargeFont);
new GUITextBlock(new Rectangle(0, 35, 0, 20), "Submarine: ", "", saveFileFrame).Font = GUI.SmallFont;
new GUITextBlock(new Rectangle(15, 52, 0, 20), subName, "", saveFileFrame).Font = GUI.SmallFont;
new GUITextBlock(new Rectangle(0, 70, 0, 20), "Last saved: ", "", saveFileFrame).Font = GUI.SmallFont;
new GUITextBlock(new Rectangle(15, 85, 0, 20), saveTime, "", saveFileFrame).Font = GUI.SmallFont;
new GUITextBlock(new Rectangle(0, 105, 0, 20), "Map seed: ", "", saveFileFrame).Font = GUI.SmallFont;
new GUITextBlock(new Rectangle(15, 120, 0, 20), mapseed, "", saveFileFrame).Font = GUI.SmallFont;
var deleteSaveButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Delete", Alignment.BottomCenter, "", saveFileFrame);
deleteSaveButton.UserData = fileName;
deleteSaveButton.OnClicked = DeleteSave;
return true;
}
private bool DeleteSave(GUIButton button, object obj)
{
string saveFile = obj as string;
if (obj == null) return false;
SaveUtil.DeleteSave(saveFile);
UpdateLoadScreen();
return true;
}
private void RemoveSaveFrame()
{
GUIComponent prevFrame = null;
foreach (GUIComponent child in menuTabs[(int)Tab.LoadGame].children)
{
if (child.UserData as string != "savefileframe") continue;
prevFrame = child;
break;
}
menuTabs[(int)Tab.LoadGame].RemoveChild(prevFrame);
}
public override void AddToGUIUpdateList()
{
buttonsTab.AddToGUIUpdateList();
if (selectedTab > 0) menuTabs[(int)selectedTab].AddToGUIUpdateList();
}
public override void Update(double deltaTime)
{
buttonsTab.Update((float)deltaTime);
if (selectedTab>0) menuTabs[(int)selectedTab].Update((float)deltaTime);
GameMain.TitleScreen.TitlePosition =
Vector2.Lerp(GameMain.TitleScreen.TitlePosition, new Vector2(
GameMain.TitleScreen.TitleSize.X / 2.0f * GameMain.TitleScreen.Scale + 30.0f,
GameMain.TitleScreen.TitleSize.Y / 2.0f * GameMain.TitleScreen.Scale + 30.0f),
0.1f);
}
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
{
graphics.Clear(Color.CornflowerBlue);
GameMain.TitleScreen.DrawLoadingText = false;
GameMain.TitleScreen.Draw(spriteBatch, graphics, (float)deltaTime);
//Game1.GameScreen.DrawMap(graphics, spriteBatch);
spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, GameMain.ScissorTestEnable);
buttonsTab.Draw(spriteBatch);
if (selectedTab>0) menuTabs[(int)selectedTab].Draw(spriteBatch);
GUI.Draw((float)deltaTime, spriteBatch, null);
GUI.Font.DrawString(spriteBatch, "Barotrauma v"+GameMain.Version, new Vector2(10, GameMain.GraphicsHeight-20), Color.White);
spriteBatch.End();
}
private bool StartGame(GUIButton button, object userData)
{
if (string.IsNullOrEmpty(saveNameBox.Text)) return false;
string[] existingSaveFiles = SaveUtil.GetSaveFiles();
if (Array.Find(existingSaveFiles, s => s == saveNameBox.Text)!=null)
{
new GUIMessageBox("Save name already in use", "Please choose another name for the save file");
return false;
}
Submarine selectedSub = subList.SelectedData as Submarine;
if (selectedSub == null)
{
new GUIMessageBox("Submarine not selected", "Please select a submarine");
return false;
}
if (!Directory.Exists(SaveUtil.TempPath))
{
Directory.CreateDirectory(SaveUtil.TempPath);
}
File.Copy(selectedSub.FilePath, Path.Combine(SaveUtil.TempPath, selectedSub.Name+".sub"), true);
selectedSub = new Submarine(Path.Combine(SaveUtil.TempPath, selectedSub.Name + ".sub"), "");
GameMain.GameSession = new GameSession(selectedSub, saveNameBox.Text, GameModePreset.list.Find(gm => gm.Name == "Single Player"));
(GameMain.GameSession.gameMode as SinglePlayerMode).GenerateMap(seedBox.Text);
GameMain.LobbyScreen.Select();
//new GUIMessageBox("Welcome to Barotrauma!", "Please note that the single player mode is very unfinished at the moment; "+
//"for example, the NPCs don't have an AI yet and there are only a couple of different quests to complete. The multiplayer "+
//"mode should be much more enjoyable to play at the moment, so my recommendation is to try out and get a hang of the game mechanics "+
//"in the single player mode and then move on to multiplayer. Have fun!\n - Regalis, the main dev of Subsurface", 400, 350);
return true;
}
private bool PreviousTab(GUIButton button, object obj)
{
//selectedTab = (int)Tabs.Main;
return true;
}
private bool LoadGame(GUIButton button, object obj)
{
string saveFile = saveList.SelectedData as string;
if (string.IsNullOrWhiteSpace(saveFile)) return false;
try
{
SaveUtil.LoadGame(saveFile);
}
catch (Exception e)
{
DebugConsole.ThrowError("Loading save \""+saveFile+"\" failed", e);
return false;
}
GameMain.LobbyScreen.Select();
return true;
}
}
}
File diff suppressed because it is too large Load Diff
+99
View File
@@ -0,0 +1,99 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
namespace Barotrauma
{
class Screen
{
private static Screen selected;
public static Screen Selected
{
get { return selected; }
}
public virtual void Deselect()
{
}
public virtual void Select()
{
if (selected != null && selected != this)
{
selected.Deselect();
GUIComponent.KeyboardDispatcher.Subscriber = null;
}
selected = this;
}
public virtual Camera Cam
{
get { return null; }
}
public virtual void AddToGUIUpdateList()
{
}
public virtual void Update(double deltaTime)
{
}
public virtual void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
{
}
public void ColorFade(Color from, Color to, float duration)
{
if (duration <= 0.0f) return;
CoroutineManager.StartCoroutine(UpdateColorFade(from, to, duration));
}
private IEnumerable<object> UpdateColorFade(Color from, Color to, float duration)
{
while (Selected != this)
{
yield return CoroutineStatus.Running;
}
float timer = 0.0f;
while (timer < duration)
{
GUI.ScreenOverlayColor = Color.Lerp(from, to, Math.Min(timer / duration, 1.0f));
timer += CoroutineManager.UnscaledDeltaTime;
yield return CoroutineStatus.Running;
}
GUI.ScreenOverlayColor = to;
yield return CoroutineStatus.Success;
}
protected void DrawSubmarineIndicator(SpriteBatch spriteBatch, Submarine submarine, Color color)
{
Vector2 subDiff = submarine.WorldPosition - Cam.WorldViewCenter;
if (Math.Abs(subDiff.X) > Cam.WorldView.Width || Math.Abs(subDiff.Y) > Cam.WorldView.Height)
{
Vector2 normalizedSubDiff = Vector2.Normalize(subDiff);
Vector2 iconPos =
Cam.WorldToScreen(Cam.WorldViewCenter) +
new Vector2(normalizedSubDiff.X * GameMain.GraphicsWidth * 0.4f, -normalizedSubDiff.Y * GameMain.GraphicsHeight * 0.4f);
GUI.SubmarineIcon.Draw(spriteBatch, iconPos, color);
Vector2 arrowOffset = normalizedSubDiff * GUI.SubmarineIcon.size.X * 0.7f;
arrowOffset.Y = -arrowOffset.Y;
GUI.Arrow.Draw(spriteBatch, iconPos + arrowOffset, color, MathUtils.VectorToAngle(arrowOffset) + MathHelper.PiOver2);
}
}
}
}
@@ -0,0 +1,343 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Networking;
using System.Collections.Generic;
using RestSharp;
namespace Barotrauma
{
class ServerListScreen : Screen
{
//how often the client is allowed to refresh servers
private TimeSpan AllowedRefreshInterval = new TimeSpan(0,0,3);
private GUIFrame menu;
private GUIListBox serverList;
private GUIButton joinButton;
private GUITextBox clientNameBox, ipBox;
//private RestRequestAsyncHandle restRequestHandle;
private bool masterServerResponded;
private IRestResponse masterServerResponse;
private int[] columnX;
//a timer for
private DateTime refreshDisableTimer;
private bool waitingForRefresh;
public ServerListScreen()
{
int width = Math.Min(GameMain.GraphicsWidth - 160, 1000);
int height = Math.Min(GameMain.GraphicsHeight - 160, 700);
Rectangle panelRect = new Rectangle(0, 0, width, height);
menu = new GUIFrame(panelRect, null, Alignment.Center, "");
menu.Padding = new Vector4(40.0f, 40.0f, 40.0f, 20.0f);
new GUITextBlock(new Rectangle(0, -25, 0, 30), "Join Server", "", Alignment.CenterX, Alignment.CenterX, menu, false, GUI.LargeFont);
new GUITextBlock(new Rectangle(0, 30, 0, 30), "Your Name:", "", menu);
clientNameBox = new GUITextBox(new Rectangle(0, 60, 200, 30), "", menu);
new GUITextBlock(new Rectangle(0, 100, 0, 30), "Server IP:", "", menu);
ipBox = new GUITextBox(new Rectangle(0, 130, 200, 30), "", menu);
int middleX = (int)(width * 0.4f);
serverList = new GUIListBox(new Rectangle(middleX,60,0,height-160), "", menu);
serverList.OnSelected = SelectServer;
float[] columnRelativeX = new float[] { 0.15f, 0.5f, 0.15f, 0.2f };
columnX = new int[columnRelativeX.Length];
for (int n = 0; n < columnX.Length; n++)
{
columnX[n] = (int)(columnRelativeX[n] * serverList.Rect.Width);
if (n > 0) columnX[n] += columnX[n - 1];
}
ScalableFont font = GUI.SmallFont; // serverList.Rect.Width < 400 ? GUI.SmallFont : GUI.Font;
new GUITextBlock(new Rectangle(middleX, 30, 0, 30), "Password", "", menu).Font = font;
new GUITextBlock(new Rectangle(middleX + columnX[0], 30, 0, 30), "Name", "", menu).Font = font;
new GUITextBlock(new Rectangle(middleX + columnX[1], 30, 0, 30), "Players", "", menu).Font = font;
new GUITextBlock(new Rectangle(middleX + columnX[2], 30, 0, 30), "Round started", "", menu).Font = font;
joinButton = new GUIButton(new Rectangle(-170, 0, 150, 30), "Refresh", Alignment.BottomRight, "", menu);
joinButton.OnClicked = RefreshServers;
joinButton = new GUIButton(new Rectangle(0,0,150,30), "Join", Alignment.BottomRight, "", menu);
joinButton.OnClicked = JoinServer;
GUIButton button = new GUIButton(new Rectangle(-20, -20, 100, 30), "Back", Alignment.TopLeft, "", menu);
button.OnClicked = GameMain.MainMenuScreen.SelectTab;
button.SelectedColor = button.Color;
refreshDisableTimer = DateTime.Now;
}
public override void Select()
{
base.Select();
RefreshServers(null, null);
}
private bool SelectServer(GUIComponent component, object obj)
{
string ip = obj as string;
if (string.IsNullOrWhiteSpace(ip)) return false;
ipBox.Text = ip;
return true;
}
private bool RefreshServers(GUIButton button, object obj)
{
if (waitingForRefresh) return false;
serverList.ClearChildren();
new GUITextBlock(new Rectangle(0, 0, 0, 20), "Refreshing server list...", "", serverList);
CoroutineManager.StartCoroutine(WaitForRefresh());
return true;
}
private IEnumerable<object> WaitForRefresh()
{
waitingForRefresh = true;
if (refreshDisableTimer > DateTime.Now)
{
yield return new WaitForSeconds((float)(refreshDisableTimer - DateTime.Now).TotalSeconds);
}
//CoroutineManager.StartCoroutine(UpdateServerList());
CoroutineManager.StartCoroutine(SendMasterServerRequest());
waitingForRefresh = false;
refreshDisableTimer = DateTime.Now + AllowedRefreshInterval;
yield return CoroutineStatus.Success;
}
private void UpdateServerList(string masterServerData)
{
serverList.ClearChildren();
//string masterServerData = GetMasterServerData();
if (string.IsNullOrWhiteSpace(masterServerData))
{
new GUITextBlock(new Rectangle(0, 0, 0, 20), "Couldn't find any servers", "", serverList);
return;
}
if (masterServerData.Substring(0, 5).ToLowerInvariant() == "error")
{
DebugConsole.ThrowError("Error while connecting to master server ("+masterServerData+")!");
return;
}
string[] lines = masterServerData.Split('\n');
for (int i = 0; i<lines.Length; i++)
{
string[] arguments = lines[i].Split('|');
if (arguments.Length < 3) continue;
string IP = arguments[0];
string port = arguments[1];
string serverName = arguments[2];
string gameStarted = (arguments.Length > 3) ? arguments[3] : "";
string currPlayersStr = (arguments.Length > 4) ? arguments[4] : "";
string maxPlayersStr = (arguments.Length > 5) ? arguments[5] : "";
string hasPassWordStr = (arguments.Length > 6) ? arguments[6] : "";
var serverFrame = new GUIFrame(new Rectangle(0, 0, 0, 30), (i % 2 == 0) ? Color.Transparent : Color.White * 0.2f, "ListBoxElement", serverList);
serverFrame.UserData = IP + ":" + port;
var passwordBox = new GUITickBox(new Rectangle(columnX[0] / 2, 0, 20, 20), "", Alignment.CenterLeft, serverFrame);
passwordBox.Selected = hasPassWordStr == "1";
passwordBox.Enabled = false;
passwordBox.UserData = "password";
new GUITextBlock(new Rectangle(columnX[0], 0, 0, 0), serverName, "", Alignment.TopLeft, Alignment.CenterLeft, serverFrame);
int playerCount = 0, maxPlayers = 1;
int.TryParse(currPlayersStr, out playerCount);
int.TryParse(maxPlayersStr, out maxPlayers);
new GUITextBlock(new Rectangle(columnX[1], 0, 0, 0), playerCount + "/" + maxPlayers, "", Alignment.TopLeft, Alignment.CenterLeft, serverFrame);
var gameStartedBox = new GUITickBox(new Rectangle(columnX[2] + (columnX[3] - columnX[2])/ 2, 0, 20, 20), "", Alignment.CenterRight, serverFrame);
gameStartedBox.Selected = gameStarted == "1";
gameStartedBox.Enabled = false;
}
}
private IEnumerable<object> SendMasterServerRequest()
{
RestClient client = null;
try
{
client = new RestClient(NetConfig.MasterServerUrl);
}
catch (Exception e)
{
DebugConsole.ThrowError("Error while connecting to master server", e);
}
if (client == null) yield return CoroutineStatus.Success;
var request = new RestRequest("masterserver2.php", Method.GET);
request.AddParameter("gamename", "barotrauma");
request.AddParameter("action", "listservers");
// execute the request
masterServerResponded = false;
var restRequestHandle = client.ExecuteAsync(request, response => MasterServerCallBack(response));
DateTime timeOut = DateTime.Now + new TimeSpan(0, 0, 8);
while (!masterServerResponded)
{
if (DateTime.Now > timeOut)
{
serverList.ClearChildren();
restRequestHandle.Abort();
new GUIMessageBox("Connection error", "Couldn't connect to master server (request timed out).");
yield return CoroutineStatus.Success;
}
yield return CoroutineStatus.Running;
}
if (masterServerResponse.ErrorException != null)
{
serverList.ClearChildren();
new GUIMessageBox("Connection error", "Error while connecting to master server {" + masterServerResponse.ErrorException + "}");
}
else if (masterServerResponse.StatusCode != System.Net.HttpStatusCode.OK)
{
serverList.ClearChildren();
switch (masterServerResponse.StatusCode)
{
case System.Net.HttpStatusCode.NotFound:
new GUIMessageBox("Connection error",
"Error while connecting to master server (404 - \"" + NetConfig.MasterServerUrl + "\" not found)");
break;
case System.Net.HttpStatusCode.ServiceUnavailable:
new GUIMessageBox("Connection error",
"Error while connecting to master server (505 - Service Unavailable) " +
"The master server may be down for maintenance or temporarily overloaded. Please try again after in a few moments.");
break;
default:
new GUIMessageBox("Connection error",
"Error while connecting to master server (" + masterServerResponse.StatusCode + ": " + masterServerResponse.StatusDescription + ")");
break;
}
}
else
{
UpdateServerList(masterServerResponse.Content);
}
yield return CoroutineStatus.Success;
}
private void MasterServerCallBack(IRestResponse response)
{
masterServerResponse = response;
masterServerResponded = true;
}
private bool JoinServer(GUIButton button, object obj)
{
if (string.IsNullOrWhiteSpace(clientNameBox.Text))
{
clientNameBox.Flash();
return false;
}
string ip = ipBox.Text;
if (string.IsNullOrWhiteSpace(ip))
{
ipBox.Flash();
return false;
}
CoroutineManager.StartCoroutine(ConnectToServer(ip));
return true;
}
public void JoinServer(string ip, bool hasPassword, string msg = "Password required")
{
CoroutineManager.StartCoroutine(ConnectToServer(ip));
}
private IEnumerable<object> ConnectToServer(string ip)
{
try
{
GameMain.NetworkMember = new GameClient(clientNameBox.Text);
GameMain.Client.ConnectToServer(ip);
}
catch (Exception e)
{
DebugConsole.ThrowError("Failed to start the client", e);
}
yield return CoroutineStatus.Success;
}
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
{
graphics.Clear(Color.CornflowerBlue);
GameMain.TitleScreen.DrawLoadingText = false;
GameMain.TitleScreen.Draw(spriteBatch, graphics, (float)deltaTime);
spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, GameMain.ScissorTestEnable);
menu.Draw(spriteBatch);
GUI.Draw((float)deltaTime, spriteBatch, null);
spriteBatch.End();
}
public override void AddToGUIUpdateList()
{
menu.AddToGUIUpdateList();
}
public override void Update(double deltaTime)
{
//GameMain.TitleScreen.Update();
menu.Update((float)deltaTime);
//GUI.Update((float)deltaTime);
}
}
}
+337
View File
@@ -0,0 +1,337 @@
using System;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Networking;
using FarseerPhysics;
using FarseerPhysics.Factories;
using FarseerPhysics.Dynamics;
using System.IO;
using System.Collections.Generic;
using RestSharp;
namespace Barotrauma
{
class ServerListScreen : Screen
{
//how often the client is allowed to refresh servers
private TimeSpan AllowedRefreshInterval = new TimeSpan(0,0,3);
private GUIFrame menu;
private GUIListBox serverList;
private GUIButton joinButton;
private GUITextBox clientNameBox, ipBox;
//private RestRequestAsyncHandle restRequestHandle;
private bool masterServerResponded;
private int[] columnX;
//a timer for
private DateTime refreshDisableTimer;
private bool waitingForRefresh;
public ServerListScreen()
{
int width = Math.Min(GameMain.GraphicsWidth - 160, 1000);
int height = Math.Min(GameMain.GraphicsHeight - 160, 700);
Rectangle panelRect = new Rectangle(0, 0, width, height);
menu = new GUIFrame(panelRect, null, Alignment.Center, GUI.Style);
menu.Padding = new Vector4(40.0f, 40.0f, 40.0f, 20.0f);
new GUITextBlock(new Rectangle(0, -25, 0, 30), "Join Server", GUI.Style, Alignment.CenterX, Alignment.CenterX, menu, false, GUI.LargeFont);
new GUITextBlock(new Rectangle(0, 30, 0, 30), "Your Name:", GUI.Style, menu);
clientNameBox = new GUITextBox(new Rectangle(0, 60, 200, 30), GUI.Style, menu);
new GUITextBlock(new Rectangle(0, 100, 0, 30), "Server IP:", GUI.Style, menu);
ipBox = new GUITextBox(new Rectangle(0, 130, 200, 30), GUI.Style, menu);
int middleX = (int)(width * 0.4f);
serverList = new GUIListBox(new Rectangle(middleX,60,0,height-160), GUI.Style, menu);
serverList.OnSelected = SelectServer;
float[] columnRelativeX = new float[] { 0.15f, 0.55f, 0.15f, 0.15f };
columnX = new int[columnRelativeX.Length];
for (int n = 0; n < columnX.Length; n++)
{
columnX[n] = (int)(columnRelativeX[n] * serverList.Rect.Width);
if (n > 0) columnX[n] += columnX[n - 1];
}
SpriteFont font = serverList.Rect.Width < 400 ? GUI.SmallFont : GUI.Font;
new GUITextBlock(new Rectangle(middleX, 30, 0, 30), "Password", GUI.Style, menu).Font = font;
new GUITextBlock(new Rectangle(middleX + columnX[0], 30, 0, 30), "Name", GUI.Style, menu).Font = font;
new GUITextBlock(new Rectangle(middleX + columnX[1], 30, 0, 30), "Players", GUI.Style, menu).Font = font;
new GUITextBlock(new Rectangle(middleX + columnX[2], 30, 0, 30), "Round started", GUI.Style, menu).Font = font;
joinButton = new GUIButton(new Rectangle(-170, 0, 150, 30), "Refresh", Alignment.BottomRight, GUI.Style, menu);
joinButton.OnClicked = RefreshServers;
joinButton = new GUIButton(new Rectangle(0,0,150,30), "Join", Alignment.BottomRight, GUI.Style, menu);
joinButton.OnClicked = JoinServer;
GUIButton button = new GUIButton(new Rectangle(-20, -20, 100, 30), "Back", Alignment.TopLeft, GUI.Style, menu);
button.OnClicked = GameMain.MainMenuScreen.SelectTab;
button.CanBeSelected = false;
button.SelectedColor = button.Color;
refreshDisableTimer = DateTime.Now;
}
public override void Select()
{
base.Select();
RefreshServers(null, null);
}
private bool SelectServer(GUIComponent component, object obj)
{
string ip = obj as string;
if (string.IsNullOrWhiteSpace(ip)) return false;
ipBox.Text = ip;
return true;
}
private bool RefreshServers(GUIButton button, object obj)
{
if (waitingForRefresh) return false;
serverList.ClearChildren();
new GUITextBlock(new Rectangle(0, 0, 0, 20), "Refreshing server list...", GUI.Style, serverList);
CoroutineManager.StartCoroutine(WaitForRefresh());
return true;
}
private IEnumerable<object> WaitForRefresh()
{
waitingForRefresh = true;
if (refreshDisableTimer > DateTime.Now)
{
yield return new WaitForSeconds((float)(refreshDisableTimer - DateTime.Now).TotalSeconds);
}
//CoroutineManager.StartCoroutine(UpdateServerList());
CoroutineManager.StartCoroutine(SendMasterServerRequest());
waitingForRefresh = false;
refreshDisableTimer = DateTime.Now + AllowedRefreshInterval;
yield return CoroutineStatus.Success;
}
private void UpdateServerList(string masterServerData)
{
serverList.ClearChildren();
//string masterServerData = GetMasterServerData();
if (string.IsNullOrWhiteSpace(masterServerData))
{
var nameText = new GUITextBlock(new Rectangle(0, 0, 0, 20), "Couldn't find any servers", GUI.Style, serverList);
return;
}
if (masterServerData.Substring(0,5).ToLower()=="error")
{
DebugConsole.ThrowError("Error while connecting to master server ("+masterServerData+")!");
return;
}
string[] lines = masterServerData.Split('\n');
for (int i = 0; i<lines.Length; i++)
{
string[] arguments = lines[i].Split('|');
if (arguments.Length < 3) continue;
string IP = arguments[0];
string port = arguments[1];
string serverName = arguments[2];
string gameStarted = (arguments.Length > 3) ? arguments[3] : "";
string playerCountStr = (arguments.Length > 4) ? arguments[4] : "";
string hasPassWordStr = (arguments.Length > 5) ? arguments[5] : "";
var serverFrame = new GUIFrame(new Rectangle(0,0,0,20), (i%2 == 0) ? Color.Transparent : Color.White*0.2f, null, serverList);
serverFrame.UserData = IP+":"+port;
serverFrame.HoverColor = Color.Gold * 0.2f;
serverFrame.SelectedColor = Color.Gold * 0.5f;
var passwordBox = new GUITickBox(new Rectangle(columnX[0]/2, 0, 20, 20), "", Alignment.TopLeft, serverFrame);
passwordBox.Selected = hasPassWordStr == "1";
passwordBox.Enabled = false;
passwordBox.UserData = "password";
var nameText = new GUITextBlock(new Rectangle(columnX[0], 0, 0, 0), serverName, GUI.Style, serverFrame);
int playerCount, maxPlayers;
playerCount = GameClient.ByteToPlayerCount((byte)int.Parse(playerCountStr), out maxPlayers);
var playerCountText = new GUITextBlock(new Rectangle(columnX[1], 0, 0, 0), playerCount + "/" + maxPlayers, GUI.Style, serverFrame);
var gameStartedBox = new GUITickBox(new Rectangle(columnX[2] + (columnX[3] - columnX[2])/ 2, 0, 20, 20), "", Alignment.TopLeft, serverFrame);
gameStartedBox.Selected = gameStarted == "1";
gameStartedBox.Enabled = false;
}
}
private IEnumerable<object> SendMasterServerRequest()
{
RestClient client = null;
try
{
client = new RestClient(NetConfig.MasterServerUrl);
}
catch (Exception e)
{
DebugConsole.ThrowError("Error while connecting to master server", e);
}
if (client == null) yield return CoroutineStatus.Success;
var request = new RestRequest("masterserver.php", Method.GET);
request.AddParameter("gamename", "barotrauma"); // adds to POST or URL querystring based on Method
request.AddParameter("action", "listservers"); // adds to POST or URL querystring based on Method
// easily add HTTP Headers
//request.AddHeader("header", "value");
//// add files to upload (works with compatible verbs)
//request.AddFile(path);
// execute the request
masterServerResponded = false;
var restRequestHandle = client.ExecuteAsync(request, response => MasterServerCallBack(response));
DateTime timeOut = DateTime.Now + new TimeSpan(0, 0, 8);
while (!masterServerResponded)
{
if (DateTime.Now > timeOut)
{
serverList.ClearChildren();
restRequestHandle.Abort();
DebugConsole.ThrowError("Couldn't connect to master server (request timed out)");
}
yield return CoroutineStatus.Running;
}
yield return CoroutineStatus.Success;
}
private void MasterServerCallBack(IRestResponse response)
{
masterServerResponded = true;
if (response.ErrorException!=null)
{
serverList.ClearChildren();
DebugConsole.ThrowError("Error while connecting to master server", response.ErrorException);
return;
}
if (response.StatusCode!= System.Net.HttpStatusCode.OK)
{
serverList.ClearChildren();
DebugConsole.ThrowError("Error while connecting to master server (" +response.StatusCode+": "+response.StatusDescription+")");
return;
}
UpdateServerList(response.Content);
}
private bool JoinServer(GUIButton button, object obj)
{
if (string.IsNullOrWhiteSpace(clientNameBox.Text))
{
clientNameBox.Flash();
return false;
}
string ip = ipBox.Text;
if (string.IsNullOrWhiteSpace(ip))
{
ipBox.Flash();
return false;
}
CoroutineManager.StartCoroutine(JoinServer(ip));
return true;
}
private IEnumerable<object> JoinServer(string ip)
{
string selectedPassword = "";
if (serverList.Selected!=null && (serverList.Selected.GetChild("password") as GUITickBox).Selected)
{
var msgBox = new GUIMessageBox("Password required:", "");
var passwordBox = new GUITextBox(new Rectangle(0,40,150,25), Alignment.TopLeft, GUI.Style, msgBox);
passwordBox.UserData = "password";
var okButton = msgBox.GetChild<GUIButton>();
while (GUIMessageBox.MessageBoxes.Contains(msgBox))
{
okButton.Enabled = !string.IsNullOrWhiteSpace(passwordBox.Text);
yield return CoroutineStatus.Running;
}
selectedPassword = passwordBox.Text;
}
GameMain.NetworkMember = new GameClient(clientNameBox.Text);
GameMain.Client.ConnectToServer(ip, selectedPassword);
yield return CoroutineStatus.Success;
}
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
{
graphics.Clear(Color.CornflowerBlue);
GameMain.GameScreen.DrawMap(graphics, spriteBatch);
spriteBatch.Begin();
menu.Draw(spriteBatch);
//if (previewPlayer!=null) previewPlayer.Draw(spriteBatch);
GUI.Draw((float)deltaTime, spriteBatch, null);
spriteBatch.End();
}
public override void Update(double deltaTime)
{
menu.Update((float)deltaTime);
GUI.Update((float)deltaTime);
}
}
}