Renamed project folders from Subsurface to Barotrauma
This commit is contained in:
@@ -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
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user