public SpawnPlayerSimulationCommand( WorldPlayers players, PlayerId playerId, IPhysicsWorld physicsWorld, PlayerConnectionRef connectionRef) { this._players = players; this._connectionRef = connectionRef; this._playerId = playerId; this._physicsWorld = physicsWorld; }
public GameWorld( WorldType worldType, WorldInstanceId id, ILogger logger, IServerConfig config, OutgoingServerChannel channelManager, IGameWorldLoader gameWorldLoader) { this.WorldType = worldType; this.InstanceId = id; this._logger = logger ?? throw new ArgumentNullException(nameof(logger)); this._isStopped = false; this._world = new World(config.Ecs); this._fixedTick = config.Simulation.FixedTick; this._channelManager = channelManager ?? throw new ArgumentNullException(nameof(channelManager)); this._simulationSynchronizer = new SimulationSynchronizer(this._world); this._entityGridMap = new EntityGridMap(config.Replication.GridSize); this._players = new WorldPlayers( config.Replication, config.PlayerInput, config.PlayerConnection.Capacity.InitialConnectionsCapacity); this._replicationManager = new WorldReplicationManager(config.Replication, this._players, this._entityGridMap); this._physicsWorld = new VolatilePhysicsWorld(config.Replication.PhysicsHistoryCount); this._systems = new Systems(this._world) .Add(new PhysicsSystem()) .Add(new ServerEntityReplicationSystem()) .Add(new JiggleSystem()) .Inject(this._physicsWorld) .Inject(new ReplicationDataBroker(config.Replication.Capacity, this._replicationManager)) .Inject(this._entityGridMap); this._simulation = new ServerSimulation <InputComponent>( config.Simulation, this._world, this._systems); this._simulation.Create(); gameWorldLoader.LoadWorld(this.WorldType, this._world, this._physicsWorld); }
public bool LoadWorld(WorldType worldType, World world, IPhysicsWorld physicsWorld) { // TODO: Load world based on WorldType const int rows = 16, cols = 16; const float unitSize = 0.5f; const float quarterUnitSize = 0.25f * unitSize; for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { var entity = world.NewEntity(); ref var replicated = ref entity.GetComponent <ReplicatedComponent>(); ref var rigidBody = ref entity.GetComponent <RigidBodyComponent>(); ref var transform = ref entity.GetComponent <TransformComponent>();
/// <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 }