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)
|
public Character(CharacterInfo characterInfo, Vector2 position, bool isNetworkPlayer = false)
|
||||||
: this(characterInfo.File, position, characterInfo, isNetworkPlayer)
|
: this(characterInfo.File, position, characterInfo, isNetworkPlayer)
|
||||||
{
|
{
|
||||||
@@ -351,7 +357,6 @@ namespace Subsurface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AnimController.FindHull();
|
AnimController.FindHull();
|
||||||
|
|
||||||
//if (info.ID >= 0)
|
//if (info.ID >= 0)
|
||||||
@@ -362,6 +367,24 @@ namespace Subsurface
|
|||||||
CharacterList.Add(this);
|
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)
|
public void Control(float deltaTime, Camera cam, bool forcePick = false)
|
||||||
{
|
{
|
||||||
if (isDead) return;
|
if (isDead) return;
|
||||||
@@ -612,15 +635,17 @@ namespace Subsurface
|
|||||||
spriteBatch.DrawString(GUI.font, Info.Name, namePos, Color.White);
|
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;
|
if (this == Character.controlled) return;
|
||||||
|
|
||||||
Vector2 healthBarPos = new Vector2(Position.X - 50, -Position.Y - 50.0f);
|
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-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);
|
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),
|
//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.limbs[0].SimPosition.X, animController.limbs[0].SimPosition.Y) +
|
||||||
// ConvertUnits.ToDisplayUnits(animController.targetMovement.X, animController.targetMovement.Y), Color.Green);
|
// ConvertUnits.ToDisplayUnits(animController.targetMovement.X, animController.targetMovement.Y), Color.Green);
|
||||||
@@ -1038,6 +1063,8 @@ namespace Subsurface
|
|||||||
|
|
||||||
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)
|
if (aiTarget != null)
|
||||||
aiTarget.Remove();
|
aiTarget.Remove();
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ namespace Subsurface
|
|||||||
|
|
||||||
public int Salary;
|
public int Salary;
|
||||||
|
|
||||||
|
public bool StartItemsGiven;
|
||||||
|
|
||||||
//public string GenderString()
|
//public string GenderString()
|
||||||
//{
|
//{
|
||||||
// return gender.ToString();
|
// return gender.ToString();
|
||||||
@@ -96,11 +98,10 @@ namespace Subsurface
|
|||||||
string genderStr = ToolBox.GetAttributeString(element, "gender", "male").ToLower();
|
string genderStr = ToolBox.GetAttributeString(element, "gender", "male").ToLower();
|
||||||
Gender = (genderStr == "male") ? Gender.Male : Gender.Female;
|
Gender = (genderStr == "male") ? Gender.Male : Gender.Female;
|
||||||
|
|
||||||
File = ToolBox.GetAttributeString(element, "file", "");
|
File = ToolBox.GetAttributeString(element, "file", "");
|
||||||
|
Salary = ToolBox.GetAttributeInt(element, "salary", 1000);
|
||||||
Salary = ToolBox.GetAttributeInt(element, "salary", 1000);
|
HeadSpriteId = ToolBox.GetAttributeInt(element, "headspriteid", 1);
|
||||||
|
StartItemsGiven = ToolBox.GetAttributeBool(element, "startitemsgiven", false);
|
||||||
HeadSpriteId = ToolBox.GetAttributeInt(element, "headspriteid", 1);
|
|
||||||
|
|
||||||
foreach (XElement subElement in element.Elements())
|
foreach (XElement subElement in element.Elements())
|
||||||
{
|
{
|
||||||
@@ -120,7 +121,8 @@ namespace Subsurface
|
|||||||
new XAttribute("file", File),
|
new XAttribute("file", File),
|
||||||
new XAttribute("gender", Gender == Gender.Male ? "male" : "female"),
|
new XAttribute("gender", Gender == Gender.Male ? "male" : "female"),
|
||||||
new XAttribute("salary", Salary),
|
new XAttribute("salary", Salary),
|
||||||
new XAttribute("headspriteid", HeadSpriteId));
|
new XAttribute("headspriteid", HeadSpriteId),
|
||||||
|
new XAttribute("startitemsgiven", StartItemsGiven));
|
||||||
|
|
||||||
Job.Save(charElement);
|
Job.Save(charElement);
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,16 @@ namespace Subsurface
|
|||||||
get { return prefab.Description; }
|
get { return prefab.Description; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JobPrefab Prefab
|
||||||
|
{
|
||||||
|
get { return prefab; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<string> SpawnItemNames
|
||||||
|
{
|
||||||
|
get { return prefab.ItemNames; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public Job(JobPrefab jobPrefab)
|
public Job(JobPrefab jobPrefab)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
foreach (XElement subElement in element.Elements())
|
foreach (XElement subElement in element.Elements())
|
||||||
{
|
{
|
||||||
switch (subElement.Name.ToString())
|
switch (subElement.Name.ToString().ToLower())
|
||||||
{
|
{
|
||||||
case "item":
|
case "item":
|
||||||
string itemName = ToolBox.GetAttributeString(subElement, "name", "");
|
string itemName = ToolBox.GetAttributeString(subElement, "name", "");
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<Jobs>
|
<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"/>
|
<Item name="ID Card"/>
|
||||||
</Captain>
|
</Captain>
|
||||||
|
|
||||||
@@ -15,4 +15,10 @@
|
|||||||
<Item name="Wrench"/>
|
<Item name="Wrench"/>
|
||||||
<Item name="Screwdriver"/>
|
<Item name="Screwdriver"/>
|
||||||
</Mechanic>
|
</Mechanic>
|
||||||
|
|
||||||
|
<Assistant allowalways="true">
|
||||||
|
<Item name="ID Card"/>
|
||||||
|
<Item name="Wrench"/>
|
||||||
|
<Item name="Screwdriver"/>
|
||||||
|
</Assistant>
|
||||||
</Jobs>
|
</Jobs>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 112 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.6 MiB |
@@ -16,17 +16,18 @@
|
|||||||
</GUIFrame>
|
</GUIFrame>
|
||||||
|
|
||||||
<GUIButton
|
<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"
|
textcolor="1.0, 1.0, 1.0, 1.0"
|
||||||
|
|
||||||
hovercolor="0.88, 0.19, 0.16, 1.0"
|
hovercolor="1.0, 0.57, 0.31, 1.0"
|
||||||
selectedcolor="0.8, 0.8, 0.8, 1.0"/>
|
selectedcolor="1.0, 0.0, 0.0, 1.0"/>
|
||||||
|
|
||||||
<GUITextBlock
|
<GUITextBlock
|
||||||
textcolor="1.0, 1.0, 1.0, 1.0"
|
textcolor="1.0, 1.0, 1.0, 1.0"
|
||||||
hovercolor="1.0, 1.0, 1.0, 0.3"
|
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
|
<GUIListBox
|
||||||
color="0.5, 0.5, 0.5, 1.0"
|
color="0.5, 0.5, 0.5, 1.0"
|
||||||
@@ -46,11 +47,26 @@
|
|||||||
</GUIScrollBar>
|
</GUIScrollBar>
|
||||||
|
|
||||||
<GUITextBox
|
<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">
|
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"/>
|
<Sprite texture="Content\UI\uiBackground.png" size="0.0, 1.0" sourcerect ="0.0, 0.0, 0.0, 90.0"/>
|
||||||
</GUITextBox>
|
</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>
|
</style>
|
||||||
@@ -5,13 +5,13 @@
|
|||||||
commonness="10"
|
commonness="10"
|
||||||
difficulty="30"
|
difficulty="30"
|
||||||
minamount="2" maxamount="3"
|
minamount="2" maxamount="3"
|
||||||
starttimemin="5" starttimemax="10"
|
starttimemin="15" starttimemax="20"
|
||||||
musictype="monster"/>
|
musictype="monster"/>
|
||||||
|
|
||||||
<MonsterEvent name="Under attack" description=""
|
<MonsterEvent name="Under attack" description=""
|
||||||
characterfile="Content/Characters/TigerThresher/tigerthresher.xml"
|
characterfile="Content/Characters/TigerThresher/tigerthresher.xml"
|
||||||
commonness="10"
|
commonness="10"
|
||||||
difficulty="50"
|
difficulty="50"
|
||||||
starttimemin="5" starttimemax="10"
|
starttimemin="15" starttimemax="20"
|
||||||
musictype="monster"/>
|
musictype="monster"/>
|
||||||
</Randomevents>
|
</Randomevents>
|
||||||
@@ -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);
|
ScriptedEvent scriptedEvent = ScriptedEvent.LoadRandom(level.Seed);
|
||||||
AddTask(new ScriptedTask(scriptedEvent));
|
AddTask(new ScriptedTask(scriptedEvent));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TaskStarted(Task task)
|
public void TaskStarted(Task task)
|
||||||
|
|||||||
@@ -21,17 +21,17 @@ namespace Subsurface
|
|||||||
this.Buttons[0].OnClicked = Close;
|
this.Buttons[0].OnClicked = Close;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GUIMessageBox(string header, string text, string[] buttons, Alignment textAlignment = (Alignment.Left | Alignment.Top))
|
public GUIMessageBox(string header, string text, string[] buttons, Alignment textAlignment = Alignment.TopLeft)
|
||||||
: base(new Rectangle(Game1.GraphicsWidth / 2 - DefaultWidth / 2, Game1.GraphicsHeight / 2 - DefaultHeight / 2, DefaultWidth, DefaultHeight),
|
: base(new Rectangle(0,0, DefaultWidth, DefaultHeight),
|
||||||
null, Alignment.CenterX, GUI.style, null)
|
null, Alignment.Center, GUI.style, null)
|
||||||
{
|
{
|
||||||
//Padding = GUI.style.smallPadding;
|
//Padding = GUI.style.smallPadding;
|
||||||
|
|
||||||
if (buttons == null || buttons.Length == 0)
|
//if (buttons == null || buttons.Length == 0)
|
||||||
{
|
//{
|
||||||
DebugConsole.ThrowError("Creating a message box with no buttons isn't allowed");
|
// DebugConsole.ThrowError("Creating a message box with no buttons isn't allowed");
|
||||||
return;
|
// return;
|
||||||
}
|
//}
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, 0, 0, 30), header, Color.Transparent, Color.White, textAlignment, GUI.style, this, true);
|
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);
|
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)
|
: this (rect, text, null, null, alignment, textAlignment, style, parent, wrap)
|
||||||
{
|
{
|
||||||
//hoverColor = style.hoverColor;
|
//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)
|
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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -196,11 +196,16 @@ namespace Subsurface
|
|||||||
|
|
||||||
GUI.Update((float)deltaTime);
|
GUI.Update((float)deltaTime);
|
||||||
|
|
||||||
if (NetworkMember != null) NetworkMember.Update();
|
if (NetworkMember != null)
|
||||||
|
{
|
||||||
|
NetworkMember.Update();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NetworkEvent.events.Clear();
|
NetworkEvent.events.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CoroutineManager.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -117,17 +117,26 @@ namespace Subsurface
|
|||||||
listBox.ClearChildren();
|
listBox.ClearChildren();
|
||||||
characters.Clear();
|
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);
|
WayPoint randomWayPoint = WayPoint.GetRandom(SpawnType.Human);
|
||||||
Vector2 position = (randomWayPoint == null) ? Vector2.Zero : randomWayPoint.SimPosition;
|
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;
|
Character.Controlled = character;
|
||||||
|
|
||||||
|
if (!character.Info.StartItemsGiven)
|
||||||
|
{
|
||||||
|
character.GiveJobItems();
|
||||||
|
character.Info.StartItemsGiven = true;
|
||||||
|
}
|
||||||
|
|
||||||
AddCharacter(character);
|
AddCharacter(character);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (characters.Count>0) SelectCharacter(characters[0]);
|
if (characters.Count > 0) SelectCharacter(characters[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EndShift()
|
public void EndShift()
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
private GUIFrame guiRoot;
|
private GUIFrame guiRoot;
|
||||||
|
|
||||||
private GUIListBox chatBox;
|
//private GUIListBox chatBox;
|
||||||
private GUITextBox textBox;
|
private GUITextBox textBox;
|
||||||
|
|
||||||
private string savePath;
|
private string savePath;
|
||||||
@@ -59,20 +59,20 @@ namespace Subsurface
|
|||||||
|
|
||||||
map = new Map(Rand.Int(), 500);
|
map = new Map(Rand.Int(), 500);
|
||||||
|
|
||||||
int width = 350, height = 100;
|
//int width = 350, height = 100;
|
||||||
if (Game1.NetworkMember!=null)
|
//if (Game1.NetworkMember!=null)
|
||||||
{
|
//{
|
||||||
chatBox = new GUIListBox(new Rectangle(
|
// chatBox = new GUIListBox(new Rectangle(
|
||||||
Game1.GraphicsWidth - 20 - width,
|
// Game1.GraphicsWidth - 20 - width,
|
||||||
Game1.GraphicsHeight - 40 - 25 - height,
|
// Game1.GraphicsHeight - 40 - 25 - height,
|
||||||
width, height),
|
// width, height),
|
||||||
Color.White * 0.5f, GUI.style, guiRoot);
|
// Color.White * 0.5f, GUI.style, guiRoot);
|
||||||
|
|
||||||
textBox = new GUITextBox(
|
// textBox = new GUITextBox(
|
||||||
new Rectangle(chatBox.Rect.X, chatBox.Rect.Y + chatBox.Rect.Height + 20, chatBox.Rect.Width, 25),
|
// 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);
|
// Color.White * 0.5f, Color.Black, Alignment.Bottom, Alignment.Left, GUI.style, guiRoot);
|
||||||
textBox.OnEnter = EnterChatMessage;
|
// textBox.OnEnter = EnterChatMessage;
|
||||||
}
|
//}
|
||||||
|
|
||||||
this.gameMode = gameMode;
|
this.gameMode = gameMode;
|
||||||
//if (gameMode != null && !gameMode.IsSinglePlayer)
|
//if (gameMode != null && !gameMode.IsSinglePlayer)
|
||||||
@@ -124,7 +124,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
this.level = level;
|
this.level = level;
|
||||||
|
|
||||||
if (Submarine.Loaded!=submarine) submarine.Load();
|
if (Submarine.Loaded != submarine) submarine.Load();
|
||||||
|
|
||||||
if (gameMode!=null) gameMode.Start(duration);
|
if (gameMode!=null) gameMode.Start(duration);
|
||||||
|
|
||||||
@@ -172,34 +172,35 @@ namespace Subsurface
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool EnterChatMessage(GUITextBox textBox, string message)
|
//public bool EnterChatMessage(GUITextBox textBox, string message)
|
||||||
{
|
//{
|
||||||
if (string.IsNullOrWhiteSpace(message)) return false;
|
// if (string.IsNullOrWhiteSpace(message)) return false;
|
||||||
|
|
||||||
else if (Game1.NetworkMember != null)
|
// else if (Game1.NetworkMember != null)
|
||||||
{
|
// {
|
||||||
Game1.NetworkMember.SendChatMessage(Game1.NetworkMember.Name + ": " + message);
|
// Game1.NetworkMember.SendChatMessage(Game1.NetworkMember.Name + ": " + message);
|
||||||
}
|
// }
|
||||||
|
|
||||||
textBox.Deselect();
|
// textBox.Deselect();
|
||||||
|
|
||||||
return true;
|
// return true;
|
||||||
}
|
//}
|
||||||
|
|
||||||
public void NewChatMessage(string text, Color color)
|
//public void NewChatMessage(string text, Color color)
|
||||||
{
|
//{
|
||||||
GUITextBlock msg = new GUITextBlock(new Rectangle(0, 0, 0, 20), text,
|
// 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);
|
|
||||||
|
|
||||||
msg.Padding = new Vector4(20.0f, 0, 0, 0);
|
// ((chatBox.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f, color,
|
||||||
chatBox.AddChild(msg);
|
// Alignment.Left, null, null, true);
|
||||||
|
|
||||||
while (chatBox.CountChildren > 20)
|
// msg.Padding = new Vector4(20.0f, 0, 0, 0);
|
||||||
{
|
// chatBox.AddChild(msg);
|
||||||
chatBox.RemoveChild(chatBox.children.First());
|
|
||||||
}
|
// while (chatBox.CountChildren > 20)
|
||||||
}
|
// {
|
||||||
|
// chatBox.RemoveChild(chatBox.children.First());
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
public void Update(float deltaTime)
|
public void Update(float deltaTime)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ namespace Subsurface
|
|||||||
|
|
||||||
private GUIButton endShiftButton;
|
private GUIButton endShiftButton;
|
||||||
|
|
||||||
private int day;
|
//private int day;
|
||||||
|
|
||||||
public int Day
|
//public int Day
|
||||||
{
|
//{
|
||||||
get { return day; }
|
// get { return day; }
|
||||||
}
|
//}
|
||||||
|
|
||||||
bool crewDead;
|
bool crewDead;
|
||||||
private float endTimer;
|
private float endTimer;
|
||||||
@@ -36,13 +36,13 @@ namespace Subsurface
|
|||||||
|
|
||||||
hireManager.GenerateCharacters("Content/Characters/Human/human.xml", 10);
|
hireManager.GenerateCharacters("Content/Characters/Human/human.xml", 10);
|
||||||
|
|
||||||
day = 1;
|
//day = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SinglePlayerMode(XElement element)
|
public SinglePlayerMode(XElement element)
|
||||||
: this(GameModePreset.list.Find(gm => gm.Name == "Single Player"))
|
: 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())
|
foreach (XElement subElement in element.Elements())
|
||||||
{
|
{
|
||||||
@@ -145,15 +145,17 @@ namespace Subsurface
|
|||||||
sb.Append("No casualties!");
|
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();
|
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("");
|
Game1.GameSession.EndShift("");
|
||||||
@@ -163,7 +165,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
public void Save(XElement element)
|
public void Save(XElement element)
|
||||||
{
|
{
|
||||||
element.Add(new XAttribute("day", day));
|
//element.Add(new XAttribute("day", day));
|
||||||
|
|
||||||
crewManager.Save(element);
|
crewManager.Save(element);
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ namespace Subsurface
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// If there is room, puts the item in the inventory and returns true, otherwise returns false
|
/// If there is room, puts the item in the inventory and returns true, otherwise returns false
|
||||||
/// </summary>
|
/// </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++)
|
for (int i = 0; i < capacity; i++)
|
||||||
{
|
{
|
||||||
@@ -54,7 +54,7 @@ namespace Subsurface
|
|||||||
if (items[i] == item) return true;
|
if (items[i] == item) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usedSlots.HasFlag(LimbSlot.Any))
|
if (allowedSlots.HasFlag(LimbSlot.Any))
|
||||||
{
|
{
|
||||||
for (int i = 0; i < capacity; i++)
|
for (int i = 0; i < capacity; i++)
|
||||||
{
|
{
|
||||||
@@ -68,12 +68,12 @@ namespace Subsurface
|
|||||||
|
|
||||||
for (int i = 0; i < capacity; i++)
|
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++)
|
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);
|
PutItem(item, i, createNetworkEvent);
|
||||||
item.Equip(character);
|
item.Equip(character);
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
guiFrame = new GUIFrame(
|
guiFrame = new GUIFrame(
|
||||||
new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Z, (int)rect.W),
|
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;
|
//guiFrame.Alpha = color.W;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ namespace Subsurface
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual int CanBePut(Item item)
|
public virtual int FindAllowedSlot(Item item)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < capacity; i++)
|
for (int i = 0; i < capacity; i++)
|
||||||
{
|
{
|
||||||
@@ -84,9 +84,9 @@ namespace Subsurface
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// If there is room, puts the item in the inventory and returns true, otherwise returns false
|
/// If there is room, puts the item in the inventory and returns true, otherwise returns false
|
||||||
/// </summary>
|
/// </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;
|
if (slot < 0) return false;
|
||||||
|
|
||||||
PutItem(item, slot, createNetworkEvent);
|
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;
|
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.X = (int)pos.X;
|
||||||
pos.Y = (int)pos.Y;
|
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 + " - "+item.ID, 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, Color.White);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.Condition < 100.0f)
|
if (item.Condition < 100.0f)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace Subsurface
|
|||||||
this.container = container;
|
this.container = container;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int CanBePut(Item item)
|
public override int FindAllowedSlot(Item item)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < capacity; i++)
|
for (int i = 0; i < capacity; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
//give an unique ID
|
//give an unique ID
|
||||||
bool IDfound;
|
bool IDfound;
|
||||||
id = 0;
|
id = 1;//Rand.Int(int.MaxValue);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
id += 1;
|
id += 1;
|
||||||
|
|||||||
+149
-86
@@ -19,6 +19,10 @@ namespace Subsurface
|
|||||||
private int seed;
|
private int seed;
|
||||||
private int size;
|
private int size;
|
||||||
|
|
||||||
|
private Texture2D iceTexture;
|
||||||
|
private Texture2D iceCraters;
|
||||||
|
private Texture2D iceCrack;
|
||||||
|
|
||||||
private Location currentLocation;
|
private Location currentLocation;
|
||||||
private Location selectedLocation;
|
private Location selectedLocation;
|
||||||
|
|
||||||
@@ -34,49 +38,12 @@ namespace Subsurface
|
|||||||
|
|
||||||
connections = new List<LocationConnection>();
|
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();
|
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];
|
currentLocation = locations[locations.Count/2];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,6 +64,12 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
if (edge.point1 == edge.point2) continue;
|
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];
|
Location[] newLocations = new Location[2];
|
||||||
newLocations[0] = locations.Find(l => l.MapPosition == edge.point1 || l.MapPosition == edge.point2);
|
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));
|
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()));
|
connections.Add(new LocationConnection(newLocations[0], newLocations[1], Level.CreateRandom()));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float minDistance = 50.0f;
|
float minDistance = 50.0f;
|
||||||
@@ -124,40 +99,103 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
LocationConnection connection = connections[i];
|
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]);
|
locations.Remove(connection.Locations[0]);
|
||||||
connections.Remove(connection);
|
connections.Remove(connection);
|
||||||
|
|
||||||
foreach (LocationConnection connection2 in connections)
|
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[0] == connection.Locations[0]) connection2.Locations[0] = connection.Locations[1];
|
||||||
if (connection2.Locations[1] == connection.Locations[0]) connection2.Locations[1] = 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)
|
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);
|
Vector2 scale = new Vector2((float)rect.Width/ size, (float)rect.Height/size);
|
||||||
|
|
||||||
float maxDist = 20.0f;
|
float maxDist = 20.0f;
|
||||||
float closestDist = 0.0f;
|
float closestDist = 0.0f;
|
||||||
Location highlightedLocation = null;
|
highlightedLocation = null;
|
||||||
foreach (Location location in locations)
|
for (int i = 0; i < locations.Count;i++ )
|
||||||
{
|
{
|
||||||
Vector2 pos = location.MapPosition * scale;
|
Location location = locations[i];
|
||||||
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X + (int)pos.X, rect.Y + (int)pos.Y, 5, 5), Color.White, true);
|
Vector2 pos = rectCorner + location.MapPosition * scale;
|
||||||
|
|
||||||
if (currentLocation == location)
|
float dist = Vector2.Distance(PlayerInput.MousePosition, new Vector2(pos.X, pos.Y));
|
||||||
{
|
|
||||||
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));
|
|
||||||
if (dist < maxDist && (highlightedLocation == null || dist < closestDist))
|
if (dist < maxDist && (highlightedLocation == null || dist < closestDist))
|
||||||
{
|
{
|
||||||
closestDist = dist;
|
closestDist = dist;
|
||||||
@@ -165,40 +203,18 @@ 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)
|
foreach (LocationConnection connection in connections)
|
||||||
{
|
{
|
||||||
GUI.DrawLine(spriteBatch,
|
Color crackColor = Color.White;
|
||||||
connection.Locations[0].MapPosition * scale + rectCorner,
|
|
||||||
connection.Locations[1].MapPosition * scale + rectCorner, Color.LightGray);
|
|
||||||
|
|
||||||
if (highlightedLocation!=currentLocation &&
|
if (highlightedLocation != currentLocation &&
|
||||||
connection.Locations.Contains(highlightedLocation) && connection.Locations.Contains(currentLocation))
|
connection.Locations.Contains(highlightedLocation) && connection.Locations.Contains(currentLocation))
|
||||||
{
|
{
|
||||||
GUI.DrawLine(spriteBatch,
|
crackColor = Color.Red;
|
||||||
connection.Locations[0].MapPosition * scale + rectCorner +Vector2.One,
|
|
||||||
connection.Locations[1].MapPosition * scale + rectCorner + Vector2.One, Color.White);
|
|
||||||
|
|
||||||
if (PlayerInput.LeftButtonClicked())
|
if (PlayerInput.LeftButtonClicked()&&
|
||||||
if(selectedLocation!=highlightedLocation && highlightedLocation!=null)
|
selectedLocation != highlightedLocation && highlightedLocation != null)
|
||||||
{
|
{
|
||||||
//currentLocation = highlightedLocation;
|
//currentLocation = highlightedLocation;
|
||||||
Game1.LobbyScreen.SelectLocation(highlightedLocation, connection);
|
Game1.LobbyScreen.SelectLocation(highlightedLocation, connection);
|
||||||
@@ -206,14 +222,59 @@ namespace Subsurface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (selectedLocation != currentLocation &&
|
if (selectedLocation != currentLocation &&
|
||||||
(connection.Locations.Contains(selectedLocation) && connection.Locations.Contains(currentLocation)))
|
(connection.Locations.Contains(selectedLocation) && connection.Locations.Contains(currentLocation)))
|
||||||
{
|
{
|
||||||
GUI.DrawLine(spriteBatch,
|
crackColor = Color.Red;
|
||||||
connection.Locations[0].MapPosition * scale + rectCorner + Vector2.One,
|
|
||||||
connection.Locations[1].MapPosition * scale + rectCorner + Vector2.One, Color.White);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
class LocationConnection
|
||||||
{
|
{
|
||||||
Location[] locations;
|
private Location[] locations;
|
||||||
Level level;
|
private Level level;
|
||||||
|
|
||||||
|
public List<Vector2[]> CrackSegments;
|
||||||
|
|
||||||
public Location[] Locations
|
public Location[] Locations
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -820,7 +820,7 @@ namespace Subsurface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ID = 1;
|
//ID = 1;
|
||||||
|
|
||||||
loaded = this;
|
loaded = this;
|
||||||
}
|
}
|
||||||
@@ -839,7 +839,6 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
if (loaded == null) return;
|
if (loaded == null) return;
|
||||||
|
|
||||||
|
|
||||||
loaded.Remove();
|
loaded.Remove();
|
||||||
|
|
||||||
loaded.Clear();
|
loaded.Clear();
|
||||||
|
|||||||
+200
-18
@@ -13,16 +13,35 @@ namespace Subsurface
|
|||||||
public enum SpawnType { None, Human, Enemy };
|
public enum SpawnType { None, Human, Enemy };
|
||||||
class WayPoint : MapEntity
|
class WayPoint : MapEntity
|
||||||
{
|
{
|
||||||
|
public static List<WayPoint> WayPointList = new List<WayPoint>();
|
||||||
|
|
||||||
private SpawnType spawnType;
|
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
|
public SpawnType SpawnType
|
||||||
{
|
{
|
||||||
get { return spawnType; }
|
get { return spawnType; }
|
||||||
set { spawnType = value; }
|
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
|
public override Vector2 SimPosition
|
||||||
{
|
{
|
||||||
get { return ConvertUnits.ToSimUnits(new Vector2(rect.X, rect.Y)); }
|
get { return ConvertUnits.ToSimUnits(new Vector2(rect.X, rect.Y)); }
|
||||||
@@ -32,8 +51,10 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
rect = newRect;
|
rect = newRect;
|
||||||
linkedTo = new ObservableCollection<MapEntity>();
|
linkedTo = new ObservableCollection<MapEntity>();
|
||||||
|
idCardTags = new string[0];
|
||||||
|
|
||||||
mapEntityList.Add(this);
|
mapEntityList.Add(this);
|
||||||
|
WayPointList.Add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Draw(SpriteBatch spriteBatch, bool editing)
|
public override void Draw(SpriteBatch spriteBatch, bool editing)
|
||||||
@@ -54,17 +75,13 @@ namespace Subsurface
|
|||||||
|
|
||||||
public override void DrawEditing(SpriteBatch spriteBatch, Camera cam)
|
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);
|
editingHUD.Update((float)Physics.step);
|
||||||
spriteBatch.DrawString(GUI.font, "Hold space to link to another entity", new Vector2(x, y + 20), Color.Black);
|
editingHUD.Draw(spriteBatch);
|
||||||
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;
|
|
||||||
|
|
||||||
if (!PlayerInput.LeftButtonClicked()) return;
|
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>();
|
List<WayPoint> wayPoints = new List<WayPoint>();
|
||||||
|
|
||||||
foreach (MapEntity e in mapEntityList)
|
foreach (WayPoint wp in WayPointList)
|
||||||
{
|
{
|
||||||
WayPoint wayPoint = e as WayPoint;
|
if (spawnType != SpawnType.None && wp.spawnType != spawnType) continue;
|
||||||
if (wayPoint==null) continue;
|
if (assignedJob != null && wp.assignedJob != assignedJob.Prefab) continue;
|
||||||
|
|
||||||
if (spawnType != SpawnType.None && wayPoint.spawnType != spawnType) continue;
|
wayPoints.Add(wp);
|
||||||
|
|
||||||
wayPoints.Add(wayPoint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wayPoints.Any()) return null;
|
if (!wayPoints.Any()) return null;
|
||||||
@@ -101,6 +205,55 @@ namespace Subsurface
|
|||||||
return wayPoints[Rand.Int(wayPoints.Count())];
|
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)
|
public override XElement Save(XDocument doc)
|
||||||
{
|
{
|
||||||
XElement element = new XElement("WayPoint");
|
XElement element = new XElement("WayPoint");
|
||||||
@@ -110,6 +263,16 @@ namespace Subsurface
|
|||||||
new XAttribute("y", rect.Y),
|
new XAttribute("y", rect.Y),
|
||||||
new XAttribute("spawn", spawnType));
|
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);
|
doc.Root.Add(element);
|
||||||
|
|
||||||
if (linkedTo != null)
|
if (linkedTo != null)
|
||||||
@@ -138,6 +301,18 @@ namespace Subsurface
|
|||||||
w.spawnType = (SpawnType)Enum.Parse(typeof(SpawnType),
|
w.spawnType = (SpawnType)Enum.Parse(typeof(SpawnType),
|
||||||
ToolBox.GetAttributeString(element, "spawn", "None"));
|
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>();
|
w.linkedToID = new List<int>();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (element.Attribute("linkedto" + i) != null)
|
while (element.Attribute("linkedto" + i) != null)
|
||||||
@@ -147,5 +322,12 @@ namespace Subsurface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Remove()
|
||||||
|
{
|
||||||
|
base.Remove();
|
||||||
|
|
||||||
|
WayPointList.Remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,8 +15,16 @@ namespace Subsurface.Networking
|
|||||||
private Character myCharacter;
|
private Character myCharacter;
|
||||||
private CharacterInfo characterInfo;
|
private CharacterInfo characterInfo;
|
||||||
|
|
||||||
|
GUIMessageBox reconnectBox;
|
||||||
|
|
||||||
|
private bool connected;
|
||||||
|
|
||||||
|
private int myID;
|
||||||
|
|
||||||
List<Client> otherClients;
|
List<Client> otherClients;
|
||||||
|
|
||||||
|
private string serverIP;
|
||||||
|
|
||||||
public Character Character
|
public Character Character
|
||||||
{
|
{
|
||||||
get { return myCharacter; }
|
get { return myCharacter; }
|
||||||
@@ -37,8 +45,10 @@ namespace Subsurface.Networking
|
|||||||
otherClients = new List<Client>();
|
otherClients = new List<Client>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ConnectToServer(string hostIP)
|
public void ConnectToServer(string hostIP)
|
||||||
{
|
{
|
||||||
|
serverIP = hostIP;
|
||||||
|
|
||||||
myCharacter = Character.Controlled;
|
myCharacter = Character.Controlled;
|
||||||
|
|
||||||
// Create new instance of configs. Parameter is "application Id". It has to be same on client and server.
|
// 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)
|
catch (ArgumentNullException e)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Couldn't connect to "+hostIP+". Error message: "+e.Message);
|
DebugConsole.ThrowError("Couldn't connect to "+hostIP+". Error message: "+e.Message);
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create timespan of 30ms
|
// Create timespan of 30ms
|
||||||
@@ -78,27 +88,24 @@ namespace Subsurface.Networking
|
|||||||
//update.Elapsed += new System.Timers.ElapsedEventHandler(Update);
|
//update.Elapsed += new System.Timers.ElapsedEventHandler(Update);
|
||||||
|
|
||||||
// Funtion that waits for connection approval info from server
|
// Funtion that waits for connection approval info from server
|
||||||
WaitForStartingInfo();
|
CoroutineManager.StartCoroutine(WaitForStartingInfo());
|
||||||
|
|
||||||
if (Client.ConnectionStatus != NetConnectionStatus.Connected)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Couldn't connect to server");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the timer
|
// Start the timer
|
||||||
//update.Start();
|
//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
|
// 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
|
// When this is set to true, we are approved and ready to go
|
||||||
bool CanStart = false;
|
bool CanStart = false;
|
||||||
|
|
||||||
@@ -107,7 +114,9 @@ namespace Subsurface.Networking
|
|||||||
// Loop untill we are approved
|
// Loop untill we are approved
|
||||||
while (!CanStart)
|
while (!CanStart)
|
||||||
{
|
{
|
||||||
if (DateTime.Now>timeOut) return;
|
yield return Status.Running;
|
||||||
|
|
||||||
|
if (DateTime.Now > timeOut) break;
|
||||||
|
|
||||||
NetIncomingMessage inc;
|
NetIncomingMessage inc;
|
||||||
// If new messages arrived
|
// If new messages arrived
|
||||||
@@ -120,7 +129,9 @@ namespace Subsurface.Networking
|
|||||||
case NetIncomingMessageType.Data:
|
case NetIncomingMessageType.Data:
|
||||||
if (inc.ReadByte() == (byte)PacketTypes.LoggedIn)
|
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
|
//add the names of other connected clients to the lobby screen
|
||||||
int existingClients = inc.ReadInt32();
|
int existingClients = inc.ReadInt32();
|
||||||
@@ -149,19 +160,50 @@ namespace Subsurface.Networking
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Should not happen and if happens, don't care
|
|
||||||
Console.WriteLine(inc.ReadString() + " Strange message");
|
Console.WriteLine(inc.ReadString() + " Strange message");
|
||||||
break;
|
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()
|
public override void Update()
|
||||||
{
|
{
|
||||||
if (updateTimer > DateTime.Now) return;
|
if (!connected || updateTimer > DateTime.Now) return;
|
||||||
|
|
||||||
if (myCharacter!=null)
|
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)
|
if (myCharacter.IsDead)
|
||||||
{
|
{
|
||||||
@@ -190,7 +232,6 @@ namespace Subsurface.Networking
|
|||||||
|
|
||||||
NetworkEvent.events.Clear();
|
NetworkEvent.events.Clear();
|
||||||
|
|
||||||
|
|
||||||
CheckServerMessages();
|
CheckServerMessages();
|
||||||
|
|
||||||
// Update current time
|
// Update current time
|
||||||
@@ -236,13 +277,20 @@ namespace Subsurface.Networking
|
|||||||
Game1.GameSession = new GameSession(Submarine.Loaded);
|
Game1.GameSession = new GameSession(Submarine.Loaded);
|
||||||
Game1.GameSession.StartShift(duration, levelSeed);
|
Game1.GameSession.StartShift(duration, levelSeed);
|
||||||
|
|
||||||
myCharacter = ReadCharacterData(inc);
|
//myCharacter = ReadCharacterData(inc);
|
||||||
Character.Controlled = myCharacter;
|
//Character.Controlled = myCharacter;
|
||||||
|
|
||||||
int count = inc.ReadInt32();
|
int count = inc.ReadInt32();
|
||||||
for (int n = 0; n < count; n++)
|
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;
|
gameStarted = true;
|
||||||
@@ -275,7 +323,7 @@ namespace Subsurface.Networking
|
|||||||
case (byte)PacketTypes.KickedOut:
|
case (byte)PacketTypes.KickedOut:
|
||||||
string msg = inc.ReadString();
|
string msg = inc.ReadString();
|
||||||
|
|
||||||
DebugConsole.ThrowError(msg);
|
new GUIMessageBox("KICKED", msg);
|
||||||
|
|
||||||
Game1.MainMenuScreen.Select();
|
Game1.MainMenuScreen.Select();
|
||||||
|
|
||||||
@@ -296,8 +344,8 @@ namespace Subsurface.Networking
|
|||||||
case (byte)PacketTypes.Traitor:
|
case (byte)PacketTypes.Traitor:
|
||||||
string targetName = inc.ReadString();
|
string targetName = inc.ReadString();
|
||||||
|
|
||||||
Game1.GameSession.NewChatMessage("You are an agent of Ordo Europae", messageColor[(int)ChatMessageType.Server]);
|
new GUIMessageBox("You are the Traitor!", "Your secret task is to assassinate " + targetName + "!");
|
||||||
Game1.GameSession.NewChatMessage("Your secret task is to assassinate " + targetName + "!", messageColor[(int)ChatMessageType.Server]);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,20 +404,37 @@ namespace Subsurface.Networking
|
|||||||
bool isFemale = inc.ReadBoolean();
|
bool isFemale = inc.ReadBoolean();
|
||||||
int inventoryID = inc.ReadInt32();
|
int inventoryID = inc.ReadInt32();
|
||||||
|
|
||||||
int headSpriteID = inc.ReadInt32();
|
int headSpriteID = inc.ReadInt32();
|
||||||
|
|
||||||
|
Vector2 position = new Vector2(inc.ReadFloat(), inc.ReadFloat());
|
||||||
|
|
||||||
string jobName = inc.ReadString();
|
string jobName = inc.ReadString();
|
||||||
JobPrefab jobPrefab = JobPrefab.List.Find(jp => jp.Name == jobName);
|
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);
|
CharacterInfo ch = new CharacterInfo("Content/Characters/Human/human.xml", newName, isFemale ? Gender.Female : Gender.Male, jobPrefab);
|
||||||
ch.HeadSpriteId = headSpriteID;
|
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.ID = ID;
|
||||||
character.Inventory.ID = inventoryID;
|
character.Inventory.ID = inventoryID;
|
||||||
|
|
||||||
|
character.GiveJobItems();
|
||||||
|
|
||||||
return character;
|
return character;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -292,6 +292,8 @@ namespace Subsurface.Networking
|
|||||||
Game1.GameSession.StartShift(Game1.NetLobbyScreen.GameDuration, Game1.NetLobbyScreen.LevelSeed);
|
Game1.GameSession.StartShift(Game1.NetLobbyScreen.GameDuration, Game1.NetLobbyScreen.LevelSeed);
|
||||||
//EventManager.SelectEvent(Game1.netLobbyScreen.SelectedEvent);
|
//EventManager.SelectEvent(Game1.netLobbyScreen.SelectedEvent);
|
||||||
|
|
||||||
|
List<CharacterInfo> characterInfos = new List<CharacterInfo>();
|
||||||
|
|
||||||
foreach (Client client in connectedClients)
|
foreach (Client client in connectedClients)
|
||||||
{
|
{
|
||||||
client.inGame = true;
|
client.inGame = true;
|
||||||
@@ -302,10 +304,21 @@ namespace Subsurface.Networking
|
|||||||
{
|
{
|
||||||
client.characterInfo = new CharacterInfo("Content/Characters/Human/human.xml", client.name);
|
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)
|
if (myClient != null)
|
||||||
{
|
{
|
||||||
WayPoint spawnPoint = WayPoint.GetRandom(SpawnType.Human);
|
WayPoint spawnPoint = WayPoint.GetRandom(SpawnType.Human);
|
||||||
@@ -313,37 +326,38 @@ namespace Subsurface.Networking
|
|||||||
myClient.character = new Character(ch, (spawnPoint == null) ? Vector2.Zero : spawnPoint.SimPosition);
|
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)
|
foreach (Client client in connectedClients)
|
||||||
{
|
{
|
||||||
NetOutgoingMessage msg = Server.CreateMessage();
|
//if (otherClient == client) continue;
|
||||||
msg.Write((byte)PacketTypes.StartGame);
|
msg.Write(client.ID);
|
||||||
|
|
||||||
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);
|
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;
|
gameStarted = true;
|
||||||
|
|
||||||
Game1.GameScreen.Cam.TargetPos = Vector2.Zero;
|
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 there's enough crew members assigned to the job already, continue
|
||||||
if (assignedClientCount[jobIndex] >= JobPrefab.List[jobIndex].MaxNumber) continue;
|
if (assignedClientCount[jobIndex] >= JobPrefab.List[jobIndex].MaxNumber) continue;
|
||||||
|
|
||||||
unassigned[i].assignedJob = JobPrefab.List[i];
|
unassigned[i].assignedJob = JobPrefab.List[jobIndex];
|
||||||
|
|
||||||
assignedClientCount[jobIndex]++;
|
assignedClientCount[jobIndex]++;
|
||||||
unassigned.RemoveAt(i);
|
unassigned.RemoveAt(i);
|
||||||
|
|||||||
@@ -103,11 +103,12 @@ namespace Subsurface.Networking
|
|||||||
DebugConsole.ThrowError("Received invalid network message");
|
DebugConsole.ThrowError("Received invalid network message");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
//288=id, 280=char
|
||||||
Entity e = Entity.FindEntityByID(id);
|
Entity e = Entity.FindEntityByID(id);
|
||||||
if (e == null)
|
if (e == null)
|
||||||
{
|
{
|
||||||
//DebugConsole.ThrowError("Couldn't find an entity matching the ID ''" + id + "''");
|
//DebugConsole.ThrowError("Couldn't find an entity matching the ID ''" + id + "''");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,13 +28,16 @@ namespace Subsurface.Networking
|
|||||||
|
|
||||||
class NetworkMember
|
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 string name;
|
||||||
|
|
||||||
protected TimeSpan updateInterval;
|
protected TimeSpan updateInterval;
|
||||||
protected DateTime updateTimer;
|
protected DateTime updateTimer;
|
||||||
|
|
||||||
|
protected GUIFrame inGameHUD;
|
||||||
|
protected GUIListBox chatBox;
|
||||||
|
|
||||||
protected bool gameStarted;
|
protected bool gameStarted;
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
@@ -47,10 +50,55 @@ namespace Subsurface.Networking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
public void AddChatMessage(string message, ChatMessageType messageType)
|
||||||
{
|
{
|
||||||
Game1.NetLobbyScreen.NewChatMessage(message, messageColor[(int)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();
|
GUI.PlayMessageSound();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -198,22 +198,21 @@ namespace Subsurface
|
|||||||
hireList.ClearChildren();
|
hireList.ClearChildren();
|
||||||
foreach (CharacterInfo c in gameMode.hireManager.availableCharacters)
|
foreach (CharacterInfo c in gameMode.hireManager.availableCharacters)
|
||||||
{
|
{
|
||||||
GUIFrame frame = new GUIFrame(
|
//GUIFrame frame = new GUIFrame(
|
||||||
new Rectangle(0, 0, 0, 25), Color.White, Alignment.Left, null, hireList);
|
// new Rectangle(0, 0, 0, 25), Color.Transparent, null, hireList);
|
||||||
frame.UserData = c;
|
//frame.UserData = c;
|
||||||
frame.Padding = new Vector4(10.0f, 0.0f, 10.0f, 0.0f);
|
//frame.Padding = new Vector4(10.0f, 0.0f, 10.0f, 0.0f);
|
||||||
|
|
||||||
GUITextBlock textBlock = new GUITextBlock(
|
GUITextBlock textBlock = new GUITextBlock(
|
||||||
new Rectangle(0, 0, 0, 25),
|
new Rectangle(0, 0, 0, 25),
|
||||||
c.Name + " (" + c.Job.Name + ")",
|
c.Name + " (" + c.Job.Name + ")", GUI.style, hireList);
|
||||||
Color.Transparent, Color.Black,
|
textBlock.UserData = c;
|
||||||
Alignment.Left, null, frame);
|
|
||||||
|
|
||||||
textBlock = new GUITextBlock(
|
textBlock = new GUITextBlock(
|
||||||
new Rectangle(0, 0, 0, 25),
|
new Rectangle(0, 0, 0, 25),
|
||||||
c.Salary.ToString(),
|
c.Salary.ToString(),
|
||||||
Color.Transparent, Color.Black,
|
null, null,
|
||||||
Alignment.Right, null, frame);
|
Alignment.TopRight, GUI.style, textBlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,7 +256,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
spriteBatch.End();
|
spriteBatch.End();
|
||||||
|
|
||||||
if (characterList.SelectedData != null)
|
if (characterList.SelectedData != null && selectedRightPanel == (int)PanelTab.Crew)
|
||||||
{
|
{
|
||||||
if (previewCharacter != null)
|
if (previewCharacter != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -222,16 +222,18 @@ namespace Subsurface
|
|||||||
if (string.IsNullOrEmpty(ipBox.Text)) return false;
|
if (string.IsNullOrEmpty(ipBox.Text)) return false;
|
||||||
|
|
||||||
Game1.NetworkMember = new GameClient(nameBox.Text);
|
Game1.NetworkMember = new GameClient(nameBox.Text);
|
||||||
if (Game1.Client.ConnectToServer(ipBox.Text))
|
Game1.Client.ConnectToServer(ipBox.Text);
|
||||||
{
|
|
||||||
Game1.NetLobbyScreen.Select();
|
return true;
|
||||||
return true;
|
//{
|
||||||
}
|
// Game1.NetLobbyScreen.Select();
|
||||||
else
|
// return true;
|
||||||
{
|
//}
|
||||||
Game1.NetworkMember = null;
|
//else
|
||||||
return false;
|
//{
|
||||||
}
|
// Game1.NetworkMember = null;
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ namespace Subsurface
|
|||||||
//int oldMapIndex = 0;
|
//int oldMapIndex = 0;
|
||||||
//if (mapList != null && mapList.SelectedData != null) oldMapIndex = mapList.SelectedIndex;
|
//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 = new GUIListBox(new Rectangle(0, 60, 200, 200), Color.White, GUI.style, infoFrame);
|
||||||
subList.OnSelected = SelectMap;
|
subList.OnSelected = SelectMap;
|
||||||
subList.Enabled = (Game1.Server != null);
|
subList.Enabled = (Game1.Server != null);
|
||||||
@@ -184,7 +184,7 @@ namespace Subsurface
|
|||||||
return;
|
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 = new GUIListBox(new Rectangle(220, 60, 200, 200), GUI.style, infoFrame);
|
||||||
modeList.Enabled = (Game1.Server != null);
|
modeList.Enabled = (Game1.Server != null);
|
||||||
//modeList.OnSelected = new GUIListBox.OnSelectedHandler(SelectEvent);
|
//modeList.OnSelected = new GUIListBox.OnSelectedHandler(SelectEvent);
|
||||||
@@ -202,16 +202,15 @@ namespace Subsurface
|
|||||||
textBlock.UserData = mode;
|
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);
|
"Game duration: ", GUI.style, Alignment.Left, Alignment.TopLeft, infoFrame);
|
||||||
durationText.TextGetter = DurationText;
|
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);
|
GUI.style, 0.1f, infoFrame);
|
||||||
durationBar.BarSize = 0.1f;
|
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),
|
new GUITextBlock(new Rectangle((int)(modeList.Rect.Right + 20 - 80), 100, 100, 20),
|
||||||
"Level Seed: ", GUI.style, Alignment.Left, Alignment.TopLeft, infoFrame);
|
"Level Seed: ", GUI.style, Alignment.Left, Alignment.TopLeft, infoFrame);
|
||||||
|
|
||||||
@@ -236,20 +235,24 @@ namespace Subsurface
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
int x = playerFrame.Rect.Width / 2;
|
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);
|
Alignment.TopLeft, GUI.style, playerFrame);
|
||||||
playerName.Text = Game1.Client.CharacterInfo.Name;
|
playerName.Text = Game1.Client.CharacterInfo.Name;
|
||||||
playerName.OnEnter += ChangeCharacterName;
|
playerName.OnEnter += ChangeCharacterName;
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(x,40,200, 30), "Gender: ", Color.Transparent, Color.Black,
|
new GUITextBlock(new Rectangle(x,70,200, 30), "Gender: ", GUI.style, playerFrame);
|
||||||
Alignment.TopLeft, 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);
|
Alignment.TopLeft, GUI.style,playerFrame);
|
||||||
maleButton.UserData = Gender.Male;
|
maleButton.UserData = Gender.Male;
|
||||||
maleButton.OnClicked += SwitchGender;
|
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);
|
Alignment.TopLeft, GUI.style, playerFrame);
|
||||||
femaleButton.UserData = Gender.Female;
|
femaleButton.UserData = Gender.Female;
|
||||||
femaleButton.OnClicked += SwitchGender;
|
femaleButton.OnClicked += SwitchGender;
|
||||||
@@ -311,6 +314,14 @@ namespace Subsurface
|
|||||||
playerList.RemoveChild(playerList.GetChild(client));
|
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)
|
public override void Update(double deltaTime)
|
||||||
{
|
{
|
||||||
base.Update(deltaTime);
|
base.Update(deltaTime);
|
||||||
@@ -406,6 +417,7 @@ namespace Subsurface
|
|||||||
Vector2 pos = new Vector2(1000.0f, 1000.0f);
|
Vector2 pos = new Vector2(1000.0f, 1000.0f);
|
||||||
|
|
||||||
Character character = new Character(Game1.Client.CharacterInfo, pos);
|
Character character = new Character(Game1.Client.CharacterInfo, pos);
|
||||||
|
character.ID = int.MaxValue;
|
||||||
|
|
||||||
Game1.Client.Character = character;
|
Game1.Client.Character = character;
|
||||||
|
|
||||||
@@ -422,6 +434,7 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
pos = ConvertUnits.ToDisplayUnits(pos);
|
pos = ConvertUnits.ToDisplayUnits(pos);
|
||||||
previewHull = new Hull(new Rectangle((int)pos.X - 100, (int)pos.Y + 100, 200, 200));
|
previewHull = new Hull(new Rectangle((int)pos.X - 100, (int)pos.Y + 100, 200, 200));
|
||||||
|
previewHull.ID = int.MaxValue - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
Physics.Alpha = 1.0f;
|
Physics.Alpha = 1.0f;
|
||||||
@@ -501,10 +514,11 @@ namespace Subsurface
|
|||||||
private void UpdateJobPreferences(GUIListBox listBox)
|
private void UpdateJobPreferences(GUIListBox listBox)
|
||||||
{
|
{
|
||||||
listBox.Deselect();
|
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;
|
float a = (float)(i - 1) / 3.0f;
|
||||||
Color color = new Color(a, 1.0f - a, 0.5f, 1.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;
|
listBox.children[i].Color = color;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
<Compile Include="Characters\Jobs\JobPrefab.cs" />
|
<Compile Include="Characters\Jobs\JobPrefab.cs" />
|
||||||
<Compile Include="Characters\AI\SteeringManager.cs" />
|
<Compile Include="Characters\AI\SteeringManager.cs" />
|
||||||
<Compile Include="Characters\AI\SteeringPath.cs" />
|
<Compile Include="Characters\AI\SteeringPath.cs" />
|
||||||
|
<Compile Include="CoroutineManager.cs" />
|
||||||
<Compile Include="Rand.cs" />
|
<Compile Include="Rand.cs" />
|
||||||
<Compile Include="Events\PropertyTask.cs" />
|
<Compile Include="Events\PropertyTask.cs" />
|
||||||
<Compile Include="Events\RepairTask.cs" />
|
<Compile Include="Events\RepairTask.cs" />
|
||||||
@@ -362,6 +363,15 @@
|
|||||||
<Content Include="Content\Items\Pump\pump.png">
|
<Content Include="Content\Items\Pump\pump.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</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">
|
<Content Include="Content\UI\caret.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user