Ejemplo n.º 1
0
        private void UpdateNetInput()
        {
            if (this != Character.Controlled)
            {
                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;
                        memState.Clear();
                        //hide after 2 seconds
                        if (lastRecvPositionUpdateTime < NetTime.Now - 2.0f)
                        {
                            Enabled = false;
                            return;
                        }
                    }
                }
                else if (GameMain.Server != null && (!(this is AICharacter) || IsRemotePlayer))
                {
                    if (!AllowInput)
                    {
                        AnimController.Frozen = false;
                        if (memInput.Count > 0)
                        {
                            prevDequeuedInput = dequeuedInput;
                            dequeuedInput     = memInput[memInput.Count - 1].states;
                            memInput.RemoveAt(memInput.Count - 1);
                        }
                    }
                    else if (memInput.Count == 0)
                    {
                        AnimController.Frozen = true;
                    }
                    else
                    {
                        AnimController.Frozen = false;
                        prevDequeuedInput     = dequeuedInput;

                        LastProcessedID = memInput[memInput.Count - 1].networkUpdateID;
                        dequeuedInput   = memInput[memInput.Count - 1].states;

                        double aimAngle = ((double)memInput[memInput.Count - 1].intAim / 65535.0) * 2.0 * Math.PI;
                        cursorPosition = (ViewTarget == null ? AnimController.AimSourcePos : ViewTarget.Position)
                                         + new Vector2((float)Math.Cos(aimAngle), (float)Math.Sin(aimAngle)) * 60.0f;

                        //reset focus when attempting to use/select something
                        if (memInput[memInput.Count - 1].states.HasFlag(InputNetFlags.Use) ||
                            memInput[memInput.Count - 1].states.HasFlag(InputNetFlags.Select))
                        {
                            focusedItem      = null;
                            focusedCharacter = null;
                        }
                        var closestEntity = FindEntityByID(memInput[memInput.Count - 1].interact);
                        if (closestEntity is Item)
                        {
                            if (CanInteractWith((Item)closestEntity))
                            {
                                focusedItem      = (Item)closestEntity;
                                focusedCharacter = null;
                            }
                        }
                        else if (closestEntity is Character)
                        {
                            if (CanInteractWith((Character)closestEntity))
                            {
                                focusedCharacter = (Character)closestEntity;
                                focusedItem      = null;
                            }
                        }

                        memInput.RemoveAt(memInput.Count - 1);

                        TransformCursorPos();

                        if ((dequeuedInput == InputNetFlags.None || dequeuedInput == InputNetFlags.FacingLeft) && Math.Abs(AnimController.Collider.LinearVelocity.X) < 0.005f && Math.Abs(AnimController.Collider.LinearVelocity.Y) < 0.2f)
                        {
                            while (memInput.Count > 5 && memInput[memInput.Count - 1].states == dequeuedInput)
                            {
                                //remove inputs where the player is not moving at all
                                //helps the server catch up, shouldn't affect final position
                                LastProcessedID = memInput[memInput.Count - 1].networkUpdateID;
                                memInput.RemoveAt(memInput.Count - 1);
                            }
                        }
                    }
                }
            }
            else if (GameMain.Client != null)
            {
                var posInfo = new CharacterStateInfo(
                    SimPosition,
                    AnimController.Collider.Rotation,
                    LastNetworkUpdateID,
                    AnimController.TargetDir,
                    SelectedCharacter == null ? (Entity)selectedConstruction : (Entity)SelectedCharacter,
                    AnimController.Anim);

                memLocalState.Add(posInfo);

                InputNetFlags newInput = InputNetFlags.None;
                if (IsKeyDown(InputType.Left))
                {
                    newInput |= InputNetFlags.Left;
                }
                if (IsKeyDown(InputType.Right))
                {
                    newInput |= InputNetFlags.Right;
                }
                if (IsKeyDown(InputType.Up))
                {
                    newInput |= InputNetFlags.Up;
                }
                if (IsKeyDown(InputType.Down))
                {
                    newInput |= InputNetFlags.Down;
                }
                if (IsKeyDown(InputType.Run))
                {
                    newInput |= InputNetFlags.Run;
                }
                if (IsKeyDown(InputType.Crouch))
                {
                    newInput |= InputNetFlags.Crouch;
                }
                if (IsKeyHit(InputType.Select))
                {
                    newInput |= InputNetFlags.Select;                                 //TODO: clean up the way this input is registered
                }
                if (IsKeyDown(InputType.Use))
                {
                    newInput |= InputNetFlags.Use;
                }
                if (IsKeyDown(InputType.Aim))
                {
                    newInput |= InputNetFlags.Aim;
                }
                if (IsKeyDown(InputType.Attack))
                {
                    newInput |= InputNetFlags.Attack;
                }
                if (IsKeyDown(InputType.Ragdoll))
                {
                    newInput |= InputNetFlags.Ragdoll;
                }

                if (AnimController.TargetDir == Direction.Left)
                {
                    newInput |= InputNetFlags.FacingLeft;
                }

                Vector2 relativeCursorPos = cursorPosition - (ViewTarget == null ? AnimController.AimSourcePos : ViewTarget.Position);
                relativeCursorPos.Normalize();
                UInt16 intAngle = (UInt16)(65535.0 * Math.Atan2(relativeCursorPos.Y, relativeCursorPos.X) / (2.0 * Math.PI));

                NetInputMem newMem = new NetInputMem();
                newMem.states = newInput;
                newMem.intAim = intAngle;
                if (focusedItem != null)
                {
                    newMem.interact = focusedItem.ID;
                }
                else if (focusedCharacter != null)
                {
                    newMem.interact = focusedCharacter.ID;
                }

                memInput.Insert(0, newMem);
                LastNetworkUpdateID++;
                if (memInput.Count > 60)
                {
                    memInput.RemoveRange(60, memInput.Count - 60);
                }
            }
            else //this == Character.Controlled && GameMain.Client == null
            {
                AnimController.Frozen = false;
            }

            if (networkUpdateSent)
            {
                foreach (Key key in keys)
                {
                    key.DequeueHit();
                    key.DequeueHeld();
                }

                networkUpdateSent = false;
            }
        }
        partial void UpdateNetInput()
        {
            if (GameMain.Client != null)
            {
                if (this != Controlled)
                {
                    if (GameMain.Client.EndCinematic != null &&
                        GameMain.Client.EndCinematic.Running) // Freezes the characters during the ending cinematic
                    {
                        AnimController.Frozen = true;
                        memState.Clear();
                        return;
                    }

                    //freeze AI characters if more than x seconds have passed since last update from the server
                    if (lastRecvPositionUpdateTime < Lidgren.Network.NetTime.Now - NetConfig.FreezeCharacterIfPositionDataMissingDelay)
                    {
                        AnimController.Frozen = true;
                        memState.Clear();
                        //hide after y seconds
                        if (lastRecvPositionUpdateTime < Lidgren.Network.NetTime.Now - NetConfig.DisableCharacterIfPositionDataMissingDelay)
                        {
                            Enabled = false;
                            return;
                        }
                    }
                }
                else
                {
                    var posInfo = new CharacterStateInfo(
                        SimPosition,
                        AnimController.Collider.Rotation,
                        LastNetworkUpdateID,
                        AnimController.TargetDir,
                        SelectedCharacter,
                        SelectedConstruction,
                        AnimController.Anim);

                    memLocalState.Add(posInfo);

                    InputNetFlags newInput = InputNetFlags.None;
                    if (IsKeyDown(InputType.Left))
                    {
                        newInput |= InputNetFlags.Left;
                    }
                    if (IsKeyDown(InputType.Right))
                    {
                        newInput |= InputNetFlags.Right;
                    }
                    if (IsKeyDown(InputType.Up))
                    {
                        newInput |= InputNetFlags.Up;
                    }
                    if (IsKeyDown(InputType.Down))
                    {
                        newInput |= InputNetFlags.Down;
                    }
                    if (IsKeyDown(InputType.Run))
                    {
                        newInput |= InputNetFlags.Run;
                    }
                    if (IsKeyDown(InputType.Crouch))
                    {
                        newInput |= InputNetFlags.Crouch;
                    }
                    if (IsKeyHit(InputType.Select))
                    {
                        newInput |= InputNetFlags.Select;                             //TODO: clean up the way this input is registered
                    }
                    if (IsKeyHit(InputType.Deselect))
                    {
                        newInput |= InputNetFlags.Deselect;
                    }
                    if (IsKeyHit(InputType.Health))
                    {
                        newInput |= InputNetFlags.Health;
                    }
                    if (IsKeyHit(InputType.Grab))
                    {
                        newInput |= InputNetFlags.Grab;
                    }
                    if (IsKeyDown(InputType.Use))
                    {
                        newInput |= InputNetFlags.Use;
                    }
                    if (IsKeyDown(InputType.Aim))
                    {
                        newInput |= InputNetFlags.Aim;
                    }
                    if (IsKeyDown(InputType.Shoot))
                    {
                        newInput |= InputNetFlags.Shoot;
                    }
                    if (IsKeyDown(InputType.Attack))
                    {
                        newInput |= InputNetFlags.Attack;
                    }
                    if (IsKeyDown(InputType.Ragdoll))
                    {
                        newInput |= InputNetFlags.Ragdoll;
                    }

                    if (AnimController.TargetDir == Direction.Left)
                    {
                        newInput |= InputNetFlags.FacingLeft;
                    }

                    Vector2 relativeCursorPos = cursorPosition - AimRefPosition;
                    relativeCursorPos.Normalize();
                    UInt16 intAngle = (UInt16)(65535.0 * Math.Atan2(relativeCursorPos.Y, relativeCursorPos.X) / (2.0 * Math.PI));

                    NetInputMem newMem = new NetInputMem
                    {
                        states = newInput,
                        intAim = intAngle
                    };

                    if (FocusedCharacter != null &&
                        FocusedCharacter.CampaignInteractionType != CampaignMode.InteractionType.None &&
                        newMem.states.HasFlag(InputNetFlags.Use))
                    {
                        newMem.interact = FocusedCharacter.ID;
                    }
                    else if (newMem.states.HasFlag(InputNetFlags.Use) && (FocusedCharacter?.IsPet ?? false))
                    {
                        newMem.interact = FocusedCharacter.ID;
                    }
                    else if (focusedItem != null && !CharacterInventory.DraggingItemToWorld &&
                             !newMem.states.HasFlag(InputNetFlags.Grab) && !newMem.states.HasFlag(InputNetFlags.Health))
                    {
                        newMem.interact = focusedItem.ID;
                    }
                    else if (FocusedCharacter != null)
                    {
                        newMem.interact = FocusedCharacter.ID;
                    }

                    memInput.Insert(0, newMem);
                    LastNetworkUpdateID++;
                    if (memInput.Count > 60)
                    {
                        memInput.RemoveRange(60, memInput.Count - 60);
                    }
                }
            }
            else //this == Character.Controlled && GameMain.Client == null
            {
                AnimController.Frozen = false;
            }
        }
