Beispiel #1
0
        /// <summary>
        /// Performs a single update cycle.
        /// </summary>
        public static void Update()
        {
            isUpdating = true;

            Time.FrameTick(false, true);

            pluginManager.InvokeBeforeUpdate();
            UpdateUserInput();

            AsyncManager.InvokeBeforeUpdate();

            Scene.Current.Update();

            AsyncManager.InvokeAfterUpdate();

            sound.Update();

            pluginManager.InvokeAfterUpdate();

            // Perform a cleanup step to catch all DisposeLater calls from this update
            RunCleanup();

            isUpdating = false;

            if (terminateScheduled)
            {
                Terminate();
            }
        }
        private void OnUpdate()
        {
            if (serverState == ServerState.Unloaded)
            {
                return;
            }

            Time.FrameTick(false, false);

            AsyncManager.InvokeBeforeUpdate();

            Scene.Current.Update();

            AsyncManager.InvokeAfterUpdate();

            DualityApp.RunCleanup();

            lock (sync) {
                // Respawn dead players immediately
                if (playerSpawningEnabled)
                {
                    foreach (KeyValuePair <NetConnection, PlayerClient> pair in players)
                    {
                        if (pair.Value.State == PlayerState.Dead)
                        {
                            RespawnPlayer(pair.Value);
                        }
                    }
                }

                if (serverState == ServerState.LevelReady)
                {
                    if (players.Count >= minPlayers)
                    {
                        countdown -= Time.DeltaTime;

                        if (countdown <= 0f)
                        {
                            serverState     = ServerState.LevelRunning;
                            countdownNotify = 0;

                            levelStartTime = NetTime.Now;

                            SendToActivePlayers(new PlayerSetControllable {
                                IsControllable = true
                            }, 3, NetDeliveryMethod.ReliableUnordered, PacketChannels.UnorderedUpdates);

                            SendToActivePlayers(new ShowMessage {
                                Flags = 0x01,
                                Text  = "\n\n\n\f[c:1]Go!"
                            }, 24, NetDeliveryMethod.ReliableUnordered, PacketChannels.UnorderedUpdates);
                        }
                        else if (countdown < countdownNotify)
                        {
                            countdownNotify = (int)Math.Ceiling(countdown);

                            if (countdownNotify == 15)
                            {
                                SendToActivePlayers(new ShowMessage {
                                    Text = "\n\n\n\f[c:1]Game will start in 15 seconds!"
                                }, 48, NetDeliveryMethod.ReliableUnordered, PacketChannels.UnorderedUpdates);
                            }
                            else if (countdownNotify == 3)
                            {
                                SendToActivePlayers(new ShowMessage {
                                    Flags = 0x01,
                                    Text  = "\n\n\n\f[c:4]3"
                                }, 24, NetDeliveryMethod.ReliableUnordered, PacketChannels.UnorderedUpdates);
                            }
                            else if (countdownNotify == 2)
                            {
                                SendToActivePlayers(new ShowMessage {
                                    Flags = 0x01,
                                    Text  = "\n\n\n\f[c:3]2"
                                }, 24, NetDeliveryMethod.ReliableUnordered, PacketChannels.UnorderedUpdates);
                            }
                            else if (countdownNotify == 1)
                            {
                                SendToActivePlayers(new ShowMessage {
                                    Flags = 0x01,
                                    Text  = "\n\n\n\f[c:2]1"
                                }, 24, NetDeliveryMethod.ReliableUnordered, PacketChannels.UnorderedUpdates);
                            }
                        }
                    }
                }
                else if (serverState == ServerState.LevelComplete)
                {
                    countdown -= Time.DeltaTime;

                    if (countdown <= 0f)
                    {
                        if (activePlaylist == null)
                        {
                            ChangeLevel(currentLevel, currentLevelType);
                        }
                        else
                        {
                            ChangeLevelFromPlaylist(activePlaylistIndex + 1);
                        }
                    }
                }

                // Update all players
                if (playerConnections.Count > 0)
                {
                    List <ActorBase> spawnedActors = levelHandler.SpawnedActors;

                    int playerCount       = players.Count;
                    int spawnedActorCount = spawnedActors.Count;

                    NetOutgoingMessage m = server.CreateMessage(14 + 21 * playerCount + 24 * spawnedActorCount);
                    m.Write(SpecialPacketTypes.UpdateAllActors);
                    m.Write((long)(NetTime.Now * 1000));

                    foreach (KeyValuePair <NetConnection, PlayerClient> pair in players)
                    {
                        PlayerClient player = pair.Value;
                        m.Write((int)player.Index); // Player Index

                        if (player.State != PlayerState.Spawned || !player.ProxyActor.IsVisible)
                        {
                            m.Write((byte)0x00); // Flags - None
                            continue;
                        }

                        m.Write((byte)0x01); // Flags - Visible

                        Vector3 pos = player.ProxyActor.Transform.Pos;
                        m.Write((ushort)(pos.X * 2.5f));
                        m.Write((ushort)(pos.Y * 2.5f));
                        m.Write((ushort)(pos.Z * 2.5f));

                        m.Write((bool)player.ProxyActor.IsFacingLeft);
                    }

                    foreach (ActorBase actor in spawnedActors)
                    {
                        if ((actor.CollisionFlags & CollisionFlags.TransformChanged) == 0)
                        {
                            continue;
                        }

                        actor.CollisionFlags &= ~CollisionFlags.TransformChanged;

                        m.Write((int)actor.Index); // Object Index

                        if (!actor.IsVisible)
                        {
                            m.Write((byte)0x00); // Flags - None
                            continue;
                        }

                        if (actor.Transform.Scale > 0.95f && actor.Transform.Scale < 1.05f &&
                            actor.Transform.Angle > -0.04f && actor.Transform.Angle < 0.04f)
                        {
                            m.Write((byte)0x01); // Flags - Visible

                            Vector3 pos = actor.Transform.Pos;
                            m.Write((ushort)(pos.X * 2.5f));
                            m.Write((ushort)(pos.Y * 2.5f));
                            m.Write((ushort)(pos.Z * 2.5f));

                            m.Write((bool)actor.IsFacingLeft);
                        }
                        else
                        {
                            m.Write((byte)0x03); // Flags - Visible | HasScaleAngle

                            Vector3 pos = actor.Transform.Pos;
                            m.Write((ushort)pos.X);
                            m.Write((ushort)pos.Y);
                            m.Write((ushort)pos.Z);

                            m.Write((float)actor.Transform.Scale);
                            m.WriteRangedSingle((float)actor.Transform.Angle, 0f, MathF.TwoPi, 8);

                            m.Write((bool)actor.IsFacingLeft);
                        }
                    }

                    m.Write((int)-1); // Terminator

                    // Send update command to all active players
                    server.Send(m, playerConnections, NetDeliveryMethod.Unreliable, PacketChannels.UnorderedUpdates);
                }
            }
        }