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:
Regalis
2015-07-09 01:40:27 +03:00
parent d56f7f3f77
commit 2254585dac
35 changed files with 831 additions and 312 deletions
+32 -5
View File
@@ -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);
@@ -1036,7 +1061,9 @@ namespace Subsurface
if (controlled == this) controlled = null; 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) if (aiTarget != null)
aiTarget.Remove(); aiTarget.Remove();
+8 -6
View File
@@ -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);
+10
View File
@@ -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)
{ {
+1 -1
View File
@@ -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", "");
+7 -1
View File
@@ -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

+22 -6
View File
@@ -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>
+2 -2
View File
@@ -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>
+45
View 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;
}
}
}
}
}
-1
View File
@@ -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)
+8 -8
View File
@@ -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);
+2 -2
View File
@@ -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)
{ {
} }
+7 -2
View File
@@ -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();
} }
+13 -4
View File
@@ -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()
+38 -37
View File
@@ -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)
{ {
+14 -12
View File
@@ -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);
+4 -4
View File
@@ -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);
+1 -1
View File
@@ -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;
+5 -5
View File
@@ -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)
+1 -1
View File
@@ -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++)
{ {
+1 -1
View File
@@ -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;
+153 -90
View File
@@ -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,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) 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);
selectedLocation = highlightedLocation; selectedLocation = highlightedLocation;
} }
} }
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
{ {
+2 -3
View File
@@ -820,7 +820,7 @@ namespace Subsurface
} }
} }
ID = 1; //ID = 1;
loaded = this; loaded = this;
} }
@@ -838,8 +838,7 @@ namespace Subsurface
public static void Unload() public static void Unload()
{ {
if (loaded == null) return; if (loaded == null) return;
loaded.Remove(); loaded.Remove();
loaded.Clear(); loaded.Clear();
+200 -18
View File
@@ -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(wayPoint); wayPoints.Add(wp);
} }
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)
@@ -146,6 +321,13 @@ namespace Subsurface
i += 1; i += 1;
} }
} }
public override void Remove()
{
base.Remove();
WayPointList.Remove(this);
}
} }
} }
+100 -35
View File
@@ -15,7 +15,15 @@ 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
{ {
@@ -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;
} }
+43 -29
View File
@@ -291,7 +291,9 @@ namespace Subsurface.Networking
Game1.GameSession = new GameSession(selectedMap, Game1.NetLobbyScreen.SelectedMode); Game1.GameSession = new GameSession(selectedMap, Game1.NetLobbyScreen.SelectedMode);
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);
+2 -1
View File
@@ -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;
} }
+50 -2
View File
@@ -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
@@ -46,11 +49,56 @@ namespace Subsurface.Networking
name = value; 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) 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();
} }
+9 -10
View File
@@ -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)
{ {
+12 -10
View File
@@ -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;
//}
} }
} }
+29 -15
View File
@@ -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,15 +202,14 @@ 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,11 +514,12 @@ 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;
} }
+10
View File
@@ -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.