Ejemplo n.º 3
0
        public virtual void ServerRead(ClientNetObject type, NetBuffer msg, Client c)
        {
            if (GameMain.Server == null)
            {
                return;
            }

            switch (type)
            {
            case ClientNetObject.CHARACTER_INPUT:

                if (c.Character != this)
                {
#if DEBUG
                    DebugConsole.Log("Received a character update message from a client who's not controlling the character");
#endif
                    return;
                }

                UInt16 networkUpdateID = msg.ReadUInt16();
                byte   inputCount      = msg.ReadByte();

                if (AllowInput)
                {
                    Enabled = true;
                }

                for (int i = 0; i < inputCount; i++)
                {
                    InputNetFlags newInput    = (InputNetFlags)msg.ReadRangedInteger(0, (int)InputNetFlags.MaxVal);
                    UInt16        newAim      = 0;
                    UInt16        newInteract = 0;

                    if (newInput.HasFlag(InputNetFlags.Aim))
                    {
                        newAim = msg.ReadUInt16();
                    }
                    if (newInput.HasFlag(InputNetFlags.Select) || newInput.HasFlag(InputNetFlags.Use))
                    {
                        newInteract = msg.ReadUInt16();
                    }

                    if (AllowInput)
                    {
                        if (NetIdUtils.IdMoreRecent((ushort)(networkUpdateID - i), LastNetworkUpdateID) && (i < 60))
                        {
                            NetInputMem newMem = new NetInputMem();
                            newMem.states   = newInput;
                            newMem.intAim   = newAim;
                            newMem.interact = newInteract;

                            newMem.networkUpdateID = (ushort)(networkUpdateID - i);

                            memInput.Insert(i, newMem);
                        }
                    }
                }

                if (NetIdUtils.IdMoreRecent(networkUpdateID, LastNetworkUpdateID))
                {
                    LastNetworkUpdateID = networkUpdateID;
                }
                if (memInput.Count > 60)
                {
                    //deleting inputs from the queue here means the server is way behind and data needs to be dropped
                    //we'll make the server drop down to 30 inputs for good measure
                    memInput.RemoveRange(30, memInput.Count - 30);
                }
                break;

            case ClientNetObject.ENTITY_STATE:
                int eventType = msg.ReadRangedInteger(0, 2);
                switch (eventType)
                {
                case 0:
                    inventory.ServerRead(type, msg, c);
                    break;

                case 1:
                    if (c.Character != this)
                    {
#if DEBUG
                        DebugConsole.Log("Received a character update message from a client who's not controlling the character");
#endif
                        return;
                    }

                    bool doingCPR = msg.ReadBoolean();
                    AnimController.Anim = doingCPR ? AnimController.Animation.CPR : AnimController.Animation.None;
                    break;

                case 2:
                    if (c.Character != this)
                    {
#if DEBUG
                        DebugConsole.Log("Received a character update message from a client who's not controlling the character");
#endif
                        return;
                    }

                    if (IsUnconscious)
                    {
                        Kill(lastAttackCauseOfDeath);
                    }
                    break;
                }
                break;
            }
            msg.ReadPadBits();
        }
