more accurate submarine body generation, multiplayer fixes, saving takes HiddenSubPosition into account, fire coordinate fixes, editscreen fixes, checking item triggers in AIObjectiveGoto, netlobbyscreen sync fixes, re-enabled level start/end positions, water edit fixed

This commit is contained in:
Regalis
2015-12-17 18:26:40 +02:00
parent 859be53d28
commit af470eab2e
53 changed files with 1065 additions and 427 deletions

View File

@@ -9,7 +9,7 @@ using System.Xml.Linq;
namespace Barotrauma
{
class BackgroundSprite : ISteerable
class BackgroundCreature : ISteerable
{
const float MaxDepth = 100.0f;
@@ -17,7 +17,7 @@ namespace Barotrauma
public bool Enabled;
private BackgroundSpritePrefab prefab;
private BackgroundCreaturePrefab prefab;
private Vector2 position;
@@ -53,7 +53,7 @@ namespace Barotrauma
set;
}
public BackgroundSprite(BackgroundSpritePrefab prefab, Vector2 position)
public BackgroundCreature(BackgroundCreaturePrefab prefab, Vector2 position)
{
this.prefab = prefab;
@@ -105,18 +105,6 @@ namespace Barotrauma
Vector2 midPoint = Swarm.MidPoint();
float midPointDist = Vector2.Distance(position, midPoint);
//steeringManager.SteeringSeek(midPoint + Swarm.AvgVelocity()*1000.0f, prefab.Speed*0.1f);
//float avgWanderAngle = 0.0f;
//foreach (var other in Swarm.Members)
//{
// avgWanderAngle += other.steeringManager.WanderAngle;
//}
//avgWanderAngle /= Swarm.Members.Count;
//steeringManager.WanderAngle = MathHelper.Lerp(steeringManager.WanderAngle, avgWanderAngle, 0.1f);
if (midPointDist > Swarm.MaxDistance)
{
steeringManager.SteeringSeek(midPoint, (midPointDist / Swarm.MaxDistance) * prefab.Speed);
@@ -169,7 +157,7 @@ namespace Barotrauma
class Swarm
{
public List<BackgroundSprite> Members;
public List<BackgroundCreature> Members;
public readonly float MaxDistance;
@@ -179,7 +167,7 @@ namespace Barotrauma
Vector2 midPoint = Vector2.Zero;
foreach (BackgroundSprite member in Members)
foreach (BackgroundCreature member in Members)
{
midPoint += member.SimPosition;
}
@@ -195,7 +183,7 @@ namespace Barotrauma
Vector2 avgVel = Vector2.Zero;
foreach (BackgroundSprite member in Members)
foreach (BackgroundCreature member in Members)
{
avgVel += member.Velocity;
}
@@ -205,13 +193,13 @@ namespace Barotrauma
return avgVel;
}
public Swarm(List<BackgroundSprite> members, float maxDistance)
public Swarm(List<BackgroundCreature> members, float maxDistance)
{
this.Members = members;
this.MaxDistance = maxDistance;
foreach (BackgroundSprite bgSprite in members)
foreach (BackgroundCreature bgSprite in members)
{
bgSprite.Swarm = this;
}

View File

@@ -0,0 +1,125 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Barotrauma
{
class BackgroundCreatureManager
{
const int MaxSprites = 100;
const float checkActiveInterval = 1.0f;
float checkActiveTimer;
private List<BackgroundCreaturePrefab> prefabs;
private List<BackgroundCreature> activeSprites;
public BackgroundCreatureManager(string configPath)
{
activeSprites = new List<BackgroundCreature>();
prefabs = new List<BackgroundCreaturePrefab>();
XDocument doc = ToolBox.TryLoadXml(configPath);
if (doc == null || doc.Root == null) return;
foreach (XElement element in doc.Root.Elements())
{
prefabs.Add(new BackgroundCreaturePrefab(element));
}
}
public void SpawnSprites(int count, Vector2? position = null)
{
activeSprites.Clear();
if (prefabs.Count == 0) return;
count = Math.Min(count, MaxSprites);
for (int i = 0; i < count; i++ )
{
Vector2 pos = Vector2.Zero;
if (position == null)
{
var wayPoints = WayPoint.WayPointList.FindAll(wp => wp.Submarine==null);
if (wayPoints.Any())
{
WayPoint wp = wayPoints[Rand.Int(wayPoints.Count)];
pos = new Vector2(wp.Rect.X, wp.Rect.Y);
pos += Rand.Vector(200.0f);
}
else
{
pos = Rand.Vector(2000.0f);
}
}
else
{
pos = (Vector2)position;
}
var prefab = prefabs[Rand.Int(prefabs.Count)];
int amount = Rand.Range(prefab.SwarmMin, prefab.SwarmMax);
List<BackgroundCreature> swarmMembers = new List<BackgroundCreature>();
for (int n = 0; n < amount; n++)
{
var newSprite = new BackgroundCreature(prefab, pos);
activeSprites.Add(newSprite);
swarmMembers.Add(newSprite);
}
if (amount > 0)
{
new Swarm(swarmMembers, prefab.SwarmRadius);
}
}
}
public void ClearSprites()
{
activeSprites.Clear();
}
public void Update(Camera cam, float deltaTime)
{
if (checkActiveTimer<0.0f)
{
foreach (BackgroundCreature sprite in activeSprites)
{
sprite.Enabled = (Math.Abs(sprite.TransformedPosition.X - cam.WorldViewCenter.X) < 4000.0f &&
Math.Abs(sprite.TransformedPosition.Y - cam.WorldViewCenter.Y) < 4000.0f);
}
checkActiveTimer = checkActiveInterval;
}
else
{
checkActiveTimer -= deltaTime;
}
foreach (BackgroundCreature sprite in activeSprites)
{
if (!sprite.Enabled) continue;
sprite.Update(deltaTime);
}
}
public void Draw(SpriteBatch spriteBatch)
{
foreach (BackgroundCreature sprite in activeSprites)
{
if (!sprite.Enabled) continue;
sprite.Draw(spriteBatch);
}
}
}
}

View File

@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Barotrauma
{
class BackgroundCreaturePrefab
{
public readonly Sprite Sprite;
public readonly float Speed;
public readonly float WanderAmount;
public readonly float WanderZAmount;
public readonly int SwarmMin, SwarmMax;
public readonly float SwarmRadius;
public readonly bool DisableRotation;
public BackgroundCreaturePrefab(XElement element)
{
Speed = ToolBox.GetAttributeFloat(element, "speed", 1.0f);
WanderAmount = ToolBox.GetAttributeFloat(element, "wanderamount", 0.0f);
WanderZAmount = ToolBox.GetAttributeFloat(element, "wanderzamount", 0.0f);
SwarmMin = ToolBox.GetAttributeInt(element, "swarmmin", 1);
SwarmMax = ToolBox.GetAttributeInt(element, "swarmmax", 1);
SwarmRadius = ToolBox.GetAttributeFloat(element, "swarmradius", 200.0f);
DisableRotation = ToolBox.GetAttributeBool(element, "disablerotation", false);
foreach (XElement subElement in element.Elements())
{
if (subElement.Name.ToString().ToLower() != "sprite") continue;
Sprite = new Sprite(subElement);
break;
}
}
}
}

View File

@@ -5,23 +5,30 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Voronoi2;
namespace Barotrauma
{
class BackgroundSprite
{
public readonly BackgroundSpritePrefab Prefab;
public Vector2 Position;
public BackgroundSprite(BackgroundSpritePrefab prefab, Vector2 position)
{
this.Prefab = prefab;
this.Position = position;
}
}
class BackgroundSpriteManager
{
const int MaxSprites = 100;
const float checkActiveInterval = 1.0f;
float checkActiveTimer;
private List<BackgroundSpritePrefab> prefabs;
private List<BackgroundSprite> activeSprites;
private List<BackgroundSprite> sprites;
public BackgroundSpriteManager(string configPath)
{
activeSprites = new List<BackgroundSprite>();
sprites = new List<BackgroundSprite>();
prefabs = new List<BackgroundSpritePrefab>();
XDocument doc = ToolBox.TryLoadXml(configPath);
@@ -33,93 +40,92 @@ namespace Barotrauma
}
}
public void SpawnSprites(int count, Vector2? position = null)
public void PlaceSprites(Level level, int amount)
{
activeSprites.Clear();
sprites.Clear();
if (prefabs.Count == 0) return;
count = Math.Min(count, MaxSprites);
for (int i = 0; i < count; i++ )
for (int i = 0 ; i <amount; i++)
{
Vector2 pos = Vector2.Zero;
BackgroundSpritePrefab prefab = GetRandomPrefab();
Vector2 pos = FindSpritePosition(level, prefab);
if (position == null)
{
var wayPoints = WayPoint.WayPointList.FindAll(wp => wp.Submarine==null);
if (wayPoints.Any())
{
WayPoint wp = wayPoints[Rand.Int(wayPoints.Count)];
pos = new Vector2(wp.Rect.X, wp.Rect.Y);
pos += Rand.Vector(200.0f);
}
else
{
pos = Rand.Vector(2000.0f);
}
}
else
{
pos = (Vector2)position;
}
var prefab = prefabs[Rand.Int(prefabs.Count)];
int amount = Rand.Range(prefab.SwarmMin, prefab.SwarmMax);
List<BackgroundSprite> swarmMembers = new List<BackgroundSprite>();
for (int n = 0; n < amount; n++)
{
var newSprite = new BackgroundSprite(prefab, pos);
activeSprites.Add(newSprite);
swarmMembers.Add(newSprite);
}
if (amount > 0)
{
new Swarm(swarmMembers, prefab.SwarmRadius);
}
sprites.Add(new BackgroundSprite(prefab, pos));
}
}
public void ClearSprites()
private Vector2 FindSpritePosition(Level level, BackgroundSpritePrefab prefab)
{
activeSprites.Clear();
Vector2 randomPos = new Vector2(Rand.Range(0.0f, level.Size.X), Rand.Range(0.0f, level.Size.Y));
var cells = level.GetCells(randomPos);
if (!cells.Any()) return Vector2.Zero;
VoronoiCell cell = cells[Rand.Int(cells.Count)];
GraphEdge bestEdge = null;
foreach (GraphEdge edge in cell.edges)
{
if (prefab.Alignment.HasFlag(Alignment.Bottom))
{
if (bestEdge == null || edge.Center.Y > bestEdge.Center.Y) bestEdge = edge;
}
else if (prefab.Alignment.HasFlag(Alignment.Top))
{
if (bestEdge == null || edge.Center.Y < bestEdge.Center.Y) bestEdge = edge;
}
else if (prefab.Alignment.HasFlag(Alignment.Left))
{
if (bestEdge == null || edge.Center.X > bestEdge.Center.X) bestEdge = edge;
}
else if (prefab.Alignment.HasFlag(Alignment.Right))
{
if (bestEdge == null || edge.Center.X < bestEdge.Center.X) bestEdge = edge;
}
}
Vector2 dir = Vector2.Normalize(bestEdge.point1 - bestEdge.point2);
Vector2 pos = bestEdge.Center;
if (prefab.Alignment.HasFlag(Alignment.Bottom))
{
pos.Y -= Math.Abs(dir.Y) * prefab.Sprite.size.X/Math.Abs(dir.X);
}
else if (prefab.Alignment.HasFlag(Alignment.Top))
{
pos.Y += Math.Abs(dir.Y) * prefab.Sprite.size.X/Math.Abs(dir.X);
}
return pos;
}
public void Update(Camera cam, float deltaTime)
public void DrawSprites(SpriteBatch spriteBatch)
{
if (checkActiveTimer<0.0f)
foreach (BackgroundSprite sprite in sprites)
{
foreach (BackgroundSprite sprite in activeSprites)
sprite.Prefab.Sprite.Draw(spriteBatch, new Vector2(sprite.Position.X, -sprite.Position.Y));
}
}
private BackgroundSpritePrefab GetRandomPrefab()
{
int totalCommonness = 0;
foreach (BackgroundSpritePrefab prefab in prefabs)
{
totalCommonness += prefab.Commonness;
}
float randomNumber = Rand.Int(totalCommonness+1);
foreach (BackgroundSpritePrefab prefab in prefabs)
{
if (randomNumber <= prefab.Commonness)
{
sprite.Enabled = (Math.Abs(sprite.TransformedPosition.X - cam.WorldViewCenter.X) < 4000.0f &&
Math.Abs(sprite.TransformedPosition.Y - cam.WorldViewCenter.Y) < 4000.0f);
return prefab;
}
checkActiveTimer = checkActiveInterval;
}
else
{
checkActiveTimer -= deltaTime;
randomNumber -= prefab.Commonness;
}
foreach (BackgroundSprite sprite in activeSprites)
{
if (!sprite.Enabled) continue;
sprite.Update(deltaTime);
}
}
public void Draw(SpriteBatch spriteBatch)
{
foreach (BackgroundSprite sprite in activeSprites)
{
if (!sprite.Enabled) continue;
sprite.Draw(spriteBatch);
}
return null;
}
}
}

View File

@@ -10,32 +10,17 @@ namespace Barotrauma
{
public readonly Sprite Sprite;
public readonly float Speed;
public readonly Alignment Alignment;
public readonly float WanderAmount;
public readonly int Commonness;
public readonly float WanderZAmount;
public readonly int SwarmMin, SwarmMax;
public readonly float SwarmRadius;
public readonly bool DisableRotation;
public BackgroundSpritePrefab(XElement element)
{
Speed = ToolBox.GetAttributeFloat(element, "speed", 1.0f);
string alignmentStr = ToolBox.GetAttributeString(element, "alignment", "BottomCenter");
WanderAmount = ToolBox.GetAttributeFloat(element, "wanderamount", 0.0f);
if (!Enum.TryParse(alignmentStr, out Alignment)) Alignment = Alignment.BottomCenter;
WanderZAmount = ToolBox.GetAttributeFloat(element, "wanderzamount", 0.0f);
SwarmMin = ToolBox.GetAttributeInt(element, "swarmmin", 1);
SwarmMax = ToolBox.GetAttributeInt(element, "swarmmax", 1);
SwarmRadius = ToolBox.GetAttributeFloat(element, "swarmradius", 200.0f);
DisableRotation = ToolBox.GetAttributeBool(element, "disablerotation", false);
Commonness = ToolBox.GetAttributeInt(element, "commonness", 1);
foreach (XElement subElement in element.Elements())
{
@@ -45,6 +30,6 @@ namespace Barotrauma
break;
}
}
}
}
}