コード例 #1
0
ファイル: MmoWorld.cs プロジェクト: Inifield/zoso-server
        /// <summary>
        /// Creates a new <see cref="MmoZone"/>.
        /// </summary>
        public MmoZone CreateZone(short id, string name, Bounds zoneBounds, Vector3 tileDimentions, ZoneDescription zoneDescription)
        {
            MmoZone existingZone;

            if (zones.TryGetValue(id, out existingZone))
            {
                return(existingZone);
            }

            // locking to update the bounds
            lock (zones)
            {
                this.bounds = this.bounds.Size != Vector3.Zero ? this.bounds.UnionWith(zoneBounds) : zoneBounds;
                var newZone = new MmoZone(this, id, name, zoneBounds, tileDimentions, zoneDescription, configuration);
                zones.Add(id, newZone);
                return(newZone);
            }
        }
コード例 #2
0
        /// <summary>
        /// Creates a new instance of the <see cref="MmoZone"/> class.
        /// </summary>
        /// <param name="world"> The world </param>
        /// <param name="name"> The name of the <see cref="MmoZone"/>. Does not have to be unique, this will be sent to the client. </param>
        /// <param name="id"> A unique id used to distinguish between other <see cref="MmoZone"/>s. Must be unique in order to avoid id conflicts. </param>
        /// <param name="tileDimentions"> </param>
        /// <param name="zoneDescription"> The zone data which contains data of the current zone </param>
        /// <param name="bounds"> </param>
        /// <param name="configuration"> </param>
        /// <remarks>
        /// The <see cref="MmoZone"/> uses an actual coordinate system, meaning x is right, z is forward and y is up always.
        /// </remarks>
        internal MmoZone(MmoWorld world, short id, string name, Bounds bounds, Vector3 tileDimentions, ZoneDescription zoneDescription, GameConfig configuration)
            : base(bounds, tileDimentions)
        {
            this.world = world;
            this.name  = name;
            this.id    = id;

            this.objectCache       = new WorldObjectCache(PeerSettings.MaxLockWaitTime);
            this.dynamicObjectPool = new ObjectPool <short, Dynamic>();

            this.localChatChannel = Chat.MmoChat.INVALID_CHAT_CHANNEL;
            this.tradeChatChannel = Chat.MmoChat.INVALID_CHAT_CHANNEL;

            var physicsEngineConfig = configuration.physics.engine;

            switch (physicsEngineConfig.type.ToLower())
            {
            case "digitalrune":
                this.physics = new RunePhysicsWorld(Bounds, physicsEngineConfig.userObject);
                break;

            default:
                this.physics = new QuantumPhysicsWorld(Bounds, this);
                break;
            }

            var terrainWidthX = zoneDescription.TerrainWidthX;
            var terrainWidthZ = zoneDescription.TerrainWidthZ;

            var heights = new float[terrainWidthX, terrainWidthZ];

            for (var z = 0; z < terrainWidthZ; z++)
            {
                for (var x = 0; x < terrainWidthX; x++)
                {
                    // we need to load it in reverse order
                    heights[x, z] = zoneDescription.Heights[z * terrainWidthX + x];
                }
            }

            var heightFieldDescription = new HeightFieldDescription
            {
                Heights  = heights,
                Position = Vector3.Zero,
                WidthX   = terrainWidthX,
                WidthZ   = terrainWidthZ
            };

            this.heightField = physics.CreateHeightField(heightFieldDescription).Shape as IHeightField;
            if (heightField == null)
            {
                throw new NullReferenceException("heightField");
            }

            // loading all box colliders
            var boxColliders = zoneDescription.Colliders.BoxColliders;

            if (boxColliders != null)
            {
                foreach (var boxCollider in boxColliders)
                {
                    physics.CreateWorldObject(boxCollider, CollisionHelper.WorldObjectColliderDescription);
                }
            }

            // loading all sphere colliders
            var sphereColliders = zoneDescription.Colliders.SphereColliders;

            if (sphereColliders != null)
            {
                foreach (var sphereCollider in sphereColliders)
                {
                    physics.CreateWorldObject(sphereCollider, CollisionHelper.WorldObjectColliderDescription);
                }
            }

            // loading all capsule colliders
            var capsuleColliders = zoneDescription.Colliders.CapsuleColliders;

            if (capsuleColliders != null)
            {
                foreach (var capsuleCollider in capsuleColliders)
                {
                    physics.CreateWorldObject(capsuleCollider, CollisionHelper.WorldObjectColliderDescription);
                }
            }
#if USE_PHYSICS
            // setting up the physics thread
            new Thread(o =>
            {
                var timer = System.Diagnostics.Stopwatch.StartNew();
                timer.Start();

                while (true)
                {
                    // sleeping for 16 ms ~ 1 / 60 s
                    Thread.Sleep(16);
                    // updating the physics engine
                    this.physics.Update(timer.Elapsed);
                    timer.Restart();
                }
            })
            {
                Priority = ThreadPriority.AboveNormal, IsBackground = true
            }.Start(this);
#endif
            // load all npc, objects, items, quest, loot, etc
            this.PrimaryFiber.Enqueue(LoadZone);
#if MMO_DEBUG
            Utils.Logger.DebugFormat("Zone (Name={0}:Min={1}:Max={2}) created in World (Min={3}:Max={4}", this.Name, Bounds.Min, Bounds.Max, World.Bounds.Min,
                                     World.Bounds.Max);
#endif
        }