Ejemplo n.º 4
0
        public virtual void ServerRead(ClientNetObject type, IReadMessage msg, Client c)
        {
            if (GameMain.Server == null)
            {
                return;
            }

            switch (type)
            {
            case ClientNetObject.CHARACTER_INPUT:

                if (c.Character != this)
                {
#if DEBUG
                    DebugConsole.Log("Received a character update message from a client who's not controlling the character");
#endif
                    return;
                }

                UInt16 networkUpdateID = msg.ReadUInt16();
                byte   inputCount      = msg.ReadByte();

                if (AllowInput)
                {
                    Enabled = true;
                }

                for (int i = 0; i < inputCount; i++)
                {
                    InputNetFlags newInput    = (InputNetFlags)msg.ReadRangedInteger(0, (int)InputNetFlags.MaxVal);
                    UInt16        newAim      = 0;
                    UInt16        newInteract = 0;

                    if (newInput != InputNetFlags.None && newInput != InputNetFlags.FacingLeft)
                    {
                        c.KickAFKTimer = 0.0f;
                    }
                    else if (AnimController.Dir < 0.0f != newInput.HasFlag(InputNetFlags.FacingLeft))
                    {
                        //character changed the direction they're facing
                        c.KickAFKTimer = 0.0f;
                    }

                    newAim = msg.ReadUInt16();
                    if (newInput.HasFlag(InputNetFlags.Select) ||
                        newInput.HasFlag(InputNetFlags.Deselect) ||
                        newInput.HasFlag(InputNetFlags.Use) ||
                        newInput.HasFlag(InputNetFlags.Health) ||
                        newInput.HasFlag(InputNetFlags.Grab))
                    {
                        newInteract = msg.ReadUInt16();
                    }

                    if (NetIdUtils.IdMoreRecent((ushort)(networkUpdateID - i), LastNetworkUpdateID) && (i < 60))
                    {
                        if ((i > 0 && memInput[i - 1].intAim != newAim))
                        {
                            c.KickAFKTimer = 0.0f;
                        }
                        NetInputMem newMem = new NetInputMem
                        {
                            states          = newInput,
                            intAim          = newAim,
                            interact        = newInteract,
                            networkUpdateID = (ushort)(networkUpdateID - i)
                        };
                        memInput.Insert(i, newMem);
                        LastInputTime = Timing.TotalTime;
                    }
                }

                if (NetIdUtils.IdMoreRecent(networkUpdateID, LastNetworkUpdateID))
                {
                    LastNetworkUpdateID = networkUpdateID;
                }
                if (memInput.Count > 60)
                {
                    //deleting inputs from the queue here means the server is way behind and data needs to be dropped
                    //we'll make the server drop down to 30 inputs for good measure
                    memInput.RemoveRange(30, memInput.Count - 30);
                }
                break;

            case ClientNetObject.ENTITY_STATE:
                int eventType = msg.ReadRangedInteger(0, 3);
                switch (eventType)
                {
                case 0:
                    Inventory.ServerRead(type, msg, c);
                    break;

                case 1:
                    bool doingCPR = msg.ReadBoolean();
                    if (c.Character != this)
                    {
#if DEBUG
                        DebugConsole.Log("Received a character update message from a client who's not controlling the character");
#endif
                        return;
                    }

                    AnimController.Anim = doingCPR ? AnimController.Animation.CPR : AnimController.Animation.None;
                    break;

                case 2:
                    if (c.Character != this)
                    {
#if DEBUG
                        DebugConsole.Log("Received a character update message from a client who's not controlling the character");
#endif
                        return;
                    }

                    if (IsUnconscious)
                    {
                        var causeOfDeath = CharacterHealth.GetCauseOfDeath();
                        Kill(causeOfDeath.First, causeOfDeath.Second);
                    }
                    break;
                }
                break;
            }
            msg.ReadPadBits();
        }