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:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user