Spawnpoints for different jobs, spawning crew members with job-specific items, fixed issues with non-matching entity IDs between client and server, Unity-like coroutine system (connecting to server doesn't freeze the game anymore), map drawing improvements
This commit is contained in:
@@ -268,6 +268,12 @@ namespace Subsurface
|
||||
{
|
||||
}
|
||||
|
||||
public Character(CharacterInfo characterInfo, WayPoint spawnPoint, bool isNetworkPlayer = false)
|
||||
: this(characterInfo.File, spawnPoint.SimPosition, characterInfo, isNetworkPlayer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Character(CharacterInfo characterInfo, Vector2 position, bool isNetworkPlayer = false)
|
||||
: this(characterInfo.File, position, characterInfo, isNetworkPlayer)
|
||||
{
|
||||
@@ -351,7 +357,6 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AnimController.FindHull();
|
||||
|
||||
//if (info.ID >= 0)
|
||||
@@ -362,6 +367,24 @@ namespace Subsurface
|
||||
CharacterList.Add(this);
|
||||
}
|
||||
|
||||
public void GiveJobItems()
|
||||
{
|
||||
if (Info == null || Info.Job == null) return;
|
||||
|
||||
foreach (string itemName in Info.Job.SpawnItemNames)
|
||||
{
|
||||
ItemPrefab itemPrefab = ItemPrefab.list.Find(ip => ip.Name == itemName) as ItemPrefab;
|
||||
if (itemPrefab == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Tried to spawn ''" + Name + "'' with the item ''" + itemName + "''. Matching item prefab not found.");
|
||||
continue;
|
||||
}
|
||||
|
||||
Item item = new Item(itemPrefab, Position);
|
||||
inventory.TryPutItem(item, item.AllowedSlots, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void Control(float deltaTime, Camera cam, bool forcePick = false)
|
||||
{
|
||||
if (isDead) return;
|
||||
@@ -612,15 +635,17 @@ namespace Subsurface
|
||||
spriteBatch.DrawString(GUI.font, Info.Name, namePos, Color.White);
|
||||
}
|
||||
|
||||
Vector2 pos = ConvertUnits.ToDisplayUnits(AnimController.limbs[0].SimPosition);
|
||||
pos.Y = -pos.Y;
|
||||
spriteBatch.DrawString(GUI.font, ID.ToString(), pos, Color.White);
|
||||
|
||||
if (this == Character.controlled) return;
|
||||
|
||||
Vector2 healthBarPos = new Vector2(Position.X - 50, -Position.Y - 50.0f);
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)healthBarPos.X-2, (int)healthBarPos.Y-2, 100+4, 15+4), Color.Black, false);
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)healthBarPos.X, (int)healthBarPos.Y, (int)(100.0f*(health/maxHealth)), 15), Color.Red, true);
|
||||
|
||||
Vector2 pos = ConvertUnits.ToDisplayUnits(AnimController.limbs[0].SimPosition);
|
||||
pos.Y = -pos.Y;
|
||||
spriteBatch.DrawString(GUI.font, ID.ToString(), pos, Color.White);
|
||||
|
||||
//GUI.DrawLine(spriteBatch, ConvertUnits.ToDisplayUnits(animController.limbs[0].SimPosition.X, animController.limbs[0].SimPosition.Y),
|
||||
// ConvertUnits.ToDisplayUnits(animController.limbs[0].SimPosition.X, animController.limbs[0].SimPosition.Y) +
|
||||
// ConvertUnits.ToDisplayUnits(animController.targetMovement.X, animController.targetMovement.Y), Color.Green);
|
||||
@@ -1036,7 +1061,9 @@ namespace Subsurface
|
||||
|
||||
if (controlled == this) controlled = null;
|
||||
|
||||
if (Game1.Client!=null && Game1.Client.Character == this) Game1.Client.Character = null;
|
||||
if (Game1.Client!=null && Game1.Client.Character == this) Game1.Client.Character = null;
|
||||
|
||||
if (inventory != null) inventory.Remove();
|
||||
|
||||
if (aiTarget != null)
|
||||
aiTarget.Remove();
|
||||
|
||||
@@ -19,6 +19,8 @@ namespace Subsurface
|
||||
|
||||
public int Salary;
|
||||
|
||||
public bool StartItemsGiven;
|
||||
|
||||
//public string GenderString()
|
||||
//{
|
||||
// return gender.ToString();
|
||||
@@ -96,11 +98,10 @@ namespace Subsurface
|
||||
string genderStr = ToolBox.GetAttributeString(element, "gender", "male").ToLower();
|
||||
Gender = (genderStr == "male") ? Gender.Male : Gender.Female;
|
||||
|
||||
File = ToolBox.GetAttributeString(element, "file", "");
|
||||
|
||||
Salary = ToolBox.GetAttributeInt(element, "salary", 1000);
|
||||
|
||||
HeadSpriteId = ToolBox.GetAttributeInt(element, "headspriteid", 1);
|
||||
File = ToolBox.GetAttributeString(element, "file", "");
|
||||
Salary = ToolBox.GetAttributeInt(element, "salary", 1000);
|
||||
HeadSpriteId = ToolBox.GetAttributeInt(element, "headspriteid", 1);
|
||||
StartItemsGiven = ToolBox.GetAttributeBool(element, "startitemsgiven", false);
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
@@ -120,7 +121,8 @@ namespace Subsurface
|
||||
new XAttribute("file", File),
|
||||
new XAttribute("gender", Gender == Gender.Male ? "male" : "female"),
|
||||
new XAttribute("salary", Salary),
|
||||
new XAttribute("headspriteid", HeadSpriteId));
|
||||
new XAttribute("headspriteid", HeadSpriteId),
|
||||
new XAttribute("startitemsgiven", StartItemsGiven));
|
||||
|
||||
Job.Save(charElement);
|
||||
|
||||
|
||||
@@ -24,6 +24,16 @@ namespace Subsurface
|
||||
get { return prefab.Description; }
|
||||
}
|
||||
|
||||
public JobPrefab Prefab
|
||||
{
|
||||
get { return prefab; }
|
||||
}
|
||||
|
||||
public List<string> SpawnItemNames
|
||||
{
|
||||
get { return prefab.ItemNames; }
|
||||
}
|
||||
|
||||
|
||||
public Job(JobPrefab jobPrefab)
|
||||
{
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace Subsurface
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString())
|
||||
switch (subElement.Name.ToString().ToLower())
|
||||
{
|
||||
case "item":
|
||||
string itemName = ToolBox.GetAttributeString(subElement, "name", "");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Jobs>
|
||||
<Captain description="The Commanding Officer with authority over the entire crew.">
|
||||
<Captain description="The Commanding Officer with authority over the entire crew." minnumber="1" maxnumber="1">
|
||||
<Item name="ID Card"/>
|
||||
</Captain>
|
||||
|
||||
@@ -15,4 +15,10 @@
|
||||
<Item name="Wrench"/>
|
||||
<Item name="Screwdriver"/>
|
||||
</Mechanic>
|
||||
|
||||
<Assistant allowalways="true">
|
||||
<Item name="ID Card"/>
|
||||
<Item name="Wrench"/>
|
||||
<Item name="Screwdriver"/>
|
||||
</Assistant>
|
||||
</Jobs>
|
||||
BIN
Subsurface/Content/Map/iceCrack.png
Normal file
BIN
Subsurface/Content/Map/iceCrack.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
BIN
Subsurface/Content/Map/iceCraters.png
Normal file
BIN
Subsurface/Content/Map/iceCraters.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 112 KiB |
BIN
Subsurface/Content/Map/iceSurface.png
Normal file
BIN
Subsurface/Content/Map/iceSurface.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.6 MiB |
@@ -16,17 +16,18 @@
|
||||
</GUIFrame>
|
||||
|
||||
<GUIButton
|
||||
color="0.6, 0.2, 0.2, 1.0"
|
||||
color="0.88, 0.25, 0.15, 1.0"
|
||||
|
||||
textcolor="1.0, 1.0, 1.0, 1.0"
|
||||
|
||||
hovercolor="0.88, 0.19, 0.16, 1.0"
|
||||
selectedcolor="0.8, 0.8, 0.8, 1.0"/>
|
||||
hovercolor="1.0, 0.57, 0.31, 1.0"
|
||||
selectedcolor="1.0, 0.0, 0.0, 1.0"/>
|
||||
|
||||
<GUITextBlock
|
||||
textcolor="1.0, 1.0, 1.0, 1.0"
|
||||
hovercolor="1.0, 1.0, 1.0, 0.3"
|
||||
selectedcolor="1.0, 0.6, 0.0, 0.3"/>
|
||||
selectedcolor="1.0, 0.6, 0.0, 0.3"
|
||||
padding="10.0, 0.0, 10.0, 0.0"/>
|
||||
|
||||
<GUIListBox
|
||||
color="0.5, 0.5, 0.5, 1.0"
|
||||
@@ -46,11 +47,26 @@
|
||||
</GUIScrollBar>
|
||||
|
||||
<GUITextBox
|
||||
color="0.5, 0.5, 0.5, 1.0"
|
||||
color="0.8, 0.8, 0.8, 1.0"
|
||||
|
||||
textcolor="1.0, 1.0, 1.0, 1.0"
|
||||
textcolor="0.0, 0.0, 0.0, 1.0"
|
||||
outlinecolor="0.5, 0.57, 0.6, 1.0">
|
||||
<Sprite texture="Content\UI\uiBackground.png" size="0.0, 1.0" sourcerect ="0.0, 0.0, 0.0, 90.0"/>
|
||||
</GUITextBox>
|
||||
|
||||
<GUIMessageBox
|
||||
padding="40.0, 40.0, 40.0, 40.0"
|
||||
color="1.0, 1.0, 1.0, 1.0"
|
||||
|
||||
textcolor="0.0, 0.0, 0.0, 1.0"
|
||||
|
||||
hovercolor="0.8, 0.8, 0.8, 1.0"
|
||||
selectedcolor="1.0, 0.82, 0.05, 1.0"
|
||||
|
||||
outlinecolor="0.5, 0.57, 0.6, 1.0">
|
||||
|
||||
<Sprite texture="Content\UI\uiBackground.png" size="0.0, 0.0" sourcerect ="0.0, 90.0, 0.0, 100.0"/>
|
||||
<Sprite texture="Content\UI\uiBackground.png" size="0.0, 1.0" sourcerect ="0.0, 0.0, 0.0, 90.0"/>
|
||||
</GUIMessageBox>
|
||||
|
||||
</style>
|
||||
@@ -5,13 +5,13 @@
|
||||
commonness="10"
|
||||
difficulty="30"
|
||||
minamount="2" maxamount="3"
|
||||
starttimemin="5" starttimemax="10"
|
||||
starttimemin="15" starttimemax="20"
|
||||
musictype="monster"/>
|
||||
|
||||
<MonsterEvent name="Under attack" description=""
|
||||
characterfile="Content/Characters/TigerThresher/tigerthresher.xml"
|
||||
commonness="10"
|
||||
difficulty="50"
|
||||
starttimemin="5" starttimemax="10"
|
||||
starttimemin="15" starttimemax="20"
|
||||
musictype="monster"/>
|
||||
</Randomevents>
|
||||
45
Subsurface/CoroutineManager.cs
Normal file
45
Subsurface/CoroutineManager.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
enum Status
|
||||
{
|
||||
Running, Success, Failure
|
||||
}
|
||||
|
||||
// Keeps track of all running coroutines, and runs them till the end.
|
||||
static class CoroutineManager
|
||||
{
|
||||
static List<IEnumerator<Status>> Coroutines = new List<IEnumerator<Status>>();
|
||||
|
||||
// Starting a coroutine just means adding an enumerator to the list.
|
||||
// You might also want to be able to stop coroutines or delete them,
|
||||
// which might mean putting them into a dictionary
|
||||
public static void StartCoroutine(IEnumerable<Status> func)
|
||||
{
|
||||
Coroutines.Add(func.GetEnumerator());
|
||||
}
|
||||
|
||||
// Updating just means stepping through all the coroutines
|
||||
public static void Update()
|
||||
{
|
||||
for (int i = Coroutines.Count-1; i>=0; i--)
|
||||
{
|
||||
Coroutines[i].MoveNext();
|
||||
|
||||
switch (Coroutines[i].Current)
|
||||
{
|
||||
case Status.Success:
|
||||
Coroutines.RemoveAt(i);
|
||||
break;
|
||||
case Status.Failure:
|
||||
DebugConsole.ThrowError("Coroutine ''" + Coroutines[i]+ "'' has failed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,6 @@ namespace Subsurface
|
||||
{
|
||||
ScriptedEvent scriptedEvent = ScriptedEvent.LoadRandom(level.Seed);
|
||||
AddTask(new ScriptedTask(scriptedEvent));
|
||||
|
||||
}
|
||||
|
||||
public void TaskStarted(Task task)
|
||||
|
||||
@@ -21,17 +21,17 @@ namespace Subsurface
|
||||
this.Buttons[0].OnClicked = Close;
|
||||
}
|
||||
|
||||
public GUIMessageBox(string header, string text, string[] buttons, Alignment textAlignment = (Alignment.Left | Alignment.Top))
|
||||
: base(new Rectangle(Game1.GraphicsWidth / 2 - DefaultWidth / 2, Game1.GraphicsHeight / 2 - DefaultHeight / 2, DefaultWidth, DefaultHeight),
|
||||
null, Alignment.CenterX, GUI.style, null)
|
||||
public GUIMessageBox(string header, string text, string[] buttons, Alignment textAlignment = Alignment.TopLeft)
|
||||
: base(new Rectangle(0,0, DefaultWidth, DefaultHeight),
|
||||
null, Alignment.Center, GUI.style, null)
|
||||
{
|
||||
//Padding = GUI.style.smallPadding;
|
||||
|
||||
if (buttons == null || buttons.Length == 0)
|
||||
{
|
||||
DebugConsole.ThrowError("Creating a message box with no buttons isn't allowed");
|
||||
return;
|
||||
}
|
||||
//if (buttons == null || buttons.Length == 0)
|
||||
//{
|
||||
// DebugConsole.ThrowError("Creating a message box with no buttons isn't allowed");
|
||||
// return;
|
||||
//}
|
||||
|
||||
new GUITextBlock(new Rectangle(0, 0, 0, 30), header, Color.Transparent, Color.White, textAlignment, GUI.style, this, true);
|
||||
new GUITextBlock(new Rectangle(0, 30, 0, DefaultHeight - 70), text, Color.Transparent, Color.White, textAlignment, GUI.style, this, true);
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace Subsurface
|
||||
}
|
||||
|
||||
|
||||
public GUITextBlock(Rectangle rect, string text, GUIStyle style, Alignment alignment = (Alignment.Left | Alignment.Top), Alignment textAlignment = (Alignment.Left | Alignment.Top), GUIComponent parent = null, bool wrap = false)
|
||||
public GUITextBlock(Rectangle rect, string text, GUIStyle style, Alignment alignment = Alignment.TopLeft, Alignment textAlignment = Alignment.TopLeft, GUIComponent parent = null, bool wrap = false)
|
||||
: this (rect, text, null, null, alignment, textAlignment, style, parent, wrap)
|
||||
{
|
||||
//hoverColor = style.hoverColor;
|
||||
@@ -77,7 +77,7 @@ namespace Subsurface
|
||||
}
|
||||
|
||||
public GUITextBlock(Rectangle rect, string text, Color? color, Color? textColor, Alignment textAlignment = Alignment.Left, GUIStyle style = null, GUIComponent parent = null, bool wrap = false)
|
||||
: this(rect, text,color, textColor, (Alignment.Left | Alignment.Top), textAlignment, style, parent, wrap)
|
||||
: this(rect, text,color, textColor, Alignment.TopLeft, textAlignment, style, parent, wrap)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -196,11 +196,16 @@ namespace Subsurface
|
||||
|
||||
GUI.Update((float)deltaTime);
|
||||
|
||||
if (NetworkMember != null) NetworkMember.Update();
|
||||
if (NetworkMember != null)
|
||||
{
|
||||
NetworkMember.Update();
|
||||
}
|
||||
else
|
||||
{
|
||||
NetworkEvent.events.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
CoroutineManager.Update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -117,17 +117,26 @@ namespace Subsurface
|
||||
listBox.ClearChildren();
|
||||
characters.Clear();
|
||||
|
||||
foreach (CharacterInfo ci in characterInfos)
|
||||
WayPoint[] waypoints = WayPoint.SelectCrewSpawnPoints(characterInfos);
|
||||
|
||||
for (int i = 0; i < waypoints.Length; i++)
|
||||
{
|
||||
WayPoint randomWayPoint = WayPoint.GetRandom(SpawnType.Human);
|
||||
Vector2 position = (randomWayPoint == null) ? Vector2.Zero : randomWayPoint.SimPosition;
|
||||
|
||||
Character character = new Character(ci.File, position, ci);
|
||||
|
||||
Character character = new Character(characterInfos[i], waypoints[i]);
|
||||
Character.Controlled = character;
|
||||
|
||||
if (!character.Info.StartItemsGiven)
|
||||
{
|
||||
character.GiveJobItems();
|
||||
character.Info.StartItemsGiven = true;
|
||||
}
|
||||
|
||||
AddCharacter(character);
|
||||
}
|
||||
|
||||
if (characters.Count>0) SelectCharacter(characters[0]);
|
||||
if (characters.Count > 0) SelectCharacter(characters[0]);
|
||||
}
|
||||
|
||||
public void EndShift()
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Subsurface
|
||||
|
||||
private GUIFrame guiRoot;
|
||||
|
||||
private GUIListBox chatBox;
|
||||
//private GUIListBox chatBox;
|
||||
private GUITextBox textBox;
|
||||
|
||||
private string savePath;
|
||||
@@ -59,20 +59,20 @@ namespace Subsurface
|
||||
|
||||
map = new Map(Rand.Int(), 500);
|
||||
|
||||
int width = 350, height = 100;
|
||||
if (Game1.NetworkMember!=null)
|
||||
{
|
||||
chatBox = new GUIListBox(new Rectangle(
|
||||
Game1.GraphicsWidth - 20 - width,
|
||||
Game1.GraphicsHeight - 40 - 25 - height,
|
||||
width, height),
|
||||
Color.White * 0.5f, GUI.style, guiRoot);
|
||||
//int width = 350, height = 100;
|
||||
//if (Game1.NetworkMember!=null)
|
||||
//{
|
||||
// chatBox = new GUIListBox(new Rectangle(
|
||||
// Game1.GraphicsWidth - 20 - width,
|
||||
// Game1.GraphicsHeight - 40 - 25 - height,
|
||||
// width, height),
|
||||
// Color.White * 0.5f, GUI.style, guiRoot);
|
||||
|
||||
textBox = new GUITextBox(
|
||||
new Rectangle(chatBox.Rect.X, chatBox.Rect.Y + chatBox.Rect.Height + 20, chatBox.Rect.Width, 25),
|
||||
Color.White * 0.5f, Color.Black, Alignment.Bottom, Alignment.Left, GUI.style, guiRoot);
|
||||
textBox.OnEnter = EnterChatMessage;
|
||||
}
|
||||
// textBox = new GUITextBox(
|
||||
// new Rectangle(chatBox.Rect.X, chatBox.Rect.Y + chatBox.Rect.Height + 20, chatBox.Rect.Width, 25),
|
||||
// Color.White * 0.5f, Color.Black, Alignment.Bottom, Alignment.Left, GUI.style, guiRoot);
|
||||
// textBox.OnEnter = EnterChatMessage;
|
||||
//}
|
||||
|
||||
this.gameMode = gameMode;
|
||||
//if (gameMode != null && !gameMode.IsSinglePlayer)
|
||||
@@ -124,7 +124,7 @@ namespace Subsurface
|
||||
|
||||
this.level = level;
|
||||
|
||||
if (Submarine.Loaded!=submarine) submarine.Load();
|
||||
if (Submarine.Loaded != submarine) submarine.Load();
|
||||
|
||||
if (gameMode!=null) gameMode.Start(duration);
|
||||
|
||||
@@ -172,34 +172,35 @@ namespace Subsurface
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool EnterChatMessage(GUITextBox textBox, string message)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(message)) return false;
|
||||
//public bool EnterChatMessage(GUITextBox textBox, string message)
|
||||
//{
|
||||
// if (string.IsNullOrWhiteSpace(message)) return false;
|
||||
|
||||
else if (Game1.NetworkMember != null)
|
||||
{
|
||||
Game1.NetworkMember.SendChatMessage(Game1.NetworkMember.Name + ": " + message);
|
||||
}
|
||||
// else if (Game1.NetworkMember != null)
|
||||
// {
|
||||
// Game1.NetworkMember.SendChatMessage(Game1.NetworkMember.Name + ": " + message);
|
||||
// }
|
||||
|
||||
textBox.Deselect();
|
||||
// textBox.Deselect();
|
||||
|
||||
return true;
|
||||
}
|
||||
// return true;
|
||||
//}
|
||||
|
||||
public void NewChatMessage(string text, Color color)
|
||||
{
|
||||
GUITextBlock msg = new GUITextBlock(new Rectangle(0, 0, 0, 20), text,
|
||||
((chatBox.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f, color,
|
||||
Alignment.Left, null, null, true);
|
||||
//public void NewChatMessage(string text, Color color)
|
||||
//{
|
||||
// GUITextBlock msg = new GUITextBlock(new Rectangle(0, 0, 0, 20), text,
|
||||
|
||||
msg.Padding = new Vector4(20.0f, 0, 0, 0);
|
||||
chatBox.AddChild(msg);
|
||||
// ((chatBox.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f, color,
|
||||
// Alignment.Left, null, null, true);
|
||||
|
||||
while (chatBox.CountChildren > 20)
|
||||
{
|
||||
chatBox.RemoveChild(chatBox.children.First());
|
||||
}
|
||||
}
|
||||
// msg.Padding = new Vector4(20.0f, 0, 0, 0);
|
||||
// chatBox.AddChild(msg);
|
||||
|
||||
// while (chatBox.CountChildren > 20)
|
||||
// {
|
||||
// chatBox.RemoveChild(chatBox.children.First());
|
||||
// }
|
||||
//}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
|
||||
@@ -15,12 +15,12 @@ namespace Subsurface
|
||||
|
||||
private GUIButton endShiftButton;
|
||||
|
||||
private int day;
|
||||
//private int day;
|
||||
|
||||
public int Day
|
||||
{
|
||||
get { return day; }
|
||||
}
|
||||
//public int Day
|
||||
//{
|
||||
// get { return day; }
|
||||
//}
|
||||
|
||||
bool crewDead;
|
||||
private float endTimer;
|
||||
@@ -36,13 +36,13 @@ namespace Subsurface
|
||||
|
||||
hireManager.GenerateCharacters("Content/Characters/Human/human.xml", 10);
|
||||
|
||||
day = 1;
|
||||
//day = 1;
|
||||
}
|
||||
|
||||
public SinglePlayerMode(XElement element)
|
||||
: this(GameModePreset.list.Find(gm => gm.Name == "Single Player"))
|
||||
{
|
||||
day = ToolBox.GetAttributeInt(element,"day",1);
|
||||
//day = ToolBox.GetAttributeInt(element,"day",1);
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
@@ -145,15 +145,17 @@ namespace Subsurface
|
||||
sb.Append("No casualties!");
|
||||
}
|
||||
|
||||
new GUIMessageBox("Day #" + day + " is over!\n", sb.ToString());
|
||||
Game1.GameSession.map.MoveToNextLocation();
|
||||
|
||||
day++;
|
||||
//new GUIMessageBox("Day #" + day + " is over!\n", sb.ToString());
|
||||
|
||||
//day++;
|
||||
}
|
||||
|
||||
crewManager.EndShift();
|
||||
for (int i = Character.CharacterList.Count-1; i>=0; i--)
|
||||
for (int i = Character.CharacterList.Count - 1; i >= 0; i--)
|
||||
{
|
||||
Character.CharacterList.RemoveAt(i);
|
||||
Character.CharacterList[i].Remove();
|
||||
}
|
||||
|
||||
Game1.GameSession.EndShift("");
|
||||
@@ -163,7 +165,7 @@ namespace Subsurface
|
||||
|
||||
public void Save(XElement element)
|
||||
{
|
||||
element.Add(new XAttribute("day", day));
|
||||
//element.Add(new XAttribute("day", day));
|
||||
|
||||
crewManager.Save(element);
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Subsurface
|
||||
/// <summary>
|
||||
/// If there is room, puts the item in the inventory and returns true, otherwise returns false
|
||||
/// </summary>
|
||||
public override bool TryPutItem(Item item, LimbSlot usedSlots, bool createNetworkEvent = true)
|
||||
public override bool TryPutItem(Item item, LimbSlot allowedSlots, bool createNetworkEvent = true)
|
||||
{
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
@@ -54,7 +54,7 @@ namespace Subsurface
|
||||
if (items[i] == item) return true;
|
||||
}
|
||||
|
||||
if (usedSlots.HasFlag(LimbSlot.Any))
|
||||
if (allowedSlots.HasFlag(LimbSlot.Any))
|
||||
{
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
@@ -68,12 +68,12 @@ namespace Subsurface
|
||||
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
if (usedSlots.HasFlag(limbSlots[i]) && items[i]!=null) return false;
|
||||
if (allowedSlots.HasFlag(limbSlots[i]) && items[i]!=null) return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
if (usedSlots.HasFlag(limbSlots[i]) && items[i] == null)
|
||||
if (allowedSlots.HasFlag(limbSlots[i]) && items[i] == null)
|
||||
{
|
||||
PutItem(item, i, createNetworkEvent);
|
||||
item.Equip(character);
|
||||
|
||||
@@ -190,7 +190,7 @@ namespace Subsurface
|
||||
|
||||
guiFrame = new GUIFrame(
|
||||
new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Z, (int)rect.W),
|
||||
new Color(color.X, color.Y, color.Z), alignment);
|
||||
new Color(color.X, color.Y, color.Z, color.W), alignment);
|
||||
//guiFrame.Alpha = color.W;
|
||||
|
||||
break;
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace Subsurface
|
||||
return -1;
|
||||
}
|
||||
|
||||
public virtual int CanBePut(Item item)
|
||||
public virtual int FindAllowedSlot(Item item)
|
||||
{
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
@@ -84,9 +84,9 @@ namespace Subsurface
|
||||
/// <summary>
|
||||
/// If there is room, puts the item in the inventory and returns true, otherwise returns false
|
||||
/// </summary>
|
||||
public virtual bool TryPutItem(Item item, LimbSlot usedSlots = 0, bool createNetworkEvent = true)
|
||||
public virtual bool TryPutItem(Item item, LimbSlot allowedSlots = 0, bool createNetworkEvent = true)
|
||||
{
|
||||
int slot = CanBePut(item);
|
||||
int slot = FindAllowedSlot(item);
|
||||
if (slot < 0) return false;
|
||||
|
||||
PutItem(item, slot, createNetworkEvent);
|
||||
@@ -268,8 +268,8 @@ namespace Subsurface
|
||||
Vector2 pos = new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height + 20) - GUI.font.MeasureString(item.Name)*0.5f;
|
||||
pos.X = (int)pos.X;
|
||||
pos.Y = (int)pos.Y;
|
||||
spriteBatch.DrawString(GUI.font, item.Name, pos - new Vector2(1.0f,1.0f), Color.Black);
|
||||
spriteBatch.DrawString(GUI.font, item.Name, pos, Color.White);
|
||||
spriteBatch.DrawString(GUI.font, item.Name + " - "+item.ID, pos - new Vector2(1.0f,1.0f), Color.Black);
|
||||
spriteBatch.DrawString(GUI.font, item.Name + " - " + item.ID, pos, Color.White);
|
||||
}
|
||||
|
||||
if (item.Condition < 100.0f)
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Subsurface
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
public override int CanBePut(Item item)
|
||||
public override int FindAllowedSlot(Item item)
|
||||
{
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace Subsurface
|
||||
{
|
||||
//give an unique ID
|
||||
bool IDfound;
|
||||
id = 0;
|
||||
id = 1;//Rand.Int(int.MaxValue);
|
||||
do
|
||||
{
|
||||
id += 1;
|
||||
|
||||
@@ -19,6 +19,10 @@ namespace Subsurface
|
||||
private int seed;
|
||||
private int size;
|
||||
|
||||
private Texture2D iceTexture;
|
||||
private Texture2D iceCraters;
|
||||
private Texture2D iceCrack;
|
||||
|
||||
private Location currentLocation;
|
||||
private Location selectedLocation;
|
||||
|
||||
@@ -34,49 +38,12 @@ namespace Subsurface
|
||||
|
||||
connections = new List<LocationConnection>();
|
||||
|
||||
iceTexture = Game1.textureLoader.FromFile("Content/Map/iceSurface.png");
|
||||
iceCraters = Game1.textureLoader.FromFile("Content/Map/iceCraters.png");
|
||||
iceCrack = Game1.textureLoader.FromFile("Content/Map/iceCrack.png");
|
||||
|
||||
GenerateLocations();
|
||||
|
||||
//for (int i = 0; i<10; i++)
|
||||
//{
|
||||
// Vector2 pos = new Vector2((float)Game1.random.NextDouble() * size, (float)Game1.random.NextDouble() * size);
|
||||
|
||||
// Location location =
|
||||
// locations.Add(location);
|
||||
//}
|
||||
|
||||
//for (int i = 0; i < 10; i++)
|
||||
//{
|
||||
|
||||
// int closestIndex = 0;
|
||||
// float closestDistance = 0.0f;
|
||||
// for (int j = 0; j<10; j++)
|
||||
// {
|
||||
// if (j == i) continue;
|
||||
|
||||
// //ignore if already connected
|
||||
// bool alreadyConnected = false;
|
||||
// foreach (LocationConnection connection in connections)
|
||||
// {
|
||||
// if (connection.Locations.Contains(locations[i]) && connection.Locations.Contains(locations[j]))
|
||||
// {
|
||||
// alreadyConnected = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (alreadyConnected) continue;
|
||||
|
||||
// float dist = Vector2.Distance(locations[i].MapPosition, locations[j].MapPosition);
|
||||
// if (closestDistance > 0.0f && dist > closestDistance) continue;
|
||||
|
||||
// closestDistance = dist;
|
||||
// closestIndex = j;
|
||||
// }
|
||||
|
||||
|
||||
// connections.Add(new LocationConnection(locations[i], locations[closestIndex], level));
|
||||
//}
|
||||
|
||||
currentLocation = locations[locations.Count/2];
|
||||
}
|
||||
|
||||
@@ -97,6 +64,12 @@ namespace Subsurface
|
||||
{
|
||||
if (edge.point1 == edge.point2) continue;
|
||||
|
||||
//remove points from the edge of the map
|
||||
if (edge.point1.X == 0 || edge.point1.X == size) continue;
|
||||
if (edge.point1.Y == 0 || edge.point1.Y == size) continue;
|
||||
if (edge.point2.X == 0 || edge.point2.X == size) continue;
|
||||
if (edge.point2.Y == 0 || edge.point2.Y == size) continue;
|
||||
|
||||
Location[] newLocations = new Location[2];
|
||||
newLocations[0] = locations.Find(l => l.MapPosition == edge.point1 || l.MapPosition == edge.point2);
|
||||
newLocations[1] = locations.Find(l => l != newLocations[0] && (l.MapPosition == edge.point1 || l.MapPosition == edge.point2));
|
||||
@@ -117,6 +90,8 @@ namespace Subsurface
|
||||
}
|
||||
|
||||
connections.Add(new LocationConnection(newLocations[0], newLocations[1], Level.CreateRandom()));
|
||||
|
||||
|
||||
}
|
||||
|
||||
float minDistance = 50.0f;
|
||||
@@ -124,40 +99,103 @@ namespace Subsurface
|
||||
{
|
||||
LocationConnection connection = connections[i];
|
||||
|
||||
if (Vector2.Distance(connection.Locations[0].MapPosition, connection.Locations[1].MapPosition) > minDistance) continue;
|
||||
if (Vector2.Distance(connection.Locations[0].MapPosition, connection.Locations[1].MapPosition) > minDistance)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
locations.Remove(connection.Locations[0]);
|
||||
connections.Remove(connection);
|
||||
|
||||
|
||||
foreach (LocationConnection connection2 in connections)
|
||||
{
|
||||
if (connection == connection2) continue;
|
||||
if (connection2.Locations[0] == connection.Locations[0]) connection2.Locations[0] = connection.Locations[1];
|
||||
if (connection2.Locations[1] == connection.Locations[0]) connection2.Locations[1] = connection.Locations[1];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = connections.Count - 1; i >= 0; i--)
|
||||
{
|
||||
LocationConnection connection = connections[i];
|
||||
|
||||
for (int n = i-1; n >= 0; n--)
|
||||
{
|
||||
if (connection.Locations.Contains(connections[n].Locations[0])
|
||||
&& connection.Locations.Contains(connections[n].Locations[1]))
|
||||
{
|
||||
connections.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (LocationConnection connection in connections)
|
||||
{
|
||||
Vector2 start = connection.Locations[0].MapPosition;
|
||||
Vector2 end = connection.Locations[1].MapPosition;
|
||||
int generations = (int)(Math.Sqrt(Vector2.Distance(start, end) / 10.0f));
|
||||
connection.CrackSegments = GenerateCrack(start, end, generations);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Vector2[]> GenerateCrack(Vector2 start, Vector2 end, int generations)
|
||||
{
|
||||
List<Vector2[]> segments = new List<Vector2[]>();
|
||||
|
||||
segments.Add(new Vector2[] {start, end});
|
||||
|
||||
float offsetAmount = 5.0f;
|
||||
|
||||
for (int n = 0; n<generations; n++)
|
||||
{
|
||||
for (int i = 0; i<segments.Count; i++)
|
||||
{
|
||||
Vector2 startSegment = segments[i][0];
|
||||
Vector2 endSegment = segments[i][1];
|
||||
|
||||
segments.RemoveAt(i);
|
||||
|
||||
Vector2 midPoint = (startSegment + endSegment) / 2.0f;
|
||||
|
||||
Vector2 normal = Vector2.Normalize(endSegment - startSegment);
|
||||
normal = new Vector2(-normal.Y, normal.X);
|
||||
midPoint += normal * Rand.Range(-offsetAmount, offsetAmount);
|
||||
|
||||
segments.Insert(i, new Vector2[] { startSegment, midPoint });
|
||||
segments.Insert(i+1, new Vector2[] { midPoint, endSegment });
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return segments;
|
||||
}
|
||||
|
||||
public void MoveToNextLocation()
|
||||
{
|
||||
currentLocation = selectedLocation;
|
||||
selectedLocation = null;
|
||||
}
|
||||
|
||||
private Location highlightedLocation;
|
||||
public void Draw(SpriteBatch spriteBatch, Rectangle rect)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, rect, Color.DarkBlue, true);
|
||||
//GUI.DrawRectangle(spriteBatch, rect, Color.DarkBlue, true);
|
||||
|
||||
spriteBatch.Draw(iceTexture, rect, Color.White);
|
||||
|
||||
Vector2 rectCorner = new Vector2(rect.X, rect.Y);
|
||||
Vector2 scale = new Vector2((float)rect.Width/ size, (float)rect.Height/size);
|
||||
|
||||
float maxDist = 20.0f;
|
||||
float closestDist = 0.0f;
|
||||
Location highlightedLocation = null;
|
||||
foreach (Location location in locations)
|
||||
highlightedLocation = null;
|
||||
for (int i = 0; i < locations.Count;i++ )
|
||||
{
|
||||
Vector2 pos = location.MapPosition * scale;
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X + (int)pos.X, rect.Y + (int)pos.Y, 5, 5), Color.White, true);
|
||||
Location location = locations[i];
|
||||
Vector2 pos = rectCorner + location.MapPosition * scale;
|
||||
|
||||
if (currentLocation == location)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X + (int)pos.X - 4, rect.Y + (int)pos.Y - 4, 5+8, 5+8), Color.Red, false);
|
||||
}
|
||||
|
||||
float dist = Vector2.Distance(PlayerInput.MousePosition, new Vector2(rect.X + pos.X, rect.Y + pos.Y));
|
||||
float dist = Vector2.Distance(PlayerInput.MousePosition, new Vector2(pos.X, pos.Y));
|
||||
if (dist < maxDist && (highlightedLocation == null || dist < closestDist))
|
||||
{
|
||||
closestDist = dist;
|
||||
@@ -165,55 +203,78 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
if (highlightedLocation!=null)
|
||||
{
|
||||
Vector2 pos = highlightedLocation.MapPosition * scale;
|
||||
pos.X = (int)pos.X;
|
||||
pos.Y = (int)pos.Y;
|
||||
spriteBatch.DrawString(GUI.font, highlightedLocation.Name, pos + new Vector2(rect.X - 50, rect.Y), Color.White);
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X + (int)pos.X - 4, rect.Y + (int)pos.Y - 4, 5 + 8, 5 + 8), Color.White, false);
|
||||
}
|
||||
|
||||
if (selectedLocation != null)
|
||||
{
|
||||
Vector2 pos = selectedLocation.MapPosition * scale;
|
||||
pos.X = (int)pos.X;
|
||||
pos.Y = (int)pos.Y;
|
||||
spriteBatch.DrawString(GUI.font, selectedLocation.Name, pos + new Vector2(rect.X - 50, rect.Y), Color.White);
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X + (int)pos.X - 4, rect.Y + (int)pos.Y - 4, 5 + 8, 5 + 8), Color.White, false);
|
||||
}
|
||||
|
||||
Vector2 rectCorner = new Vector2(rect.X, rect.Y);
|
||||
foreach (LocationConnection connection in connections)
|
||||
{
|
||||
GUI.DrawLine(spriteBatch,
|
||||
connection.Locations[0].MapPosition * scale + rectCorner,
|
||||
connection.Locations[1].MapPosition * scale + rectCorner, Color.LightGray);
|
||||
|
||||
if (highlightedLocation!=currentLocation &&
|
||||
Color crackColor = Color.White;
|
||||
|
||||
if (highlightedLocation != currentLocation &&
|
||||
connection.Locations.Contains(highlightedLocation) && connection.Locations.Contains(currentLocation))
|
||||
{
|
||||
GUI.DrawLine(spriteBatch,
|
||||
connection.Locations[0].MapPosition * scale + rectCorner +Vector2.One,
|
||||
connection.Locations[1].MapPosition * scale + rectCorner + Vector2.One, Color.White);
|
||||
crackColor = Color.Red;
|
||||
|
||||
if (PlayerInput.LeftButtonClicked())
|
||||
if(selectedLocation!=highlightedLocation && highlightedLocation!=null)
|
||||
if (PlayerInput.LeftButtonClicked()&&
|
||||
selectedLocation != highlightedLocation && highlightedLocation != null)
|
||||
{
|
||||
//currentLocation = highlightedLocation;
|
||||
Game1.LobbyScreen.SelectLocation(highlightedLocation, connection);
|
||||
selectedLocation = highlightedLocation;
|
||||
}
|
||||
selectedLocation = highlightedLocation;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (selectedLocation != currentLocation &&
|
||||
(connection.Locations.Contains(selectedLocation) && connection.Locations.Contains(currentLocation)))
|
||||
{
|
||||
GUI.DrawLine(spriteBatch,
|
||||
connection.Locations[0].MapPosition * scale + rectCorner + Vector2.One,
|
||||
connection.Locations[1].MapPosition * scale + rectCorner + Vector2.One, Color.White);
|
||||
|
||||
crackColor = Color.Red;
|
||||
}
|
||||
|
||||
foreach (Vector2[] segment in connection.CrackSegments)
|
||||
{
|
||||
Vector2 start = segment[0] * scale + rectCorner;
|
||||
Vector2 end = segment[1] * scale + rectCorner;
|
||||
float dist = Vector2.Distance(start, end);
|
||||
|
||||
//spriteBatch.Draw(iceCrack,
|
||||
// new Rectangle((int)((start.X + end.X) / 2.0f), (int)((start.Y + end.Y) / 2.0f), (int)dist, 30),
|
||||
// new Rectangle(0, 0, iceCrack.Width, 60), crackColor, MathUtils.VectorToAngle(start - end),
|
||||
// new Vector2(dist / 2, 30), SpriteEffects.None, 0.01f);
|
||||
GUI.DrawLine(spriteBatch,
|
||||
segment[0] * scale + rectCorner,
|
||||
segment[1] * scale + rectCorner, crackColor);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < locations.Count; i++)
|
||||
{
|
||||
Location location = locations[i];
|
||||
Vector2 pos = rectCorner + location.MapPosition * scale;
|
||||
|
||||
int imgIndex = i % 16;
|
||||
int xCell = imgIndex % 4;
|
||||
int yCell = (int)Math.Floor(imgIndex / 4.0f);
|
||||
spriteBatch.Draw(iceCraters, pos,
|
||||
new Rectangle(xCell * 64, yCell * 64, 64, 64),
|
||||
Color.White, i,
|
||||
new Vector2(32, 32), 0.5f*scale, SpriteEffects.None, 0.0f);
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++ )
|
||||
{
|
||||
Location location = (i == 0) ? highlightedLocation : selectedLocation;
|
||||
if (i == 2) location = currentLocation;
|
||||
|
||||
if (location == null) continue;
|
||||
|
||||
Vector2 pos = rectCorner + location.MapPosition * scale;
|
||||
pos.X = (int)pos.X;
|
||||
pos.Y = (int)pos.Y;
|
||||
if (highlightedLocation==location)
|
||||
{
|
||||
spriteBatch.DrawString(GUI.font, location.Name, pos + new Vector2(-50, -20), Color.DarkRed);
|
||||
}
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X - 4, (int)pos.Y - 4, 5 + 8, 5 + 8), Color.DarkRed, false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -222,8 +283,10 @@ namespace Subsurface
|
||||
|
||||
class LocationConnection
|
||||
{
|
||||
Location[] locations;
|
||||
Level level;
|
||||
private Location[] locations;
|
||||
private Level level;
|
||||
|
||||
public List<Vector2[]> CrackSegments;
|
||||
|
||||
public Location[] Locations
|
||||
{
|
||||
|
||||
@@ -820,7 +820,7 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
ID = 1;
|
||||
//ID = 1;
|
||||
|
||||
loaded = this;
|
||||
}
|
||||
@@ -838,8 +838,7 @@ namespace Subsurface
|
||||
public static void Unload()
|
||||
{
|
||||
if (loaded == null) return;
|
||||
|
||||
|
||||
|
||||
loaded.Remove();
|
||||
|
||||
loaded.Clear();
|
||||
|
||||
@@ -13,16 +13,35 @@ namespace Subsurface
|
||||
public enum SpawnType { None, Human, Enemy };
|
||||
class WayPoint : MapEntity
|
||||
{
|
||||
|
||||
public static List<WayPoint> WayPointList = new List<WayPoint>();
|
||||
|
||||
private SpawnType spawnType;
|
||||
|
||||
//characters spawning at the waypoint will be given an ID card with these tags
|
||||
private string[] idCardTags;
|
||||
|
||||
//only characters with this job will be spawned at the waypoint
|
||||
private JobPrefab assignedJob;
|
||||
|
||||
public SpawnType SpawnType
|
||||
{
|
||||
get { return spawnType; }
|
||||
set { spawnType = value; }
|
||||
}
|
||||
|
||||
public string[] IdCardTags
|
||||
{
|
||||
get { return idCardTags; }
|
||||
private set
|
||||
{
|
||||
idCardTags = value;
|
||||
for (int i = 0; i<idCardTags.Length; i++)
|
||||
{
|
||||
idCardTags[i] = idCardTags[i].Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector2 SimPosition
|
||||
{
|
||||
get { return ConvertUnits.ToSimUnits(new Vector2(rect.X, rect.Y)); }
|
||||
@@ -32,8 +51,10 @@ namespace Subsurface
|
||||
{
|
||||
rect = newRect;
|
||||
linkedTo = new ObservableCollection<MapEntity>();
|
||||
idCardTags = new string[0];
|
||||
|
||||
mapEntityList.Add(this);
|
||||
WayPointList.Add(this);
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch, bool editing)
|
||||
@@ -54,17 +75,13 @@ namespace Subsurface
|
||||
|
||||
public override void DrawEditing(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
int x = 300, y = 10;
|
||||
if (editingHUD==null)
|
||||
{
|
||||
editingHUD = CreateEditingHUD();
|
||||
}
|
||||
|
||||
spriteBatch.DrawString(GUI.font, "Editing waypoint", new Vector2(x, y), Color.Black);
|
||||
spriteBatch.DrawString(GUI.font, "Hold space to link to another entity", new Vector2(x, y + 20), Color.Black);
|
||||
spriteBatch.DrawString(GUI.font, "Spawnpoint: "+spawnType.ToString()+" +/-", new Vector2(x, y + 40), Color.Black);
|
||||
|
||||
if (PlayerInput.KeyHit(Keys.Add)) spawnType += 1;
|
||||
if (PlayerInput.KeyHit(Keys.Subtract)) spawnType -= 1;
|
||||
|
||||
if (spawnType > SpawnType.Enemy) spawnType = SpawnType.None;
|
||||
if (spawnType < SpawnType.None) spawnType = SpawnType.Enemy;
|
||||
editingHUD.Update((float)Physics.step);
|
||||
editingHUD.Draw(spriteBatch);
|
||||
|
||||
if (!PlayerInput.LeftButtonClicked()) return;
|
||||
|
||||
@@ -82,18 +99,105 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
public static WayPoint GetRandom(SpawnType spawnType = SpawnType.None)
|
||||
private bool ChangeSpawnType(GUIButton button, object obj)
|
||||
{
|
||||
GUITextBlock spawnTypeText = button.Parent as GUITextBlock;
|
||||
|
||||
spawnType += (int)button.UserData;
|
||||
|
||||
if (spawnType > SpawnType.Enemy) spawnType = SpawnType.None;
|
||||
if (spawnType < SpawnType.None) spawnType = SpawnType.Enemy;
|
||||
|
||||
spawnTypeText.Text = spawnType.ToString();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool EnterIDCardTags(GUITextBox textBox, string text)
|
||||
{
|
||||
IdCardTags = text.Split(',');
|
||||
textBox.Text = text;
|
||||
textBox.Color = Color.White;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool EnterAssignedJob(GUITextBox textBox, string text)
|
||||
{
|
||||
string trimmedName = text.ToLower().Trim();
|
||||
assignedJob = JobPrefab.List.Find(jp => jp.Name.ToLower() == trimmedName);
|
||||
|
||||
if (assignedJob !=null && trimmedName!="none")
|
||||
{
|
||||
textBox.Color = Color.White;
|
||||
textBox.Text = (assignedJob == null) ? "None" : assignedJob.Name;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool TextBoxChanged(GUITextBox textBox, string text)
|
||||
{
|
||||
textBox.Color = Color.Red;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private GUIComponent CreateEditingHUD(bool inGame = false)
|
||||
{
|
||||
int width = 500;
|
||||
int x = Game1.GraphicsWidth / 2 - width / 2, y = 10;
|
||||
|
||||
editingHUD = new GUIFrame(new Rectangle(x, y, width, 150), Color.Black * 0.5f);
|
||||
editingHUD.Padding = new Vector4(10, 10, 0, 0);
|
||||
editingHUD.UserData = this;
|
||||
|
||||
new GUITextBlock(new Rectangle(0, 0, 100, 20), "Editing waypoint", GUI.style, editingHUD);
|
||||
new GUITextBlock(new Rectangle(0, 20, 100, 20), "Hold space to link to another entity", GUI.style, editingHUD);
|
||||
new GUITextBlock(new Rectangle(0, 40, 100, 20), "Spawnpoint: ", GUI.style, editingHUD);
|
||||
|
||||
var spawnTypeText = new GUITextBlock(new Rectangle(0, 40, 200, 20), spawnType.ToString(), GUI.style, Alignment.Right, Alignment.TopLeft, editingHUD);
|
||||
|
||||
var button = new GUIButton(new Rectangle(-30,0,20,20), "-", Alignment.Right, GUI.style, spawnTypeText);
|
||||
button.UserData = -1;
|
||||
button.OnClicked = ChangeSpawnType;
|
||||
|
||||
button = new GUIButton(new Rectangle(0, 0, 20, 20), "+", Alignment.Right, GUI.style, spawnTypeText);
|
||||
button.UserData = 1;
|
||||
button.OnClicked = ChangeSpawnType;
|
||||
|
||||
//spriteBatch.DrawString(GUI.font, "Spawnpoint: " + spawnType.ToString() + " +/-", new Vector2(x, y + 40), Color.Black);
|
||||
|
||||
y = 40+20;
|
||||
|
||||
new GUITextBlock(new Rectangle(0, y, 100, 20), "ID Card tags:", Color.Transparent, Color.Black, Alignment.TopLeft, null, editingHUD);
|
||||
GUITextBox propertyBox = new GUITextBox(new Rectangle(100, y, 200, 20), GUI.style, editingHUD);
|
||||
propertyBox.Text = string.Join(", ", idCardTags);
|
||||
propertyBox.OnEnter = EnterIDCardTags;
|
||||
propertyBox.OnTextChanged = TextBoxChanged;
|
||||
y = y + 30;
|
||||
|
||||
new GUITextBlock(new Rectangle(0, y, 100, 20), "Assigned job:", Color.Transparent, Color.Black, Alignment.TopLeft, null, editingHUD);
|
||||
propertyBox = new GUITextBox(new Rectangle(100, y, 200, 20), GUI.style, editingHUD);
|
||||
propertyBox.Text = (assignedJob == null) ? "None" : assignedJob.Name;
|
||||
|
||||
propertyBox.OnEnter = EnterAssignedJob;
|
||||
propertyBox.OnTextChanged = TextBoxChanged;
|
||||
y = y + 30;
|
||||
|
||||
return editingHUD;
|
||||
}
|
||||
|
||||
public static WayPoint GetRandom(SpawnType spawnType = SpawnType.None, Job assignedJob = null)
|
||||
{
|
||||
List<WayPoint> wayPoints = new List<WayPoint>();
|
||||
|
||||
foreach (MapEntity e in mapEntityList)
|
||||
foreach (WayPoint wp in WayPointList)
|
||||
{
|
||||
WayPoint wayPoint = e as WayPoint;
|
||||
if (wayPoint==null) continue;
|
||||
|
||||
if (spawnType != SpawnType.None && wayPoint.spawnType != spawnType) continue;
|
||||
if (spawnType != SpawnType.None && wp.spawnType != spawnType) continue;
|
||||
if (assignedJob != null && wp.assignedJob != assignedJob.Prefab) continue;
|
||||
|
||||
wayPoints.Add(wayPoint);
|
||||
wayPoints.Add(wp);
|
||||
}
|
||||
|
||||
if (!wayPoints.Any()) return null;
|
||||
@@ -101,6 +205,55 @@ namespace Subsurface
|
||||
return wayPoints[Rand.Int(wayPoints.Count())];
|
||||
}
|
||||
|
||||
public static WayPoint[] SelectCrewSpawnPoints(List<CharacterInfo> crew)
|
||||
{
|
||||
List<WayPoint> unassignedWayPoints = new List<WayPoint>();
|
||||
foreach (WayPoint wp in WayPointList)
|
||||
{
|
||||
if (wp.spawnType == SpawnType.Human) unassignedWayPoints.Add(wp);
|
||||
}
|
||||
|
||||
WayPoint[] assignedWayPoints = new WayPoint[crew.Count];
|
||||
|
||||
for (int i = 0; i < crew.Count; i++ )
|
||||
{
|
||||
//try to give the crew member a spawnpoint that hasn't been assigned to anyone and matches their job
|
||||
for (int n = 0; n < unassignedWayPoints.Count; n++)
|
||||
{
|
||||
|
||||
if (crew[i].Job.Prefab != unassignedWayPoints[n].assignedJob) continue;
|
||||
assignedWayPoints[i] = unassignedWayPoints[n];
|
||||
unassignedWayPoints.RemoveAt(n);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//go through the crewmembers that don't have a spawnpoint yet (if any)
|
||||
for (int i = 0; i < crew.Count; i++)
|
||||
{
|
||||
if (assignedWayPoints[i] != null) continue;
|
||||
|
||||
//try to assign a spawnpoint that matches the job, even if the spawnpoint is already assigned to someone else
|
||||
foreach (WayPoint wp in WayPointList)
|
||||
{
|
||||
if (wp.spawnType != SpawnType.Human || wp.assignedJob != crew[i].Job.Prefab) continue;
|
||||
|
||||
assignedWayPoints[i] = wp;
|
||||
break;
|
||||
}
|
||||
|
||||
if (assignedWayPoints[i] != null) continue;
|
||||
|
||||
//everything else failed -> just give a random spawnpoint
|
||||
assignedWayPoints[i] = GetRandom(SpawnType.Human);
|
||||
}
|
||||
|
||||
|
||||
return assignedWayPoints;
|
||||
}
|
||||
|
||||
|
||||
public override XElement Save(XDocument doc)
|
||||
{
|
||||
XElement element = new XElement("WayPoint");
|
||||
@@ -110,6 +263,16 @@ namespace Subsurface
|
||||
new XAttribute("y", rect.Y),
|
||||
new XAttribute("spawn", spawnType));
|
||||
|
||||
if (idCardTags.Length > 0)
|
||||
{
|
||||
element.Add(new XAttribute("idcardtags", string.Join(",", idCardTags)));
|
||||
}
|
||||
|
||||
if (assignedJob != null)
|
||||
{
|
||||
element.Add(new XAttribute("job", assignedJob.Name));
|
||||
}
|
||||
|
||||
doc.Root.Add(element);
|
||||
|
||||
if (linkedTo != null)
|
||||
@@ -138,6 +301,18 @@ namespace Subsurface
|
||||
w.spawnType = (SpawnType)Enum.Parse(typeof(SpawnType),
|
||||
ToolBox.GetAttributeString(element, "spawn", "None"));
|
||||
|
||||
string idCardTagString = ToolBox.GetAttributeString(element, "idcardtags", "");
|
||||
if (!string.IsNullOrWhiteSpace(idCardTagString))
|
||||
{
|
||||
w.IdCardTags = idCardTagString.Split(',');
|
||||
}
|
||||
|
||||
string jobName = ToolBox.GetAttributeString(element, "job", "").ToLower();
|
||||
if (!string.IsNullOrWhiteSpace(jobName))
|
||||
{
|
||||
w.assignedJob = JobPrefab.List.Find(jp => jp.Name.ToLower() == jobName);
|
||||
}
|
||||
|
||||
w.linkedToID = new List<int>();
|
||||
int i = 0;
|
||||
while (element.Attribute("linkedto" + i) != null)
|
||||
@@ -146,6 +321,13 @@ namespace Subsurface
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Remove()
|
||||
{
|
||||
base.Remove();
|
||||
|
||||
WayPointList.Remove(this);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,15 @@ namespace Subsurface.Networking
|
||||
private Character myCharacter;
|
||||
private CharacterInfo characterInfo;
|
||||
|
||||
GUIMessageBox reconnectBox;
|
||||
|
||||
private bool connected;
|
||||
|
||||
private int myID;
|
||||
|
||||
List<Client> otherClients;
|
||||
|
||||
private string serverIP;
|
||||
|
||||
public Character Character
|
||||
{
|
||||
@@ -37,8 +45,10 @@ namespace Subsurface.Networking
|
||||
otherClients = new List<Client>();
|
||||
}
|
||||
|
||||
public bool ConnectToServer(string hostIP)
|
||||
public void ConnectToServer(string hostIP)
|
||||
{
|
||||
serverIP = hostIP;
|
||||
|
||||
myCharacter = Character.Controlled;
|
||||
|
||||
// Create new instance of configs. Parameter is "application Id". It has to be same on client and server.
|
||||
@@ -65,7 +75,7 @@ namespace Subsurface.Networking
|
||||
catch (ArgumentNullException e)
|
||||
{
|
||||
DebugConsole.ThrowError("Couldn't connect to "+hostIP+". Error message: "+e.Message);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Create timespan of 30ms
|
||||
@@ -78,27 +88,24 @@ namespace Subsurface.Networking
|
||||
//update.Elapsed += new System.Timers.ElapsedEventHandler(Update);
|
||||
|
||||
// Funtion that waits for connection approval info from server
|
||||
WaitForStartingInfo();
|
||||
|
||||
if (Client.ConnectionStatus != NetConnectionStatus.Connected)
|
||||
{
|
||||
DebugConsole.ThrowError("Couldn't connect to server");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
CoroutineManager.StartCoroutine(WaitForStartingInfo());
|
||||
|
||||
// Start the timer
|
||||
//update.Start();
|
||||
|
||||
}
|
||||
|
||||
private bool RetryConnection(GUIButton button, object obj)
|
||||
{
|
||||
ConnectToServer(serverIP);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Before main looping starts, we loop here and wait for approval message
|
||||
private void WaitForStartingInfo()
|
||||
private IEnumerable<Status> WaitForStartingInfo()
|
||||
{
|
||||
reconnectBox = new GUIMessageBox("CONNECTING", "Connecting to "+serverIP, new string[0]);
|
||||
|
||||
// When this is set to true, we are approved and ready to go
|
||||
bool CanStart = false;
|
||||
|
||||
@@ -107,7 +114,9 @@ namespace Subsurface.Networking
|
||||
// Loop untill we are approved
|
||||
while (!CanStart)
|
||||
{
|
||||
if (DateTime.Now>timeOut) return;
|
||||
yield return Status.Running;
|
||||
|
||||
if (DateTime.Now > timeOut) break;
|
||||
|
||||
NetIncomingMessage inc;
|
||||
// If new messages arrived
|
||||
@@ -120,7 +129,9 @@ namespace Subsurface.Networking
|
||||
case NetIncomingMessageType.Data:
|
||||
if (inc.ReadByte() == (byte)PacketTypes.LoggedIn)
|
||||
{
|
||||
int myID = inc.ReadInt32();
|
||||
myID = inc.ReadInt32();
|
||||
|
||||
Game1.NetLobbyScreen.ClearPlayers();
|
||||
|
||||
//add the names of other connected clients to the lobby screen
|
||||
int existingClients = inc.ReadInt32();
|
||||
@@ -149,19 +160,50 @@ namespace Subsurface.Networking
|
||||
|
||||
break;
|
||||
default:
|
||||
// Should not happen and if happens, don't care
|
||||
Console.WriteLine(inc.ReadString() + " Strange message");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (reconnectBox != null)
|
||||
{
|
||||
reconnectBox.Close(null, null);
|
||||
reconnectBox = null;
|
||||
}
|
||||
|
||||
if (Client.ConnectionStatus != NetConnectionStatus.Connected)
|
||||
{
|
||||
reconnectBox = new GUIMessageBox("CONNECTION FAILED", "Failed to connect to server.", new string[] { "Retry", "Cancel" });
|
||||
reconnectBox.Buttons[0].OnClicked += RetryConnection;
|
||||
reconnectBox.Buttons[0].OnClicked += reconnectBox.Close;
|
||||
}
|
||||
else
|
||||
{
|
||||
Game1.NetLobbyScreen.Select();
|
||||
connected = true;
|
||||
}
|
||||
|
||||
yield return Status.Success;
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (updateTimer > DateTime.Now) return;
|
||||
|
||||
if (myCharacter!=null)
|
||||
if (!connected || updateTimer > DateTime.Now) return;
|
||||
|
||||
if (reconnectBox != null)
|
||||
{
|
||||
ConnectToServer(serverIP);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Client.ConnectionStatus == NetConnectionStatus.Disconnected)
|
||||
{
|
||||
reconnectBox = new GUIMessageBox("CONNECTION LOST", "You have been disconnected from the server. Reconnecting...", new string[0]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (myCharacter != null)
|
||||
{
|
||||
if (myCharacter.IsDead)
|
||||
{
|
||||
@@ -190,7 +232,6 @@ namespace Subsurface.Networking
|
||||
|
||||
NetworkEvent.events.Clear();
|
||||
|
||||
|
||||
CheckServerMessages();
|
||||
|
||||
// Update current time
|
||||
@@ -236,13 +277,20 @@ namespace Subsurface.Networking
|
||||
Game1.GameSession = new GameSession(Submarine.Loaded);
|
||||
Game1.GameSession.StartShift(duration, levelSeed);
|
||||
|
||||
myCharacter = ReadCharacterData(inc);
|
||||
Character.Controlled = myCharacter;
|
||||
//myCharacter = ReadCharacterData(inc);
|
||||
//Character.Controlled = myCharacter;
|
||||
|
||||
int count = inc.ReadInt32();
|
||||
for (int n = 0; n < count; n++)
|
||||
{
|
||||
ReadCharacterData(inc);
|
||||
int id = inc.ReadInt32();
|
||||
Character newCharacter = ReadCharacterData(inc);
|
||||
|
||||
if (id == myID)
|
||||
{
|
||||
myCharacter = newCharacter;
|
||||
Character.Controlled = myCharacter;
|
||||
}
|
||||
}
|
||||
|
||||
gameStarted = true;
|
||||
@@ -275,7 +323,7 @@ namespace Subsurface.Networking
|
||||
case (byte)PacketTypes.KickedOut:
|
||||
string msg = inc.ReadString();
|
||||
|
||||
DebugConsole.ThrowError(msg);
|
||||
new GUIMessageBox("KICKED", msg);
|
||||
|
||||
Game1.MainMenuScreen.Select();
|
||||
|
||||
@@ -296,8 +344,8 @@ namespace Subsurface.Networking
|
||||
case (byte)PacketTypes.Traitor:
|
||||
string targetName = inc.ReadString();
|
||||
|
||||
Game1.GameSession.NewChatMessage("You are an agent of Ordo Europae", messageColor[(int)ChatMessageType.Server]);
|
||||
Game1.GameSession.NewChatMessage("Your secret task is to assassinate " + targetName + "!", messageColor[(int)ChatMessageType.Server]);
|
||||
new GUIMessageBox("You are the Traitor!", "Your secret task is to assassinate " + targetName + "!");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -356,20 +404,37 @@ namespace Subsurface.Networking
|
||||
bool isFemale = inc.ReadBoolean();
|
||||
int inventoryID = inc.ReadInt32();
|
||||
|
||||
int headSpriteID = inc.ReadInt32();
|
||||
|
||||
int headSpriteID = inc.ReadInt32();
|
||||
|
||||
Vector2 position = new Vector2(inc.ReadFloat(), inc.ReadFloat());
|
||||
|
||||
string jobName = inc.ReadString();
|
||||
JobPrefab jobPrefab = JobPrefab.List.Find(jp => jp.Name == jobName);
|
||||
|
||||
Vector2 position = new Vector2(inc.ReadFloat(), inc.ReadFloat());
|
||||
|
||||
CharacterInfo ch = new CharacterInfo("Content/Characters/Human/human.xml", newName, isFemale ? Gender.Female : Gender.Male, jobPrefab);
|
||||
ch.HeadSpriteId = headSpriteID;
|
||||
Character character = new Character(ch, position);
|
||||
|
||||
WayPoint closestWaypoint = null;
|
||||
float closestDist = 0.0f;
|
||||
foreach (WayPoint wp in WayPoint.WayPointList)
|
||||
{
|
||||
float dist = Vector2.Distance(wp.SimPosition, position);
|
||||
if (closestWaypoint != null && dist > closestDist) continue;
|
||||
|
||||
closestWaypoint = wp;
|
||||
closestDist = dist;
|
||||
continue;
|
||||
}
|
||||
|
||||
Character character = (closestWaypoint == null) ?
|
||||
new Character(ch, position) :
|
||||
new Character(ch, closestWaypoint);
|
||||
|
||||
character.ID = ID;
|
||||
character.Inventory.ID = inventoryID;
|
||||
|
||||
character.GiveJobItems();
|
||||
|
||||
return character;
|
||||
}
|
||||
|
||||
|
||||
@@ -291,7 +291,9 @@ namespace Subsurface.Networking
|
||||
Game1.GameSession = new GameSession(selectedMap, Game1.NetLobbyScreen.SelectedMode);
|
||||
Game1.GameSession.StartShift(Game1.NetLobbyScreen.GameDuration, Game1.NetLobbyScreen.LevelSeed);
|
||||
//EventManager.SelectEvent(Game1.netLobbyScreen.SelectedEvent);
|
||||
|
||||
|
||||
List<CharacterInfo> characterInfos = new List<CharacterInfo>();
|
||||
|
||||
foreach (Client client in connectedClients)
|
||||
{
|
||||
client.inGame = true;
|
||||
@@ -302,10 +304,21 @@ namespace Subsurface.Networking
|
||||
{
|
||||
client.characterInfo = new CharacterInfo("Content/Characters/Human/human.xml", client.name);
|
||||
}
|
||||
characterInfos.Add(client.characterInfo);
|
||||
|
||||
client.character = new Character(client.characterInfo, (spawnPoint == null) ? Vector2.Zero : spawnPoint.SimPosition, true);
|
||||
//client.character = new Character(client.characterInfo, (spawnPoint == null) ? Vector2.Zero : spawnPoint.SimPosition, true);
|
||||
}
|
||||
|
||||
WayPoint[] assignedWayPoints = WayPoint.SelectCrewSpawnPoints(characterInfos);
|
||||
|
||||
for (int i = 0; i < connectedClients.Count; i++ )
|
||||
{
|
||||
connectedClients[i].character = new Character(
|
||||
connectedClients[i].characterInfo, assignedWayPoints[i], true);
|
||||
connectedClients[i].character.GiveJobItems();
|
||||
}
|
||||
|
||||
//todo: fix
|
||||
if (myClient != null)
|
||||
{
|
||||
WayPoint spawnPoint = WayPoint.GetRandom(SpawnType.Human);
|
||||
@@ -313,37 +326,38 @@ namespace Subsurface.Networking
|
||||
myClient.character = new Character(ch, (spawnPoint == null) ? Vector2.Zero : spawnPoint.SimPosition);
|
||||
}
|
||||
|
||||
//foreach (Client client in connectedClients)
|
||||
//{
|
||||
NetOutgoingMessage msg = Server.CreateMessage();
|
||||
msg.Write((byte)PacketTypes.StartGame);
|
||||
|
||||
msg.Write(seed);
|
||||
|
||||
msg.Write(Game1.NetLobbyScreen.LevelSeed);
|
||||
|
||||
msg.Write(Game1.NetLobbyScreen.SelectedMap.Name);
|
||||
msg.Write(Game1.NetLobbyScreen.SelectedMap.Hash.MD5Hash);
|
||||
|
||||
msg.Write(Game1.NetLobbyScreen.GameDuration.TotalMinutes);
|
||||
|
||||
//WriteCharacterData(msg, client.name, client.character);
|
||||
|
||||
msg.Write((myClient == null) ? connectedClients.Count : connectedClients.Count+1);
|
||||
foreach (Client client in connectedClients)
|
||||
{
|
||||
NetOutgoingMessage msg = Server.CreateMessage();
|
||||
msg.Write((byte)PacketTypes.StartGame);
|
||||
|
||||
msg.Write(seed);
|
||||
|
||||
msg.Write(Game1.NetLobbyScreen.LevelSeed);
|
||||
|
||||
msg.Write(Game1.NetLobbyScreen.SelectedMap.Name);
|
||||
msg.Write(Game1.NetLobbyScreen.SelectedMap.Hash.MD5Hash);
|
||||
|
||||
msg.Write(Game1.NetLobbyScreen.GameDuration.TotalMinutes);
|
||||
|
||||
//if (otherClient == client) continue;
|
||||
msg.Write(client.ID);
|
||||
WriteCharacterData(msg, client.name, client.character);
|
||||
|
||||
msg.Write((myClient == null) ? connectedClients.Count - 1 : connectedClients.Count);
|
||||
foreach (Client otherClient in connectedClients)
|
||||
{
|
||||
if (otherClient == client) continue;
|
||||
WriteCharacterData(msg, otherClient.name, otherClient.character);
|
||||
}
|
||||
|
||||
if (myClient!=null)
|
||||
{
|
||||
WriteCharacterData(msg, myClient.name, myClient.character);
|
||||
}
|
||||
|
||||
Server.SendMessage(msg, client.Connection, NetDeliveryMethod.ReliableUnordered, 0);
|
||||
}
|
||||
|
||||
if (myClient!=null)
|
||||
{
|
||||
WriteCharacterData(msg, myClient.name, myClient.character);
|
||||
}
|
||||
|
||||
SendMessage(msg, NetDeliveryMethod.ReliableUnordered, null);
|
||||
//}
|
||||
|
||||
gameStarted = true;
|
||||
|
||||
Game1.GameScreen.Cam.TargetPos = Vector2.Zero;
|
||||
@@ -580,7 +594,7 @@ namespace Subsurface.Networking
|
||||
//if there's enough crew members assigned to the job already, continue
|
||||
if (assignedClientCount[jobIndex] >= JobPrefab.List[jobIndex].MaxNumber) continue;
|
||||
|
||||
unassigned[i].assignedJob = JobPrefab.List[i];
|
||||
unassigned[i].assignedJob = JobPrefab.List[jobIndex];
|
||||
|
||||
assignedClientCount[jobIndex]++;
|
||||
unassigned.RemoveAt(i);
|
||||
|
||||
@@ -103,11 +103,12 @@ namespace Subsurface.Networking
|
||||
DebugConsole.ThrowError("Received invalid network message");
|
||||
return false;
|
||||
}
|
||||
|
||||
//288=id, 280=char
|
||||
Entity e = Entity.FindEntityByID(id);
|
||||
if (e == null)
|
||||
{
|
||||
//DebugConsole.ThrowError("Couldn't find an entity matching the ID ''" + id + "''");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,13 +28,16 @@ namespace Subsurface.Networking
|
||||
|
||||
class NetworkMember
|
||||
{
|
||||
protected static Color[] messageColor = { Color.Black, Color.DarkRed, Color.DarkBlue, Color.DarkGreen };
|
||||
protected static Color[] messageColor = { Color.White, Color.Red, Color.LightBlue, Color.LightGreen };
|
||||
|
||||
protected string name;
|
||||
|
||||
protected TimeSpan updateInterval;
|
||||
protected DateTime updateTimer;
|
||||
|
||||
protected GUIFrame inGameHUD;
|
||||
protected GUIListBox chatBox;
|
||||
|
||||
protected bool gameStarted;
|
||||
|
||||
public string Name
|
||||
@@ -46,11 +49,56 @@ namespace Subsurface.Networking
|
||||
name = value;
|
||||
}
|
||||
}
|
||||
|
||||
public GUIFrame InGameHUD
|
||||
{
|
||||
get { return inGameHUD; }
|
||||
}
|
||||
|
||||
public NetworkMember()
|
||||
{
|
||||
inGameHUD = new GUIFrame(new Rectangle(0,0,0,0), null, null);
|
||||
|
||||
int width = 350, height = 100;
|
||||
chatBox = new GUIListBox(new Rectangle(
|
||||
Game1.GraphicsWidth - 20 - width,
|
||||
Game1.GraphicsHeight - 40 - 25 - height,
|
||||
width, height),
|
||||
Color.White * 0.5f, GUI.style, inGameHUD);
|
||||
|
||||
var textBox = new GUITextBox(
|
||||
new Rectangle(chatBox.Rect.X, chatBox.Rect.Y + chatBox.Rect.Height + 20, chatBox.Rect.Width, 25),
|
||||
Color.White * 0.5f, Color.Black, Alignment.TopLeft, Alignment.Left, GUI.style, inGameHUD);
|
||||
textBox.OnEnter = EnterChatMessage;
|
||||
}
|
||||
|
||||
|
||||
public bool EnterChatMessage(GUITextBox textBox, string message)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(message)) return false;
|
||||
|
||||
SendChatMessage(Game1.NetworkMember.Name + ": " + message);
|
||||
|
||||
textBox.Deselect();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void AddChatMessage(string message, ChatMessageType messageType)
|
||||
{
|
||||
Game1.NetLobbyScreen.NewChatMessage(message, messageColor[(int)messageType]);
|
||||
if (Game1.GameSession != null) Game1.GameSession.NewChatMessage(message, messageColor[(int)messageType]);
|
||||
|
||||
GUITextBlock msg = new GUITextBlock(new Rectangle(0, 0, 0, 20), message,
|
||||
((chatBox.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f, messageColor[(int)messageType],
|
||||
Alignment.Left, null, null, true);
|
||||
|
||||
msg.Padding = new Vector4(20.0f, 0, 0, 0);
|
||||
chatBox.AddChild(msg);
|
||||
|
||||
while (chatBox.CountChildren > 20)
|
||||
{
|
||||
chatBox.RemoveChild(chatBox.children[0]);
|
||||
}
|
||||
|
||||
GUI.PlayMessageSound();
|
||||
}
|
||||
|
||||
@@ -198,22 +198,21 @@ namespace Subsurface
|
||||
hireList.ClearChildren();
|
||||
foreach (CharacterInfo c in gameMode.hireManager.availableCharacters)
|
||||
{
|
||||
GUIFrame frame = new GUIFrame(
|
||||
new Rectangle(0, 0, 0, 25), Color.White, Alignment.Left, null, hireList);
|
||||
frame.UserData = c;
|
||||
frame.Padding = new Vector4(10.0f, 0.0f, 10.0f, 0.0f);
|
||||
//GUIFrame frame = new GUIFrame(
|
||||
// new Rectangle(0, 0, 0, 25), Color.Transparent, null, hireList);
|
||||
//frame.UserData = c;
|
||||
//frame.Padding = new Vector4(10.0f, 0.0f, 10.0f, 0.0f);
|
||||
|
||||
GUITextBlock textBlock = new GUITextBlock(
|
||||
new Rectangle(0, 0, 0, 25),
|
||||
c.Name + " (" + c.Job.Name + ")",
|
||||
Color.Transparent, Color.Black,
|
||||
Alignment.Left, null, frame);
|
||||
c.Name + " (" + c.Job.Name + ")", GUI.style, hireList);
|
||||
textBlock.UserData = c;
|
||||
|
||||
textBlock = new GUITextBlock(
|
||||
new Rectangle(0, 0, 0, 25),
|
||||
c.Salary.ToString(),
|
||||
Color.Transparent, Color.Black,
|
||||
Alignment.Right, null, frame);
|
||||
null, null,
|
||||
Alignment.TopRight, GUI.style, textBlock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,7 +256,7 @@ namespace Subsurface
|
||||
|
||||
spriteBatch.End();
|
||||
|
||||
if (characterList.SelectedData != null)
|
||||
if (characterList.SelectedData != null && selectedRightPanel == (int)PanelTab.Crew)
|
||||
{
|
||||
if (previewCharacter != null)
|
||||
{
|
||||
|
||||
@@ -222,16 +222,18 @@ namespace Subsurface
|
||||
if (string.IsNullOrEmpty(ipBox.Text)) return false;
|
||||
|
||||
Game1.NetworkMember = new GameClient(nameBox.Text);
|
||||
if (Game1.Client.ConnectToServer(ipBox.Text))
|
||||
{
|
||||
Game1.NetLobbyScreen.Select();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Game1.NetworkMember = null;
|
||||
return false;
|
||||
}
|
||||
Game1.Client.ConnectToServer(ipBox.Text);
|
||||
|
||||
return true;
|
||||
//{
|
||||
// Game1.NetLobbyScreen.Select();
|
||||
// return true;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// Game1.NetworkMember = null;
|
||||
// return false;
|
||||
//}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ namespace Subsurface
|
||||
//int oldMapIndex = 0;
|
||||
//if (mapList != null && mapList.SelectedData != null) oldMapIndex = mapList.SelectedIndex;
|
||||
|
||||
new GUITextBlock(new Rectangle(0, 30, 0, 30), "Selected submarine:", null, null, Alignment.Left, null, infoFrame);
|
||||
new GUITextBlock(new Rectangle(0, 30, 0, 30), "Selected submarine:", GUI.style, infoFrame);
|
||||
subList = new GUIListBox(new Rectangle(0, 60, 200, 200), Color.White, GUI.style, infoFrame);
|
||||
subList.OnSelected = SelectMap;
|
||||
subList.Enabled = (Game1.Server != null);
|
||||
@@ -184,7 +184,7 @@ namespace Subsurface
|
||||
return;
|
||||
}
|
||||
|
||||
new GUITextBlock(new Rectangle(220, 30, 0, 30), "Selected game mode: ", null, null, Alignment.Left, GUI.style, infoFrame);
|
||||
new GUITextBlock(new Rectangle(220, 30, 0, 30), "Selected game mode: ", GUI.style, infoFrame);
|
||||
modeList = new GUIListBox(new Rectangle(220, 60, 200, 200), GUI.style, infoFrame);
|
||||
modeList.Enabled = (Game1.Server != null);
|
||||
//modeList.OnSelected = new GUIListBox.OnSelectedHandler(SelectEvent);
|
||||
@@ -202,15 +202,14 @@ namespace Subsurface
|
||||
textBlock.UserData = mode;
|
||||
}
|
||||
|
||||
GUITextBlock durationText = new GUITextBlock(new Rectangle((int)(modeList.Rect.Right + 20 - 100), 30, 100, 20),
|
||||
GUITextBlock durationText = new GUITextBlock(new Rectangle((int)(modeList.Rect.Right + 20 - 80), 30, 100, 20),
|
||||
"Game duration: ", GUI.style, Alignment.Left, Alignment.TopLeft, infoFrame);
|
||||
durationText.TextGetter = DurationText;
|
||||
|
||||
durationBar = new GUIScrollBar(new Rectangle((int)(modeList.Rect.Right + 20 - 100), 60, 180, 20),
|
||||
durationBar = new GUIScrollBar(new Rectangle((int)(modeList.Rect.Right + 20 - 80), 60, 180, 20),
|
||||
GUI.style, 0.1f, infoFrame);
|
||||
durationBar.BarSize = 0.1f;
|
||||
durationBar.Enabled = (Game1.Server != null);
|
||||
|
||||
durationBar.Enabled = (Game1.Server != null);
|
||||
|
||||
new GUITextBlock(new Rectangle((int)(modeList.Rect.Right + 20 - 80), 100, 100, 20),
|
||||
"Level Seed: ", GUI.style, Alignment.Left, Alignment.TopLeft, infoFrame);
|
||||
@@ -236,20 +235,24 @@ namespace Subsurface
|
||||
else
|
||||
{
|
||||
int x = playerFrame.Rect.Width / 2;
|
||||
GUITextBox playerName = new GUITextBox(new Rectangle(x, 0, 0, 20),
|
||||
|
||||
|
||||
new GUITextBlock(new Rectangle(x, 0, 200, 30), "Name: ", GUI.style, playerFrame);
|
||||
|
||||
|
||||
GUITextBox playerName = new GUITextBox(new Rectangle(x, 30, 0, 20),
|
||||
Alignment.TopLeft, GUI.style, playerFrame);
|
||||
playerName.Text = Game1.Client.CharacterInfo.Name;
|
||||
playerName.OnEnter += ChangeCharacterName;
|
||||
|
||||
new GUITextBlock(new Rectangle(x,40,200, 30), "Gender: ", Color.Transparent, Color.Black,
|
||||
Alignment.TopLeft, GUI.style, playerFrame);
|
||||
new GUITextBlock(new Rectangle(x,70,200, 30), "Gender: ", GUI.style, playerFrame);
|
||||
|
||||
GUIButton maleButton = new GUIButton(new Rectangle(x+70,50,70,20), "Male",
|
||||
GUIButton maleButton = new GUIButton(new Rectangle(x, 100, 70, 20), "Male",
|
||||
Alignment.TopLeft, GUI.style,playerFrame);
|
||||
maleButton.UserData = Gender.Male;
|
||||
maleButton.OnClicked += SwitchGender;
|
||||
|
||||
GUIButton femaleButton = new GUIButton(new Rectangle(x+150, 50, 70, 20), "Female",
|
||||
GUIButton femaleButton = new GUIButton(new Rectangle(x+150, 100, 70, 20), "Female",
|
||||
Alignment.TopLeft, GUI.style, playerFrame);
|
||||
femaleButton.UserData = Gender.Female;
|
||||
femaleButton.OnClicked += SwitchGender;
|
||||
@@ -311,6 +314,14 @@ namespace Subsurface
|
||||
playerList.RemoveChild(playerList.GetChild(client));
|
||||
}
|
||||
|
||||
public void ClearPlayers()
|
||||
{
|
||||
for (int i = 1; i<playerList.CountChildren; i++)
|
||||
{
|
||||
playerList.RemoveChild(playerList.children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
@@ -406,6 +417,7 @@ namespace Subsurface
|
||||
Vector2 pos = new Vector2(1000.0f, 1000.0f);
|
||||
|
||||
Character character = new Character(Game1.Client.CharacterInfo, pos);
|
||||
character.ID = int.MaxValue;
|
||||
|
||||
Game1.Client.Character = character;
|
||||
|
||||
@@ -422,6 +434,7 @@ namespace Subsurface
|
||||
{
|
||||
pos = ConvertUnits.ToDisplayUnits(pos);
|
||||
previewHull = new Hull(new Rectangle((int)pos.X - 100, (int)pos.Y + 100, 200, 200));
|
||||
previewHull.ID = int.MaxValue - 2;
|
||||
}
|
||||
|
||||
Physics.Alpha = 1.0f;
|
||||
@@ -501,11 +514,12 @@ namespace Subsurface
|
||||
private void UpdateJobPreferences(GUIListBox listBox)
|
||||
{
|
||||
listBox.Deselect();
|
||||
for (int i = 0; i<listBox.children.Count; i++)
|
||||
for (int i = 1; i<listBox.children.Count; i++)
|
||||
{
|
||||
float a = (float)i/listBox.children.Count;
|
||||
Color color = new Color(a, 1.0f - a, 0.5f, 1.0f);
|
||||
|
||||
float a = (float)(i - 1) / 3.0f;
|
||||
a = Math.Min(a, 3);
|
||||
Color color = new Color(1.0f-a, (1.0f - a)*0.6f, 0.0f, 0.3f);
|
||||
|
||||
listBox.children[i].Color = color;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
<Compile Include="Characters\Jobs\JobPrefab.cs" />
|
||||
<Compile Include="Characters\AI\SteeringManager.cs" />
|
||||
<Compile Include="Characters\AI\SteeringPath.cs" />
|
||||
<Compile Include="CoroutineManager.cs" />
|
||||
<Compile Include="Rand.cs" />
|
||||
<Compile Include="Events\PropertyTask.cs" />
|
||||
<Compile Include="Events\RepairTask.cs" />
|
||||
@@ -362,6 +363,15 @@
|
||||
<Content Include="Content\Items\Pump\pump.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\Map\iceCrack.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\Map\iceCraters.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\Map\iceSurface.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\UI\caret.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user