Monster syncing fixes:

- clients freeze and disable AI characters if no updates have been received in a while (due to the monster being far away from player-controlled characters at the servers side for example)
- server disables AI characters that are too far for updates to be sent to clients (-> targets of monster missions can't swim away from the spawnpos and cause the clients' sonars to point to an incorrect position)
This commit is contained in:
Regalis
2017-03-01 23:13:10 +02:00
parent 708a67caeb
commit 65625777e5
3 changed files with 41 additions and 21 deletions
+25 -1
View File
@@ -51,6 +51,22 @@ namespace Barotrauma
if (Controlled == this || !aiController.Enabled) return;
if (GameMain.Client != null)
{
//freeze AI characters if more than 1 seconds have passed since last update from the server
if (lastRecvPositionUpdateTime < NetTime.Now - 1.0f)
{
AnimController.Frozen = true;
memPos.Clear();
//hide after 2 seconds
if (lastRecvPositionUpdateTime < NetTime.Now - 2.0f)
{
Enabled = false;
return;
}
}
}
if (soundTimer > 0)
{
soundTimer -= deltaTime;
@@ -149,11 +165,12 @@ namespace Barotrauma
public override bool ReadNetworkData(NetworkEventType type, NetIncomingMessage message, float sendingTime, out object data)
{
data = null;
Enabled = true;
//server doesn't accept AICharacter updates from the clients
if (GameMain.Server != null) return false;
Enabled = true;
switch (type)
{
case NetworkEventType.KillCharacter:
@@ -198,6 +215,13 @@ namespace Barotrauma
case NetworkEventType.EntityUpdate:
if (sendingTime <= LastNetworkUpdate) return false;
if (GameMain.Client != null)
{
lastRecvPositionUpdateTime = (float)NetTime.Now;
AnimController.Frozen = false;
Enabled = true;
}
bool playerControlled = message.ReadBoolean();
if (playerControlled)
{
+9 -14
View File
@@ -20,14 +20,10 @@ namespace Barotrauma
public static bool DisableControls;
private UInt32 netStateID;
public UInt32 NetStateID
{
get { return netStateID; }
}
protected List<PosInfo> memPos = new List<PosInfo>();
protected float lastRecvPositionUpdateTime;
private bool networkUpdateSent;
//the Character that the player is currently controlling
@@ -58,6 +54,7 @@ namespace Barotrauma
}
set
{
if (value == enabled) return;
enabled = value;
foreach (Limb limb in AnimController.Limbs)
@@ -757,13 +754,6 @@ namespace Barotrauma
// AnimController.TargetDir = Direction.Right;
// }
//}
//else if (GameMain.Client != null && Character.controlled != this)
//{
// if (memPos.Count > 0)
// {
// AnimController.TargetDir = memPos[0].Direction;
// }
//}
if (attackCoolDown >0.0f)
{
@@ -1957,7 +1947,12 @@ namespace Barotrauma
break;
case NetworkEventType.EntityUpdate:
if (GameMain.Client != null) Enabled = true;
if (GameMain.Client != null)
{
lastRecvPositionUpdateTime = (float)NetTime.Now;
AnimController.Frozen = false;
Enabled = true;
}
Vector2 relativeCursorPos = Vector2.Zero;
+7 -6
View File
@@ -472,18 +472,19 @@ namespace Barotrauma.Networking
// }
//}
float ignoreDistance = FarseerPhysics.ConvertUnits.ToDisplayUnits(NetConfig.CharacterIgnoreDistance);
foreach (Character c in Character.CharacterList)
{
if (c.IsDead) continue;
if (c is AICharacter)
{
//todo: take multiple subs into account
//Vector2 diff = c.WorldPosition - Submarine.MainSub.WorldPosition;
//if (FarseerPhysics.ConvertUnits.ToSimUnits(diff.Length()) > NetConfig.CharacterIgnoreDistance) continue;
c.Enabled =
(myCharacter != null && Vector2.Distance(myCharacter.WorldPosition, c.WorldPosition) < ignoreDistance) ||
Character.CharacterList.Any(c2 => c2.IsRemotePlayer && Vector2.Distance(c2.WorldPosition, c.WorldPosition) < ignoreDistance);
}
if (c.IsDead) continue;
new NetworkEvent(NetworkEventType.ImportantEntityUpdate, c.ID, false);
}