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:
@@ -45,7 +45,7 @@ namespace Subsurface
|
||||
{
|
||||
//give an unique ID
|
||||
bool IDfound;
|
||||
id = 0;
|
||||
id = 1;//Rand.Int(int.MaxValue);
|
||||
do
|
||||
{
|
||||
id += 1;
|
||||
|
||||
@@ -19,6 +19,10 @@ namespace Subsurface
|
||||
private int seed;
|
||||
private int size;
|
||||
|
||||
private Texture2D iceTexture;
|
||||
private Texture2D iceCraters;
|
||||
private Texture2D iceCrack;
|
||||
|
||||
private Location currentLocation;
|
||||
private Location selectedLocation;
|
||||
|
||||
@@ -34,49 +38,12 @@ namespace Subsurface
|
||||
|
||||
connections = new List<LocationConnection>();
|
||||
|
||||
iceTexture = Game1.textureLoader.FromFile("Content/Map/iceSurface.png");
|
||||
iceCraters = Game1.textureLoader.FromFile("Content/Map/iceCraters.png");
|
||||
iceCrack = Game1.textureLoader.FromFile("Content/Map/iceCrack.png");
|
||||
|
||||
GenerateLocations();
|
||||
|
||||
//for (int i = 0; i<10; i++)
|
||||
//{
|
||||
// Vector2 pos = new Vector2((float)Game1.random.NextDouble() * size, (float)Game1.random.NextDouble() * size);
|
||||
|
||||
// Location location =
|
||||
// locations.Add(location);
|
||||
//}
|
||||
|
||||
//for (int i = 0; i < 10; i++)
|
||||
//{
|
||||
|
||||
// int closestIndex = 0;
|
||||
// float closestDistance = 0.0f;
|
||||
// for (int j = 0; j<10; j++)
|
||||
// {
|
||||
// if (j == i) continue;
|
||||
|
||||
// //ignore if already connected
|
||||
// bool alreadyConnected = false;
|
||||
// foreach (LocationConnection connection in connections)
|
||||
// {
|
||||
// if (connection.Locations.Contains(locations[i]) && connection.Locations.Contains(locations[j]))
|
||||
// {
|
||||
// alreadyConnected = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (alreadyConnected) continue;
|
||||
|
||||
// float dist = Vector2.Distance(locations[i].MapPosition, locations[j].MapPosition);
|
||||
// if (closestDistance > 0.0f && dist > closestDistance) continue;
|
||||
|
||||
// closestDistance = dist;
|
||||
// closestIndex = j;
|
||||
// }
|
||||
|
||||
|
||||
// connections.Add(new LocationConnection(locations[i], locations[closestIndex], level));
|
||||
//}
|
||||
|
||||
currentLocation = locations[locations.Count/2];
|
||||
}
|
||||
|
||||
@@ -97,6 +64,12 @@ namespace Subsurface
|
||||
{
|
||||
if (edge.point1 == edge.point2) continue;
|
||||
|
||||
//remove points from the edge of the map
|
||||
if (edge.point1.X == 0 || edge.point1.X == size) continue;
|
||||
if (edge.point1.Y == 0 || edge.point1.Y == size) continue;
|
||||
if (edge.point2.X == 0 || edge.point2.X == size) continue;
|
||||
if (edge.point2.Y == 0 || edge.point2.Y == size) continue;
|
||||
|
||||
Location[] newLocations = new Location[2];
|
||||
newLocations[0] = locations.Find(l => l.MapPosition == edge.point1 || l.MapPosition == edge.point2);
|
||||
newLocations[1] = locations.Find(l => l != newLocations[0] && (l.MapPosition == edge.point1 || l.MapPosition == edge.point2));
|
||||
@@ -117,6 +90,8 @@ namespace Subsurface
|
||||
}
|
||||
|
||||
connections.Add(new LocationConnection(newLocations[0], newLocations[1], Level.CreateRandom()));
|
||||
|
||||
|
||||
}
|
||||
|
||||
float minDistance = 50.0f;
|
||||
@@ -124,40 +99,103 @@ namespace Subsurface
|
||||
{
|
||||
LocationConnection connection = connections[i];
|
||||
|
||||
if (Vector2.Distance(connection.Locations[0].MapPosition, connection.Locations[1].MapPosition) > minDistance) continue;
|
||||
if (Vector2.Distance(connection.Locations[0].MapPosition, connection.Locations[1].MapPosition) > minDistance)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
locations.Remove(connection.Locations[0]);
|
||||
connections.Remove(connection);
|
||||
|
||||
|
||||
foreach (LocationConnection connection2 in connections)
|
||||
{
|
||||
if (connection == connection2) continue;
|
||||
if (connection2.Locations[0] == connection.Locations[0]) connection2.Locations[0] = connection.Locations[1];
|
||||
if (connection2.Locations[1] == connection.Locations[0]) connection2.Locations[1] = connection.Locations[1];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = connections.Count - 1; i >= 0; i--)
|
||||
{
|
||||
LocationConnection connection = connections[i];
|
||||
|
||||
for (int n = i-1; n >= 0; n--)
|
||||
{
|
||||
if (connection.Locations.Contains(connections[n].Locations[0])
|
||||
&& connection.Locations.Contains(connections[n].Locations[1]))
|
||||
{
|
||||
connections.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (LocationConnection connection in connections)
|
||||
{
|
||||
Vector2 start = connection.Locations[0].MapPosition;
|
||||
Vector2 end = connection.Locations[1].MapPosition;
|
||||
int generations = (int)(Math.Sqrt(Vector2.Distance(start, end) / 10.0f));
|
||||
connection.CrackSegments = GenerateCrack(start, end, generations);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Vector2[]> GenerateCrack(Vector2 start, Vector2 end, int generations)
|
||||
{
|
||||
List<Vector2[]> segments = new List<Vector2[]>();
|
||||
|
||||
segments.Add(new Vector2[] {start, end});
|
||||
|
||||
float offsetAmount = 5.0f;
|
||||
|
||||
for (int n = 0; n<generations; n++)
|
||||
{
|
||||
for (int i = 0; i<segments.Count; i++)
|
||||
{
|
||||
Vector2 startSegment = segments[i][0];
|
||||
Vector2 endSegment = segments[i][1];
|
||||
|
||||
segments.RemoveAt(i);
|
||||
|
||||
Vector2 midPoint = (startSegment + endSegment) / 2.0f;
|
||||
|
||||
Vector2 normal = Vector2.Normalize(endSegment - startSegment);
|
||||
normal = new Vector2(-normal.Y, normal.X);
|
||||
midPoint += normal * Rand.Range(-offsetAmount, offsetAmount);
|
||||
|
||||
segments.Insert(i, new Vector2[] { startSegment, midPoint });
|
||||
segments.Insert(i+1, new Vector2[] { midPoint, endSegment });
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return segments;
|
||||
}
|
||||
|
||||
public void MoveToNextLocation()
|
||||
{
|
||||
currentLocation = selectedLocation;
|
||||
selectedLocation = null;
|
||||
}
|
||||
|
||||
private Location highlightedLocation;
|
||||
public void Draw(SpriteBatch spriteBatch, Rectangle rect)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, rect, Color.DarkBlue, true);
|
||||
//GUI.DrawRectangle(spriteBatch, rect, Color.DarkBlue, true);
|
||||
|
||||
spriteBatch.Draw(iceTexture, rect, Color.White);
|
||||
|
||||
Vector2 rectCorner = new Vector2(rect.X, rect.Y);
|
||||
Vector2 scale = new Vector2((float)rect.Width/ size, (float)rect.Height/size);
|
||||
|
||||
float maxDist = 20.0f;
|
||||
float closestDist = 0.0f;
|
||||
Location highlightedLocation = null;
|
||||
foreach (Location location in locations)
|
||||
highlightedLocation = null;
|
||||
for (int i = 0; i < locations.Count;i++ )
|
||||
{
|
||||
Vector2 pos = location.MapPosition * scale;
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X + (int)pos.X, rect.Y + (int)pos.Y, 5, 5), Color.White, true);
|
||||
Location location = locations[i];
|
||||
Vector2 pos = rectCorner + location.MapPosition * scale;
|
||||
|
||||
if (currentLocation == location)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X + (int)pos.X - 4, rect.Y + (int)pos.Y - 4, 5+8, 5+8), Color.Red, false);
|
||||
}
|
||||
|
||||
float dist = Vector2.Distance(PlayerInput.MousePosition, new Vector2(rect.X + pos.X, rect.Y + pos.Y));
|
||||
float dist = Vector2.Distance(PlayerInput.MousePosition, new Vector2(pos.X, pos.Y));
|
||||
if (dist < maxDist && (highlightedLocation == null || dist < closestDist))
|
||||
{
|
||||
closestDist = dist;
|
||||
@@ -165,55 +203,78 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
if (highlightedLocation!=null)
|
||||
{
|
||||
Vector2 pos = highlightedLocation.MapPosition * scale;
|
||||
pos.X = (int)pos.X;
|
||||
pos.Y = (int)pos.Y;
|
||||
spriteBatch.DrawString(GUI.font, highlightedLocation.Name, pos + new Vector2(rect.X - 50, rect.Y), Color.White);
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X + (int)pos.X - 4, rect.Y + (int)pos.Y - 4, 5 + 8, 5 + 8), Color.White, false);
|
||||
}
|
||||
|
||||
if (selectedLocation != null)
|
||||
{
|
||||
Vector2 pos = selectedLocation.MapPosition * scale;
|
||||
pos.X = (int)pos.X;
|
||||
pos.Y = (int)pos.Y;
|
||||
spriteBatch.DrawString(GUI.font, selectedLocation.Name, pos + new Vector2(rect.X - 50, rect.Y), Color.White);
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X + (int)pos.X - 4, rect.Y + (int)pos.Y - 4, 5 + 8, 5 + 8), Color.White, false);
|
||||
}
|
||||
|
||||
Vector2 rectCorner = new Vector2(rect.X, rect.Y);
|
||||
foreach (LocationConnection connection in connections)
|
||||
{
|
||||
GUI.DrawLine(spriteBatch,
|
||||
connection.Locations[0].MapPosition * scale + rectCorner,
|
||||
connection.Locations[1].MapPosition * scale + rectCorner, Color.LightGray);
|
||||
|
||||
if (highlightedLocation!=currentLocation &&
|
||||
Color crackColor = Color.White;
|
||||
|
||||
if (highlightedLocation != currentLocation &&
|
||||
connection.Locations.Contains(highlightedLocation) && connection.Locations.Contains(currentLocation))
|
||||
{
|
||||
GUI.DrawLine(spriteBatch,
|
||||
connection.Locations[0].MapPosition * scale + rectCorner +Vector2.One,
|
||||
connection.Locations[1].MapPosition * scale + rectCorner + Vector2.One, Color.White);
|
||||
crackColor = Color.Red;
|
||||
|
||||
if (PlayerInput.LeftButtonClicked())
|
||||
if(selectedLocation!=highlightedLocation && highlightedLocation!=null)
|
||||
if (PlayerInput.LeftButtonClicked()&&
|
||||
selectedLocation != highlightedLocation && highlightedLocation != null)
|
||||
{
|
||||
//currentLocation = highlightedLocation;
|
||||
Game1.LobbyScreen.SelectLocation(highlightedLocation, connection);
|
||||
selectedLocation = highlightedLocation;
|
||||
}
|
||||
selectedLocation = highlightedLocation;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (selectedLocation != currentLocation &&
|
||||
(connection.Locations.Contains(selectedLocation) && connection.Locations.Contains(currentLocation)))
|
||||
{
|
||||
GUI.DrawLine(spriteBatch,
|
||||
connection.Locations[0].MapPosition * scale + rectCorner + Vector2.One,
|
||||
connection.Locations[1].MapPosition * scale + rectCorner + Vector2.One, Color.White);
|
||||
|
||||
crackColor = Color.Red;
|
||||
}
|
||||
|
||||
foreach (Vector2[] segment in connection.CrackSegments)
|
||||
{
|
||||
Vector2 start = segment[0] * scale + rectCorner;
|
||||
Vector2 end = segment[1] * scale + rectCorner;
|
||||
float dist = Vector2.Distance(start, end);
|
||||
|
||||
//spriteBatch.Draw(iceCrack,
|
||||
// new Rectangle((int)((start.X + end.X) / 2.0f), (int)((start.Y + end.Y) / 2.0f), (int)dist, 30),
|
||||
// new Rectangle(0, 0, iceCrack.Width, 60), crackColor, MathUtils.VectorToAngle(start - end),
|
||||
// new Vector2(dist / 2, 30), SpriteEffects.None, 0.01f);
|
||||
GUI.DrawLine(spriteBatch,
|
||||
segment[0] * scale + rectCorner,
|
||||
segment[1] * scale + rectCorner, crackColor);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < locations.Count; i++)
|
||||
{
|
||||
Location location = locations[i];
|
||||
Vector2 pos = rectCorner + location.MapPosition * scale;
|
||||
|
||||
int imgIndex = i % 16;
|
||||
int xCell = imgIndex % 4;
|
||||
int yCell = (int)Math.Floor(imgIndex / 4.0f);
|
||||
spriteBatch.Draw(iceCraters, pos,
|
||||
new Rectangle(xCell * 64, yCell * 64, 64, 64),
|
||||
Color.White, i,
|
||||
new Vector2(32, 32), 0.5f*scale, SpriteEffects.None, 0.0f);
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++ )
|
||||
{
|
||||
Location location = (i == 0) ? highlightedLocation : selectedLocation;
|
||||
if (i == 2) location = currentLocation;
|
||||
|
||||
if (location == null) continue;
|
||||
|
||||
Vector2 pos = rectCorner + location.MapPosition * scale;
|
||||
pos.X = (int)pos.X;
|
||||
pos.Y = (int)pos.Y;
|
||||
if (highlightedLocation==location)
|
||||
{
|
||||
spriteBatch.DrawString(GUI.font, location.Name, pos + new Vector2(-50, -20), Color.DarkRed);
|
||||
}
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X - 4, (int)pos.Y - 4, 5 + 8, 5 + 8), Color.DarkRed, false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -222,8 +283,10 @@ namespace Subsurface
|
||||
|
||||
class LocationConnection
|
||||
{
|
||||
Location[] locations;
|
||||
Level level;
|
||||
private Location[] locations;
|
||||
private Level level;
|
||||
|
||||
public List<Vector2[]> CrackSegments;
|
||||
|
||||
public Location[] Locations
|
||||
{
|
||||
|
||||
@@ -820,7 +820,7 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
ID = 1;
|
||||
//ID = 1;
|
||||
|
||||
loaded = this;
|
||||
}
|
||||
@@ -838,8 +838,7 @@ namespace Subsurface
|
||||
public static void Unload()
|
||||
{
|
||||
if (loaded == null) return;
|
||||
|
||||
|
||||
|
||||
loaded.Remove();
|
||||
|
||||
loaded.Clear();
|
||||
|
||||
@@ -13,16 +13,35 @@ namespace Subsurface
|
||||
public enum SpawnType { None, Human, Enemy };
|
||||
class WayPoint : MapEntity
|
||||
{
|
||||
|
||||
public static List<WayPoint> WayPointList = new List<WayPoint>();
|
||||
|
||||
private SpawnType spawnType;
|
||||
|
||||
//characters spawning at the waypoint will be given an ID card with these tags
|
||||
private string[] idCardTags;
|
||||
|
||||
//only characters with this job will be spawned at the waypoint
|
||||
private JobPrefab assignedJob;
|
||||
|
||||
public SpawnType SpawnType
|
||||
{
|
||||
get { return spawnType; }
|
||||
set { spawnType = value; }
|
||||
}
|
||||
|
||||
public string[] IdCardTags
|
||||
{
|
||||
get { return idCardTags; }
|
||||
private set
|
||||
{
|
||||
idCardTags = value;
|
||||
for (int i = 0; i<idCardTags.Length; i++)
|
||||
{
|
||||
idCardTags[i] = idCardTags[i].Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector2 SimPosition
|
||||
{
|
||||
get { return ConvertUnits.ToSimUnits(new Vector2(rect.X, rect.Y)); }
|
||||
@@ -32,8 +51,10 @@ namespace Subsurface
|
||||
{
|
||||
rect = newRect;
|
||||
linkedTo = new ObservableCollection<MapEntity>();
|
||||
idCardTags = new string[0];
|
||||
|
||||
mapEntityList.Add(this);
|
||||
WayPointList.Add(this);
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch, bool editing)
|
||||
@@ -54,17 +75,13 @@ namespace Subsurface
|
||||
|
||||
public override void DrawEditing(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
int x = 300, y = 10;
|
||||
if (editingHUD==null)
|
||||
{
|
||||
editingHUD = CreateEditingHUD();
|
||||
}
|
||||
|
||||
spriteBatch.DrawString(GUI.font, "Editing waypoint", new Vector2(x, y), Color.Black);
|
||||
spriteBatch.DrawString(GUI.font, "Hold space to link to another entity", new Vector2(x, y + 20), Color.Black);
|
||||
spriteBatch.DrawString(GUI.font, "Spawnpoint: "+spawnType.ToString()+" +/-", new Vector2(x, y + 40), Color.Black);
|
||||
|
||||
if (PlayerInput.KeyHit(Keys.Add)) spawnType += 1;
|
||||
if (PlayerInput.KeyHit(Keys.Subtract)) spawnType -= 1;
|
||||
|
||||
if (spawnType > SpawnType.Enemy) spawnType = SpawnType.None;
|
||||
if (spawnType < SpawnType.None) spawnType = SpawnType.Enemy;
|
||||
editingHUD.Update((float)Physics.step);
|
||||
editingHUD.Draw(spriteBatch);
|
||||
|
||||
if (!PlayerInput.LeftButtonClicked()) return;
|
||||
|
||||
@@ -82,18 +99,105 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
public static WayPoint GetRandom(SpawnType spawnType = SpawnType.None)
|
||||
private bool ChangeSpawnType(GUIButton button, object obj)
|
||||
{
|
||||
GUITextBlock spawnTypeText = button.Parent as GUITextBlock;
|
||||
|
||||
spawnType += (int)button.UserData;
|
||||
|
||||
if (spawnType > SpawnType.Enemy) spawnType = SpawnType.None;
|
||||
if (spawnType < SpawnType.None) spawnType = SpawnType.Enemy;
|
||||
|
||||
spawnTypeText.Text = spawnType.ToString();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool EnterIDCardTags(GUITextBox textBox, string text)
|
||||
{
|
||||
IdCardTags = text.Split(',');
|
||||
textBox.Text = text;
|
||||
textBox.Color = Color.White;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool EnterAssignedJob(GUITextBox textBox, string text)
|
||||
{
|
||||
string trimmedName = text.ToLower().Trim();
|
||||
assignedJob = JobPrefab.List.Find(jp => jp.Name.ToLower() == trimmedName);
|
||||
|
||||
if (assignedJob !=null && trimmedName!="none")
|
||||
{
|
||||
textBox.Color = Color.White;
|
||||
textBox.Text = (assignedJob == null) ? "None" : assignedJob.Name;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool TextBoxChanged(GUITextBox textBox, string text)
|
||||
{
|
||||
textBox.Color = Color.Red;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private GUIComponent CreateEditingHUD(bool inGame = false)
|
||||
{
|
||||
int width = 500;
|
||||
int x = Game1.GraphicsWidth / 2 - width / 2, y = 10;
|
||||
|
||||
editingHUD = new GUIFrame(new Rectangle(x, y, width, 150), Color.Black * 0.5f);
|
||||
editingHUD.Padding = new Vector4(10, 10, 0, 0);
|
||||
editingHUD.UserData = this;
|
||||
|
||||
new GUITextBlock(new Rectangle(0, 0, 100, 20), "Editing waypoint", GUI.style, editingHUD);
|
||||
new GUITextBlock(new Rectangle(0, 20, 100, 20), "Hold space to link to another entity", GUI.style, editingHUD);
|
||||
new GUITextBlock(new Rectangle(0, 40, 100, 20), "Spawnpoint: ", GUI.style, editingHUD);
|
||||
|
||||
var spawnTypeText = new GUITextBlock(new Rectangle(0, 40, 200, 20), spawnType.ToString(), GUI.style, Alignment.Right, Alignment.TopLeft, editingHUD);
|
||||
|
||||
var button = new GUIButton(new Rectangle(-30,0,20,20), "-", Alignment.Right, GUI.style, spawnTypeText);
|
||||
button.UserData = -1;
|
||||
button.OnClicked = ChangeSpawnType;
|
||||
|
||||
button = new GUIButton(new Rectangle(0, 0, 20, 20), "+", Alignment.Right, GUI.style, spawnTypeText);
|
||||
button.UserData = 1;
|
||||
button.OnClicked = ChangeSpawnType;
|
||||
|
||||
//spriteBatch.DrawString(GUI.font, "Spawnpoint: " + spawnType.ToString() + " +/-", new Vector2(x, y + 40), Color.Black);
|
||||
|
||||
y = 40+20;
|
||||
|
||||
new GUITextBlock(new Rectangle(0, y, 100, 20), "ID Card tags:", Color.Transparent, Color.Black, Alignment.TopLeft, null, editingHUD);
|
||||
GUITextBox propertyBox = new GUITextBox(new Rectangle(100, y, 200, 20), GUI.style, editingHUD);
|
||||
propertyBox.Text = string.Join(", ", idCardTags);
|
||||
propertyBox.OnEnter = EnterIDCardTags;
|
||||
propertyBox.OnTextChanged = TextBoxChanged;
|
||||
y = y + 30;
|
||||
|
||||
new GUITextBlock(new Rectangle(0, y, 100, 20), "Assigned job:", Color.Transparent, Color.Black, Alignment.TopLeft, null, editingHUD);
|
||||
propertyBox = new GUITextBox(new Rectangle(100, y, 200, 20), GUI.style, editingHUD);
|
||||
propertyBox.Text = (assignedJob == null) ? "None" : assignedJob.Name;
|
||||
|
||||
propertyBox.OnEnter = EnterAssignedJob;
|
||||
propertyBox.OnTextChanged = TextBoxChanged;
|
||||
y = y + 30;
|
||||
|
||||
return editingHUD;
|
||||
}
|
||||
|
||||
public static WayPoint GetRandom(SpawnType spawnType = SpawnType.None, Job assignedJob = null)
|
||||
{
|
||||
List<WayPoint> wayPoints = new List<WayPoint>();
|
||||
|
||||
foreach (MapEntity e in mapEntityList)
|
||||
foreach (WayPoint wp in WayPointList)
|
||||
{
|
||||
WayPoint wayPoint = e as WayPoint;
|
||||
if (wayPoint==null) continue;
|
||||
|
||||
if (spawnType != SpawnType.None && wayPoint.spawnType != spawnType) continue;
|
||||
if (spawnType != SpawnType.None && wp.spawnType != spawnType) continue;
|
||||
if (assignedJob != null && wp.assignedJob != assignedJob.Prefab) continue;
|
||||
|
||||
wayPoints.Add(wayPoint);
|
||||
wayPoints.Add(wp);
|
||||
}
|
||||
|
||||
if (!wayPoints.Any()) return null;
|
||||
@@ -101,6 +205,55 @@ namespace Subsurface
|
||||
return wayPoints[Rand.Int(wayPoints.Count())];
|
||||
}
|
||||
|
||||
public static WayPoint[] SelectCrewSpawnPoints(List<CharacterInfo> crew)
|
||||
{
|
||||
List<WayPoint> unassignedWayPoints = new List<WayPoint>();
|
||||
foreach (WayPoint wp in WayPointList)
|
||||
{
|
||||
if (wp.spawnType == SpawnType.Human) unassignedWayPoints.Add(wp);
|
||||
}
|
||||
|
||||
WayPoint[] assignedWayPoints = new WayPoint[crew.Count];
|
||||
|
||||
for (int i = 0; i < crew.Count; i++ )
|
||||
{
|
||||
//try to give the crew member a spawnpoint that hasn't been assigned to anyone and matches their job
|
||||
for (int n = 0; n < unassignedWayPoints.Count; n++)
|
||||
{
|
||||
|
||||
if (crew[i].Job.Prefab != unassignedWayPoints[n].assignedJob) continue;
|
||||
assignedWayPoints[i] = unassignedWayPoints[n];
|
||||
unassignedWayPoints.RemoveAt(n);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//go through the crewmembers that don't have a spawnpoint yet (if any)
|
||||
for (int i = 0; i < crew.Count; i++)
|
||||
{
|
||||
if (assignedWayPoints[i] != null) continue;
|
||||
|
||||
//try to assign a spawnpoint that matches the job, even if the spawnpoint is already assigned to someone else
|
||||
foreach (WayPoint wp in WayPointList)
|
||||
{
|
||||
if (wp.spawnType != SpawnType.Human || wp.assignedJob != crew[i].Job.Prefab) continue;
|
||||
|
||||
assignedWayPoints[i] = wp;
|
||||
break;
|
||||
}
|
||||
|
||||
if (assignedWayPoints[i] != null) continue;
|
||||
|
||||
//everything else failed -> just give a random spawnpoint
|
||||
assignedWayPoints[i] = GetRandom(SpawnType.Human);
|
||||
}
|
||||
|
||||
|
||||
return assignedWayPoints;
|
||||
}
|
||||
|
||||
|
||||
public override XElement Save(XDocument doc)
|
||||
{
|
||||
XElement element = new XElement("WayPoint");
|
||||
@@ -110,6 +263,16 @@ namespace Subsurface
|
||||
new XAttribute("y", rect.Y),
|
||||
new XAttribute("spawn", spawnType));
|
||||
|
||||
if (idCardTags.Length > 0)
|
||||
{
|
||||
element.Add(new XAttribute("idcardtags", string.Join(",", idCardTags)));
|
||||
}
|
||||
|
||||
if (assignedJob != null)
|
||||
{
|
||||
element.Add(new XAttribute("job", assignedJob.Name));
|
||||
}
|
||||
|
||||
doc.Root.Add(element);
|
||||
|
||||
if (linkedTo != null)
|
||||
@@ -138,6 +301,18 @@ namespace Subsurface
|
||||
w.spawnType = (SpawnType)Enum.Parse(typeof(SpawnType),
|
||||
ToolBox.GetAttributeString(element, "spawn", "None"));
|
||||
|
||||
string idCardTagString = ToolBox.GetAttributeString(element, "idcardtags", "");
|
||||
if (!string.IsNullOrWhiteSpace(idCardTagString))
|
||||
{
|
||||
w.IdCardTags = idCardTagString.Split(',');
|
||||
}
|
||||
|
||||
string jobName = ToolBox.GetAttributeString(element, "job", "").ToLower();
|
||||
if (!string.IsNullOrWhiteSpace(jobName))
|
||||
{
|
||||
w.assignedJob = JobPrefab.List.Find(jp => jp.Name.ToLower() == jobName);
|
||||
}
|
||||
|
||||
w.linkedToID = new List<int>();
|
||||
int i = 0;
|
||||
while (element.Attribute("linkedto" + i) != null)
|
||||
@@ -146,6 +321,13 @@ namespace Subsurface
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Remove()
|
||||
{
|
||||
base.Remove();
|
||||
|
||||
WayPointList.Remove(this);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user