Admin can play in multiplayer, backgroundsprites, fixrequirement bugfix, the condition of the reactor won't detoriate when it's running

This commit is contained in:
Regalis
2015-09-04 12:57:12 +03:00
parent 25242fe913
commit 2f08dcf3f9
21 changed files with 547 additions and 114 deletions

View File

@@ -15,8 +15,6 @@ namespace Subsurface
{
get;
}
Vector2 Position
{

View File

@@ -0,0 +1,208 @@
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 Subsurface
{
class BackgroundSprite : ISteerable
{
const float MaxDepth = 100.0f;
const float CheckWallsInterval = 5.0f;
private BackgroundSpritePrefab prefab;
private Vector2 position;
private Vector3 velocity;
private float depth;
private SteeringManager steeringManager;
private float checkWallsTimer;
public Swarm Swarm;
public Vector2 Position
{
get { return position; }
}
public Vector2 Velocity
{
get { return new Vector2(velocity.X, velocity.Y); }
}
public Vector2 Steering
{
get;
set;
}
public BackgroundSprite(BackgroundSpritePrefab prefab, Vector2 position)
{
this.prefab = prefab;
this.position = position;
steeringManager = new SteeringManager(this);
velocity = new Vector3(
Rand.Range(-prefab.Speed, prefab.Speed),
Rand.Range(-prefab.Speed, prefab.Speed),
Rand.Range(0.0f, prefab.WanderZAmount));
}
float ang;
Vector2 obstacleDiff;
public void Update(float deltaTime)
{
position += new Vector2(velocity.X, velocity.Y) * deltaTime;
depth = MathHelper.Clamp(depth + velocity.Z * deltaTime, 0.0f, MaxDepth);
checkWallsTimer -= deltaTime;
if (checkWallsTimer<=0.0f)
{
checkWallsTimer = CheckWallsInterval;
obstacleDiff = Vector2.Zero;
var cells = Level.Loaded.GetCells(position, 1);
if (cells.Count>0)
{
foreach (Voronoi2.VoronoiCell cell in cells)
{
obstacleDiff += cell.Center - position;
}
obstacleDiff = Vector2.Normalize(obstacleDiff)*prefab.Speed;
}
}
if (Swarm!=null)
{
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);
}
}
if (prefab.WanderAmount > 0.0f)
{
steeringManager.SteeringWander(prefab.Speed);
}
if (obstacleDiff != Vector2.Zero)
{
steeringManager.SteeringSeek(-obstacleDiff, prefab.Speed);
}
steeringManager.Update(prefab.Speed);
if (prefab.WanderZAmount>0.0f)
{
ang += Rand.Range(-prefab.WanderZAmount, prefab.WanderZAmount);
velocity.Z = (float)Math.Sin(ang)*prefab.Speed;
}
velocity = Vector3.Lerp(velocity, new Vector3(Steering.X, Steering.Y, velocity.Z), deltaTime);
}
public void Draw(SpriteBatch spriteBatch)
{
float rotation = 0.0f;
if (!prefab.DisableRotation)
{
rotation = MathUtils.VectorToAngle(new Vector2(velocity.X, -velocity.Y));
if (velocity.X < 0.0f) rotation -= MathHelper.Pi;
}
Vector2 drawPos = position + Level.Loaded.Position;
if (depth > 0.0f)
{
Vector2 camOffset = drawPos - Game1.GameScreen.Cam.WorldViewCenter;
drawPos = drawPos - camOffset * (depth / MaxDepth) * 0.05f;
}
prefab.Sprite.Draw(spriteBatch, new Vector2(drawPos.X, -drawPos.Y), Color.Lerp(Color.White, Color.DarkBlue, (depth/MaxDepth)*0.3f),
rotation, 1.0f - (depth / MaxDepth) * 0.2f, velocity.X > 0.0f ? SpriteEffects.None : SpriteEffects.FlipHorizontally, (depth / MaxDepth));
}
}
class Swarm
{
public List<BackgroundSprite> Members;
public readonly float MaxDistance;
public Vector2 MidPoint()
{
if (Members.Count == 0) return Vector2.Zero;
Vector2 midPoint = Vector2.Zero;
foreach (BackgroundSprite member in Members)
{
midPoint += member.Position;
}
midPoint /= Members.Count;
return midPoint;
}
public Vector2 AvgVelocity()
{
if (Members.Count == 0) return Vector2.Zero;
Vector2 avgVel = Vector2.Zero;
foreach (BackgroundSprite member in Members)
{
avgVel += member.Velocity;
}
avgVel /= Members.Count;
return avgVel;
}
public Swarm(List<BackgroundSprite> members, float maxDistance)
{
this.Members = members;
this.MaxDistance = maxDistance;
foreach (BackgroundSprite bgSprite in members)
{
bgSprite.Swarm = this;
}
}
}
}

View File

@@ -0,0 +1,74 @@
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 Subsurface
{
class BackgroundSpriteManager
{
const int MaxSprites = 100;
private List<BackgroundSpritePrefab> prefabs;
private List<BackgroundSprite> activeSprites;
public BackgroundSpriteManager(string configPath)
{
XDocument doc = ToolBox.TryLoadXml(configPath);
if (doc == null) return;
activeSprites = new List<BackgroundSprite>();
prefabs = new List<BackgroundSpritePrefab>();
foreach (XElement element in doc.Root.Elements())
{
prefabs.Add(new BackgroundSpritePrefab(element));
}
}
public void Update(float deltaTime)
{
if (activeSprites.Count < MaxSprites)
{
WayPoint wp = WayPoint.WayPointList[Rand.Int(WayPoint.WayPointList.Count)];
Vector2 pos = new Vector2(wp.Rect.X, wp.Rect.Y);
pos += Rand.Vector(200.0f);
var prefab = prefabs[Rand.Int(prefabs.Count)];
int amount = Rand.Range(prefab.SwarmMin,prefab.SwarmMax);
List<BackgroundSprite> swarmMembers = new List<BackgroundSprite>();
for (int i = 0; i<amount; i++)
{
var newSprite = new BackgroundSprite(prefab, pos);
activeSprites.Add(newSprite);
swarmMembers.Add(newSprite);
}
if (amount>0)
{
Swarm swarm = new Swarm(swarmMembers, prefab.SwarmRadius);
}
}
foreach (BackgroundSprite sprite in activeSprites)
{
sprite.Update(deltaTime);
}
}
public void Draw(SpriteBatch spriteBatch)
{
foreach (BackgroundSprite sprite in activeSprites)
{
sprite.Draw(spriteBatch);
}
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Subsurface
{
class BackgroundSpritePrefab
{
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 BackgroundSpritePrefab(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

@@ -1123,7 +1123,7 @@ namespace Subsurface
else if (type == NetworkEventType.KillCharacter)
{
Kill(true);
if (Game1.Client != null && controlled == this)
if (Game1.NetworkMember != null && controlled == this)
{
Game1.Client.AddChatMessage("YOU HAVE DIED. Your chat messages will only be visible to other dead players.", ChatMessageType.Dead);
Game1.LightManager.LosEnabled = false;

View File

@@ -607,7 +607,8 @@ namespace Subsurface
}
else
{
correctionMovement = Vector2.Normalize(newMovement) * Math.Min(1.0f + dist, 3.0f);
correctionMovement = Vector2.Normalize(newMovement) * Math.Min(1.0f + dist, 3.0f);
if (Math.Abs(correctionMovement.Y) < 0.1f) correctionMovement.Y = 0.0f;
}
}