Networking optimization/bugfixes (hull water volumes & wall damage are synced, more reliable inventory updates, AICharacter sync changes), proper particle collisions with walls
This commit is contained in:
@@ -68,7 +68,7 @@ namespace Subsurface
|
||||
float cameraDist = Vector2.Distance(GameMain.GameScreen.Cam.Position, displayPosition)/2.0f;
|
||||
GameMain.GameScreen.Cam.Shake = CameraShake * Math.Max((displayRange - cameraDist)/displayRange, 0.0f);
|
||||
|
||||
if (attack.StructureDamage > 0.0f)
|
||||
if (attack.GetStructureDamage(1.0f) > 0.0f)
|
||||
{
|
||||
List<Structure> structureList = new List<Structure>();
|
||||
|
||||
@@ -91,11 +91,13 @@ namespace Subsurface
|
||||
for (int i = 0; i < structure.SectionCount; i++)
|
||||
{
|
||||
float distFactor = 1.0f - (Vector2.Distance(structure.SectionPosition(i), displayPosition) / displayRange);
|
||||
if (distFactor > 0.0f) structure.AddDamage(i, attack.StructureDamage*distFactor);
|
||||
if (distFactor > 0.0f) structure.AddDamage(i, attack.GetStructureDamage(1.0f)*distFactor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (force == 0.0f && attack.Stun == 0.0f && attack.GetDamage(1.0f) == 0.0f) return;
|
||||
|
||||
foreach (Character c in Character.CharacterList)
|
||||
{
|
||||
float dist = Vector2.Distance(c.SimPosition, simPosition);
|
||||
@@ -109,7 +111,7 @@ namespace Subsurface
|
||||
distFactor = 1.0f - Vector2.Distance(limb.SimPosition, simPosition)/attack.Range;
|
||||
|
||||
c.AddDamage(limb.SimPosition, DamageType.None,
|
||||
attack.Damage / c.AnimController.Limbs.Length * distFactor, 0.0f, attack.Stun * distFactor, true);
|
||||
attack.GetDamage(1.0f) / c.AnimController.Limbs.Length * distFactor, 0.0f, attack.Stun * distFactor, true);
|
||||
if (force>0.0f)
|
||||
{
|
||||
limb.body.ApplyLinearImpulse(Vector2.Normalize(limb.SimPosition - simPosition) * distFactor * force);
|
||||
|
||||
@@ -10,6 +10,8 @@ namespace Subsurface
|
||||
{
|
||||
class Gap : MapEntity
|
||||
{
|
||||
public static List<Gap> GapList = new List<Gap>();
|
||||
|
||||
public bool isHorizontal;
|
||||
|
||||
//private Sound waterSound;
|
||||
@@ -53,21 +55,8 @@ namespace Subsurface
|
||||
}
|
||||
|
||||
public Gap(Rectangle newRect)
|
||||
: this(newRect, (newRect.Width < newRect.Height))
|
||||
{
|
||||
rect = newRect;
|
||||
linkedTo = new ObservableCollection<MapEntity>();
|
||||
|
||||
//waterSound = new Sound("waterstream", 0.0f);
|
||||
|
||||
flowForce = Vector2.Zero;
|
||||
|
||||
isHorizontal = (rect.Width < rect.Height);
|
||||
|
||||
open = 1.0f;
|
||||
|
||||
FindHulls();
|
||||
|
||||
mapEntityList.Add(this);
|
||||
}
|
||||
|
||||
public Gap(Rectangle newRect, bool isHorizontal)
|
||||
@@ -83,15 +72,15 @@ namespace Subsurface
|
||||
|
||||
FindHulls();
|
||||
|
||||
GapList.Add(this);
|
||||
mapEntityList.Add(this);
|
||||
}
|
||||
|
||||
public static void UpdateHulls()
|
||||
{
|
||||
foreach (MapEntity entity in mapEntityList)
|
||||
foreach (Gap g in Gap.GapList)
|
||||
{
|
||||
Gap g = entity as Gap;
|
||||
if (g != null) g.FindHulls();
|
||||
g.FindHulls();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,17 +262,19 @@ namespace Subsurface
|
||||
Vector2 pos = Position;
|
||||
if (isHorizontal)
|
||||
{
|
||||
pos.Y = MathHelper.Clamp(lowerSurface, rect.Y - rect.Height, rect.Y);
|
||||
pos.X += Math.Sign(flowForce.X);
|
||||
pos.Y = MathHelper.Clamp((higherSurface+lowerSurface)/2.0f, rect.Y - rect.Height, rect.Y);
|
||||
|
||||
Vector2 velocity = new Vector2(
|
||||
MathHelper.Clamp(flowForce.X, -5000.0f, 5000.0f) * Rand.Range(0.5f, 0.7f),
|
||||
flowForce.Y * Rand.Range(0.5f, 0.7f));
|
||||
|
||||
var particle = GameMain.ParticleManager.CreateParticle("watersplash",
|
||||
new Vector2(pos.X, pos.Y - Rand.Range(0.0f, 10.0f)),
|
||||
new Vector2(
|
||||
MathHelper.Clamp(flowForce.X, -5000.0f, 5000.0f) * Rand.Range(0.5f, 0.7f),
|
||||
flowForce.Y * Rand.Range(0.5f, 0.7f)));
|
||||
new Vector2(pos.X, pos.Y - Rand.Range(0.0f, 10.0f)), velocity);
|
||||
|
||||
if (particle != null)
|
||||
{
|
||||
particle.Size = particle.Size * Math.Abs(flowForce.X / 1000.0f);
|
||||
|
||||
}
|
||||
|
||||
pos.Y = Rand.Range(lowerSurface, rect.Y - rect.Height);
|
||||
@@ -296,8 +287,13 @@ namespace Subsurface
|
||||
for (int i = 0; i < rect.Width; i += (int)Rand.Range(80, 100))
|
||||
{
|
||||
pos.X = Rand.Range(rect.X, rect.X + rect.Width);
|
||||
Subsurface.Particles.Particle splash = GameMain.ParticleManager.CreateParticle("watersplash", pos,
|
||||
new Vector2(0, Math.Max(flowForce.Y * Rand.Range(0.5f, 0.8f), 0.0f)));
|
||||
|
||||
Vector2 velocity = new Vector2(
|
||||
flowForce.X * Rand.Range(0.5f, 0.7f),
|
||||
Math.Max(flowForce.Y,-100.0f) * Rand.Range(0.5f, 0.7f));
|
||||
|
||||
var splash = GameMain.ParticleManager.CreateParticle("watersplash", pos,
|
||||
velocity);
|
||||
|
||||
if (splash != null) splash.Size = splash.Size * MathHelper.Clamp(rect.Width / 50.0f, 0.8f, 4.0f);
|
||||
|
||||
@@ -327,7 +323,7 @@ namespace Subsurface
|
||||
//horizontal gap (such as a regular door)
|
||||
if (isHorizontal)
|
||||
{
|
||||
//higherSurface = Math.Min(hull1.Surface,hull2.Surface);
|
||||
higherSurface = Math.Max(hull1.Surface,hull2.Surface);
|
||||
float delta=0.0f;
|
||||
//water level is above the lower boundary of the gap
|
||||
if (Math.Max(hull1.Surface+hull1.WaveY[hull1.WaveY.Length - 1], hull2.Surface+hull2.WaveY[0]) > rect.Y - size)
|
||||
@@ -453,6 +449,8 @@ namespace Subsurface
|
||||
|
||||
flowForce = new Vector2(0.0f,-delta);
|
||||
|
||||
flowForce.X = hull1.WaveY[hull1.GetWaveIndex(rect.X)] - hull1.WaveY[hull1.GetWaveIndex(rect.Right)] * 10.0f;
|
||||
|
||||
//if (water2.Volume < water2.FullVolume - Hull.MaxCompress)
|
||||
//{
|
||||
// int posX = (int)((rect.X + size / 2.0f - water1.Rect.X) / Hull.WaveWidth);
|
||||
@@ -569,6 +567,8 @@ namespace Subsurface
|
||||
{
|
||||
base.Remove();
|
||||
|
||||
GapList.Remove(this);
|
||||
|
||||
if (soundIndex > -1) Sounds.SoundManager.Stop(soundIndex);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,8 @@ namespace Subsurface
|
||||
float[] leftDelta;
|
||||
float[] rightDelta;
|
||||
|
||||
float lastSentVolume;
|
||||
|
||||
public override bool IsLinkable
|
||||
{
|
||||
get { return true; }
|
||||
@@ -73,7 +75,8 @@ namespace Subsurface
|
||||
{
|
||||
get { return volume; }
|
||||
set
|
||||
{
|
||||
{
|
||||
if (!MathUtils.IsValid(value)) return;
|
||||
volume = MathHelper.Clamp(value, 0.0f, FullVolume + MaxCompress);
|
||||
if (volume < FullVolume) Pressure = rect.Y - rect.Height + volume / rect.Width;
|
||||
if (volume > 0.0f) update = true;
|
||||
@@ -155,8 +158,13 @@ namespace Subsurface
|
||||
|
||||
public int GetWaveIndex(Vector2 position)
|
||||
{
|
||||
int index = (int)(position.X - rect.X) / WaveWidth;
|
||||
index = (int)MathHelper.Clamp(index, 0, waveY.Length-1);
|
||||
return GetWaveIndex(position.X);
|
||||
}
|
||||
|
||||
public int GetWaveIndex(float xPos)
|
||||
{
|
||||
int index = (int)(xPos - rect.X) / WaveWidth;
|
||||
index = (int)MathHelper.Clamp(index, 0, waveY.Length - 1);
|
||||
return index;
|
||||
}
|
||||
|
||||
@@ -202,6 +210,12 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
//update client hulls if the amount of water has changed by >10%
|
||||
if (Math.Abs(lastSentVolume-volume)>FullVolume*0.1f)
|
||||
{
|
||||
new Networking.NetworkEvent(ID, false);
|
||||
lastSentVolume = volume;
|
||||
}
|
||||
|
||||
if (!update) return;
|
||||
|
||||
@@ -254,9 +268,9 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
if (volume<FullVolume)
|
||||
if (volume < FullVolume)
|
||||
{
|
||||
LethalPressure -= 0.5f;
|
||||
LethalPressure -= 10.0f * deltaTime;
|
||||
if (Volume == 0.0f)
|
||||
{
|
||||
for (int i = 1; i < waveY.Length - 1; i++)
|
||||
@@ -268,7 +282,7 @@ namespace Subsurface
|
||||
}
|
||||
else
|
||||
{
|
||||
LethalPressure += 1.0f;
|
||||
LethalPressure += 10.0f * deltaTime;
|
||||
}
|
||||
|
||||
|
||||
@@ -402,12 +416,17 @@ namespace Subsurface
|
||||
//returns the water block which contains the point (or null if it isn't inside any)
|
||||
public static Hull FindHull(Vector2 position, Hull guess = null)
|
||||
{
|
||||
if (guess != null && hullList.Contains(guess))
|
||||
return FindHull(position, hullList, guess);
|
||||
}
|
||||
|
||||
public static Hull FindHull(Vector2 position, List<Hull> hulls, Hull guess = null)
|
||||
{
|
||||
if (guess != null && hulls.Contains(guess))
|
||||
{
|
||||
if (Submarine.RectContains(guess.rect, position)) return guess;
|
||||
}
|
||||
|
||||
foreach (Hull w in hullList)
|
||||
foreach (Hull w in hulls)
|
||||
{
|
||||
if (Submarine.RectContains(w.rect, position)) return w;
|
||||
}
|
||||
@@ -445,6 +464,28 @@ namespace Subsurface
|
||||
|
||||
h.ID = int.Parse(element.Attribute("ID").Value);
|
||||
}
|
||||
|
||||
public override void FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetOutgoingMessage message, object data)
|
||||
{
|
||||
message.Write(volume);
|
||||
}
|
||||
|
||||
public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message)
|
||||
{
|
||||
float newVolume = this.volume;
|
||||
|
||||
try
|
||||
{
|
||||
newVolume = message.ReadFloat();
|
||||
}
|
||||
|
||||
catch
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Volume = newVolume;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,6 @@ namespace Subsurface
|
||||
get;
|
||||
}
|
||||
|
||||
AttackResult AddDamage(IDamageable attacker, Vector2 position, Attack attack, bool playSound=true);
|
||||
AttackResult AddDamage(IDamageable attacker, Vector2 position, Attack attack, float deltaTime, bool playSound=true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,7 +417,7 @@ int currentTargetIndex = 1;
|
||||
}
|
||||
if (allowedEdges.Count==0)
|
||||
{
|
||||
edgeIndex = 0;
|
||||
edgeIndex = rand.Next() % currentCell.edges.Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -21,6 +21,10 @@ namespace Subsurface
|
||||
public float damage;
|
||||
public Gap gap;
|
||||
|
||||
public float lastSentDamage;
|
||||
|
||||
public float lastUpdate;
|
||||
|
||||
public bool isHighLighted;
|
||||
|
||||
public WallSection(Rectangle rect)
|
||||
@@ -412,7 +416,7 @@ namespace Subsurface
|
||||
sections[sectionIndex].rect.Y - sections[sectionIndex].rect.Height / 2.0f);
|
||||
}
|
||||
|
||||
public AttackResult AddDamage(IDamageable attacker, Vector2 position, Attack attack, bool playSound = false)
|
||||
public AttackResult AddDamage(IDamageable attacker, Vector2 position, Attack attack, float deltaTime, bool playSound = false)
|
||||
{
|
||||
if (!prefab.HasBody || prefab.IsPlatform) return new AttackResult(0.0f, 0.0f);
|
||||
|
||||
@@ -421,23 +425,29 @@ namespace Subsurface
|
||||
|
||||
GameMain.ParticleManager.CreateParticle("dustcloud", SectionPosition(i), 0.0f, 0.0f);
|
||||
|
||||
float damageAmount = attack.GetStructureDamage(deltaTime);
|
||||
|
||||
if (playSound && !SectionHasHole(i))
|
||||
{
|
||||
DamageSoundType damageSoundType = (attack.DamageType == DamageType.Blunt) ? DamageSoundType.StructureBlunt : DamageSoundType.StructureSlash;
|
||||
AmbientSoundManager.PlayDamageSound(damageSoundType, attack.Damage, position);
|
||||
AmbientSoundManager.PlayDamageSound(damageSoundType, damageAmount, position);
|
||||
}
|
||||
|
||||
AddDamage(i, attack.Damage);
|
||||
AddDamage(i, damageAmount);
|
||||
|
||||
return new AttackResult(attack.Damage, 0.0f);
|
||||
return new AttackResult(damageAmount, 0.0f);
|
||||
}
|
||||
|
||||
private void SetDamage(int sectionIndex, float damage)
|
||||
{
|
||||
if (!prefab.HasBody) return;
|
||||
|
||||
if (damage != sections[sectionIndex].damage)
|
||||
if (damage != sections[sectionIndex].damage && Math.Abs(sections[sectionIndex].lastSentDamage - damage)>5.0f)
|
||||
{
|
||||
new NetworkEvent(NetworkEventType.UpdateEntity, ID, false, sectionIndex);
|
||||
sections[sectionIndex].lastSentDamage = damage;
|
||||
|
||||
}
|
||||
|
||||
if (damage < prefab.MaxHealth*0.5f)
|
||||
{
|
||||
@@ -637,6 +647,7 @@ namespace Subsurface
|
||||
return;
|
||||
}
|
||||
|
||||
message.Write((float)NetTime.Now);
|
||||
message.Write(byteIndex);
|
||||
message.Write(sections[sectionIndex].damage);
|
||||
}
|
||||
@@ -645,9 +656,11 @@ namespace Subsurface
|
||||
{
|
||||
int sectionIndex = 0;
|
||||
float damage = 0.0f;
|
||||
float updateTime = 0.0f;
|
||||
|
||||
try
|
||||
{
|
||||
updateTime = message.ReadFloat();
|
||||
sectionIndex = message.ReadByte();
|
||||
damage = message.ReadFloat();
|
||||
}
|
||||
@@ -656,6 +669,9 @@ namespace Subsurface
|
||||
return;
|
||||
}
|
||||
|
||||
if (sections[sectionIndex].lastUpdate != 0.0f && updateTime < sections[sectionIndex].lastUpdate) return;
|
||||
|
||||
sections[sectionIndex].lastUpdate = updateTime;
|
||||
SetDamage(sectionIndex, damage);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user