コード例 #1
0
 /// <summary>
 ///     Creates an instance of <see cref="PointerInputCmdMessage"/> with an optional Entity reference.
 /// </summary>
 /// <param name="tick">Client tick this was created.</param>
 /// <param name="inputFunctionId">Function this command is changing.</param>
 /// <param name="coordinates">Local Coordinates of the pointer when the command was created.</param>
 /// <param name="uid">Entity that was under the pointer when the command was created.</param>
 public PointerInputCmdMessage(GameTick tick, ushort subTick, KeyFunctionId inputFunctionId, EntityCoordinates coordinates, EntityUid uid)
     : base(tick, subTick, inputFunctionId)
 {
     Coordinates = coordinates;
     Uid         = uid;
 }
コード例 #2
0
 /// <summary>
 ///     Creates an instance of <see cref="EventInputCmdMessage"/>.
 /// </summary>
 /// <param name="tick">Client tick this was created.</param>
 /// <param name="inputFunctionId">Function this command is changing.</param>
 public EventInputCmdMessage(GameTick tick, ushort subTick, KeyFunctionId inputFunctionId)
     : base(tick, subTick, inputFunctionId)
 {
 }
コード例 #3
0
 /// <summary>
 ///     Creates an instance of <see cref="PointerInputCmdMessage"/>.
 /// </summary>
 /// <param name="tick">Client tick this was created.</param>
 /// <param name="inputFunctionId">Function this command is changing.</param>
 /// <param name="coordinates">Local Coordinates of the pointer when the command was created.</param>
 public PointerInputCmdMessage(GameTick tick, ushort subTick, KeyFunctionId inputFunctionId, EntityCoordinates coordinates)
     : this(tick, subTick, inputFunctionId, coordinates, EntityUid.Invalid)
 {
 }
コード例 #4
0
 public NeptuniumProductionEvent(Mine mine, GameTick occursAt) : base(occursAt, Priority.LowPriorty)
 {
     this._mine           = mine;
     this._nextProduction = null;
 }
コード例 #5
0
        public WorldStateImmutable CreateDevWorldState()
        {
            var players = new List <PlayerImmutable>();

            var gameTick = new GameTick(0);

            int playerCount = 5;

            for (int i = 0; i < playerCount; i++)
            {
                players.Add(
                    new PlayerImmutable(
                        PlayerId: PlayerIdFactory.Create($"discostu#{i}"),
                        PlayerType: Id.PlayerType("terran"),
                        Name: $"Commander Discostu#{i}",
                        Created: DateTime.Now,
                        State: new PlayerStateImmutable(
                            LastGameTickUpdate: DateTime.Now,
                            CurrentGameTick: gameTick,
                            Resources: new Dictionary <ResourceDefId, decimal> {
                    { Id.ResDef("land"), 50 },
                    { Id.ResDef("minerals"), 5000 },
                    { Id.ResDef("gas"), 3000 }
                },
                            Assets: new HashSet <AssetImmutable> {
                    new AssetImmutable(
                        AssetDefId: Id.AssetDef("commandcenter"),
                        Level: 1
                        ),
                    new AssetImmutable(
                        AssetDefId: Id.AssetDef("factory"),
                        Level: 1
                        ),
                    new AssetImmutable(
                        AssetDefId: Id.AssetDef("armory"),
                        Level: 1
                        ),
                    new AssetImmutable(
                        AssetDefId: Id.AssetDef("spaceport"),
                        Level: 1
                        )
                },
                            Units: new List <UnitImmutable> {
                    new UnitImmutable(
                        UnitId: Id.NewUnitId(),
                        UnitDefId: Id.UnitDef("wbf"),
                        Count: 10,
                        Position: null
                        ),
                    new UnitImmutable(
                        UnitId: Id.NewUnitId(),
                        UnitDefId: Id.UnitDef("spacemarine"),
                        Count: 25,
                        Position: null
                        ),
                    new UnitImmutable(
                        UnitId: Id.NewUnitId(),
                        UnitDefId: Id.UnitDef("siegetank"),
                        Count: 3,
                        Position: i == 0 ? null : PlayerIdFactory.Create("discostu#0")
                        ),
                }
                            )
                        )
                    );
            }

            return(new WorldStateImmutable(
                       players.ToDictionary(x => x.PlayerId),
                       new GameTickStateImmutable(gameTick, DateTime.Now - TimeSpan.FromMinutes(1)),
                       new List <GameActionImmutable>()
                       ));
        }
コード例 #6
0
 /// <summary>
 ///     Creates an instance of <see cref="StateInputCmdMessage"/>.
 /// </summary>
 /// <param name="tick">Client tick this was created.</param>
 /// <param name="inputFunctionId">Function this command is changing.</param>
 /// <param name="state">New state of the Input Function.</param>
 public StateInputCmdMessage(GameTick tick, ushort subTick, KeyFunctionId inputFunctionId, BoundKeyState state)
     : base(tick, subTick, inputFunctionId)
 {
     State = state;
 }
コード例 #7
0
 /// <summary>
 /// Advances the GameState by one tick. IMPORTANT: This does NOT apply any time machine actions.
 /// </summary>
 /// <returns>The next GameTick</returns>
 public GameTick GoToNextTick()
 {
     this.CurrentTick = this.CurrentTick.GetNextTick();
     return(this.CurrentTick);
 }
コード例 #8
0
 protected NaturalGameEvent(GameTick occursAt, Priority priority)
 {
     this._eventId  = Guid.NewGuid().ToString();
     this._occursAt = occursAt;
     this._priority = priority;
 }
コード例 #9
0
        internal IList <GameAction> GetAndRemoveDueActions(PlayerId playerId, string name, GameTick gameTick)
        {
            // TODO: synchronize
            var actions = GetActions(playerId).Where(x => x.Name == name && x.IsDue(gameTick)).ToList();             // copy

            foreach (var action in actions)
            {
                Remove(action);
            }
            return(actions);
        }
コード例 #10
0
        /// <inheritdoc />
        public void SendGameStateUpdate()
        {
            DebugTools.Assert(_networkManager.IsServer);

            _entityManager.Update();

            if (!_networkManager.IsConnected)
            {
                // Prevent deletions piling up if we have no clients.
                _entityManager.CullDeletionHistory(GameTick.MaxValue);
                _mapManager.CullDeletionHistory(GameTick.MaxValue);
                return;
            }

            var inputSystem = _systemManager.GetEntitySystem <InputSystem>();

            var oldestAck = GameTick.MaxValue;


            foreach (var channel in _networkManager.Channels)
            {
                var session = _playerManager.GetSessionByChannel(channel);
                if (session == null || session.Status != SessionStatus.InGame)
                {
                    // client still joining, maybe iterate over sessions instead?
                    continue;
                }

                if (!_ackedStates.TryGetValue(channel.ConnectionId, out var lastAck))
                {
                    DebugTools.Assert("Why does this channel not have an entry?");
                }

                var entStates = lastAck == GameTick.Zero || !PvsEnabled
                    ? _entityManager.GetEntityStates(lastAck)
                    : _entityManager.UpdatePlayerSeenEntityStates(lastAck, session, _entityManager.MaxUpdateRange);

                var playerStates = _playerManager.GetPlayerStates(lastAck);
                var deletions    = _entityManager.GetDeletedEntities(lastAck);
                var mapData      = _mapManager.GetStateData(lastAck);


                // lastAck varies with each client based on lag and such, we can't just make 1 global state and send it to everyone
                var lastInputCommand  = inputSystem.GetLastInputCommand(session);
                var lastSystemMessage = _entityNetworkManager.GetLastMessageSequence(session);
                var state             = new GameState(lastAck, _gameTiming.CurTick,
                                                      Math.Max(lastInputCommand, lastSystemMessage), entStates, playerStates, deletions, mapData);
                if (lastAck < oldestAck)
                {
                    oldestAck = lastAck;
                }

                // actually send the state
                var stateUpdateMessage = _networkManager.CreateNetMessage <MsgState>();
                stateUpdateMessage.State = state;
                _networkManager.ServerSendMessage(stateUpdateMessage, channel);

                // If the state is too big we let Lidgren send it reliably.
                // This is to avoid a situation where a state is so large that it consistently gets dropped
                // (or, well, part of it).
                // When we send them reliably, we immediately update the ack so that the next state will not be huge.
                if (stateUpdateMessage.ShouldSendReliably())
                {
                    _ackedStates[channel.ConnectionId] = _gameTiming.CurTick;
                }
            }

            // keep the deletion history buffers clean
            if (oldestAck > _lastOldestAck)
            {
                _lastOldestAck = oldestAck;
                _entityManager.CullDeletionHistory(oldestAck);
                _mapManager.CullDeletionHistory(oldestAck);
            }
        }
コード例 #11
0
 /// <summary>
 /// Constructor for the combat event
 /// </summary>
 /// <param name="combatant1">The first combatant</param>
 /// <param name="combatant2">The second combatant</param>
 /// <param name="tick">The tick the combat occurs</param>
 /// <param name="combatLocation">The location of the combat</param>
 public CombatEvent(ICombatable combatant1, ICombatable combatant2, GameTick tick) : base(tick, Priority.NATURAL_PRIORITY_9)
 {
     this._combatant1 = combatant1;
     this._combatant2 = combatant2;
 }
コード例 #12
0
ファイル: LaunchEvent.cs プロジェクト: naib864/Remake-Core
        /// <summary>
        /// Creates any combat events that will result in the launch.
        /// </summary>
        private void CreateCombatEvents()
        {
            // Create the combat event for arrival
            RftVector targetPosition = this._destination.GetTargetPosition(_source.GetCurrentPosition(), this._launchedSub.GetSpeed());
            GameTick  arrival        = this._launchTime.Advance((int)Math.Floor((targetPosition - _source.GetCurrentPosition()).Magnitude() / this._launchedSub.GetSpeed()));

            CombatEvent arriveCombat = new CombatEvent(this._launchedSub, this._destination, arrival, targetPosition);

            _combatEvents.Add(arriveCombat);
            Game.TimeMachine.AddEvent(arriveCombat);

            // Determine any combat events that may exist along the way.
            // First determine if any subs are on the same path.
            // Subs will only be on the same path if it is outpost to outpost
            if (this._destination.GetType().Equals(typeof(Outpost)) && this._source.GetType().Equals(typeof(Outpost)))
            {
                // Interpolate to launch time to determine combats!
                GameTick currentTick = Game.TimeMachine.GetCurrentTick();
                Game.TimeMachine.GoTo(this.GetTick());
                GameState interpolatedState = Game.TimeMachine.GetState();


                foreach (Sub sub in interpolatedState.getSubsOnPath((Outpost)this._source, (Outpost)this._destination))
                {
                    // Don't combat with yourself
                    if (sub == this.GetActiveSub())
                    {
                        continue;
                    }

                    // Determine if we combat it
                    if (sub.GetDirection() == this.GetActiveSub().GetDirection())
                    {
                        if (this.GetActiveSub().GetExpectedArrival() < sub.GetExpectedArrival())
                        {
                            // We can catch it. Determine when and create a combat event.
                        }
                    }
                    else
                    {
                        // Sub is moving towards us.
                        if (sub.GetOwner() != this.GetActiveSub().GetOwner())
                        {
                            // Combat will occur
                            // Determine when and create a combat event.

                            // Determine the number of ticks between the incoming sub & the launched sub.
                            int ticksBetweenSubs = sub.GetExpectedArrival() - this._launchTime;

                            // Determine the speed ratio as a number between 0-0.5
                            double speedRatio = (sub.GetSpeed() / this.GetActiveSub().GetSpeed()) - 0.5;

                            int ticksUntilCombat = (int)Math.Floor(speedRatio * ticksBetweenSubs);

                            // Determine collision position:
                            RftVector combatPosition = new RftVector(RftVector.Map, this.GetActiveSub().GetDirection() * ticksUntilCombat);

                            CombatEvent combatEvent = new CombatEvent(sub, this.GetActiveSub(), this._launchTime.Advance(ticksUntilCombat), combatPosition);
                            _combatEvents.Add(combatEvent);
                            Game.TimeMachine.AddEvent(combatEvent);
                        }
                    }
                }
                // Go back to the original point in time.
                Game.TimeMachine.GoTo(currentTick);
            }
        }
コード例 #13
0
 /// <summary>
 /// Constructor for the combat event
 /// </summary>
 /// <param name="combatant1">The first combatant</param>
 /// <param name="combatant2">The second combatant</param>
 /// <param name="tick">The tick the combat occurs</param>
 public CombatEvent(Entity combatant1, Entity combatant2, GameTick tick) : base(tick, Priority.NaturalPriority9)
 {
     this._combatant1 = combatant1;
     this._combatant2 = combatant2;
 }
コード例 #14
0
        /// <inheritdoc />
        public void SendGameStateUpdate()
        {
            DebugTools.Assert(_networkManager.IsServer);

            if (!_networkManager.IsConnected)
            {
                // Prevent deletions piling up if we have no clients.
                _entityManager.CullDeletionHistory(GameTick.MaxValue);
                _mapManager.CullDeletionHistory(GameTick.MaxValue);
                return;
            }

            var oldestAck = GameTick.MaxValue;

            var work = new List <(INetChannel channel, GameTick lastAck)>();

            foreach (var channel in _networkManager.Channels)
            {
                var session = _playerManager.GetSessionByChannel(channel);
                if (session == null || session.Status != SessionStatus.InGame)
                {
                    // client still joining, maybe iterate over sessions instead?
                    continue;
                }

                if (!_ackedStates.TryGetValue(channel.ConnectionId, out var lastAck))
                {
                    DebugTools.Assert("Why does this channel not have an entry?");
                }

                work.Add((channel, lastAck));

                if (lastAck < oldestAck)
                {
                    oldestAck = lastAck;
                }
            }

            var workDone = ParallelStates
                ? work.AsParallel().Select(GenerateStateFor).ToList()
                : work.Select(GenerateStateFor).ToList();

            foreach (var(channel, state) in workDone)
            {
                // actually send the state
                var stateUpdateMessage = _networkManager.CreateNetMessage <MsgState>();
                stateUpdateMessage.State = state;
                _networkManager.ServerSendMessage(stateUpdateMessage, channel);

                // If the state is too big we let Lidgren send it reliably.
                // This is to avoid a situation where a state is so large that it consistently gets dropped
                // (or, well, part of it).
                // When we send them reliably, we immediately update the ack so that the next state will not be huge.
                if (stateUpdateMessage.ShouldSendReliably())
                {
                    _ackedStates[channel.ConnectionId] = _gameTiming.CurTick;
                }
            }

            // keep the deletion history buffers clean
            if (oldestAck > _lastOldestAck)
            {
                _lastOldestAck = oldestAck;
                _entityManager.CullDeletionHistory(oldestAck);
                _mapManager.CullDeletionHistory(oldestAck);
            }
        }
コード例 #15
0
 /// <summary>
 ///     Creates an instance of <see cref="FullInputCmdMessage"/>.
 /// </summary>
 /// <param name="tick">Client tick this was created.</param>
 /// <param name="inputSequence"></param>
 /// <param name="inputFunctionId">Function this command is changing.</param>
 /// <param name="state">New state of the Input Function.</param>
 /// <param name="coordinates">Local Coordinates of the pointer when the command was created.</param>
 /// <param name="screenCoordinates"></param>
 public FullInputCmdMessage(GameTick tick, ushort subTick, int inputSequence, KeyFunctionId inputFunctionId, BoundKeyState state, EntityCoordinates coordinates, ScreenCoordinates screenCoordinates)
     : this(tick, subTick, inputFunctionId, state, coordinates, screenCoordinates, EntityUid.Invalid)
 {
 }
コード例 #16
0
 public static void Write(this NetOutgoingMessage message, GameTick tick)
 {
     message.Write(tick.Value);
 }
コード例 #17
0
 /// <summary>
 ///     Creates an instance of <see cref="InputCmdMessage"/>.
 /// </summary>
 /// <param name="tick">Client tick this was created.</param>
 /// <param name="inputFunctionId">Function this command is changing.</param>
 public InputCmdMessage(GameTick tick, ushort subTick, KeyFunctionId inputFunctionId)
 {
     Tick            = tick;
     SubTick         = subTick;
     InputFunctionId = inputFunctionId;
 }
コード例 #18
0
 public void Dirty()
 {
     _lastStateUpdate = _timing.CurTick;
 }
コード例 #19
0
 /// <summary>
 /// Factory Constructor
 /// </summary>
 /// <param name="id">ID of the outpost</param>
 /// <param name="outpostStartPosition">Position of outpost</param>
 /// <param name="outpostOwner">Owner of outpost</param>
 public Factory(string id, RftVector outpostStartPosition, Player outpostOwner) : base(id, outpostStartPosition, outpostOwner)
 {
     this._ticksPerProduction     = STANDARD_TICKS_PER_PRODUCTION;
     this._ticksToFirstProduction = new GameTick(STANDARD_TICKS_PER_PRODUCTION);             //TODO: randomize
     this._drillersPerProduction  = Constants.BaseFactoryProduction;
 }
コード例 #20
0
 public void Dirty(GameTick currentTick)
 {
     LastUpdate = currentTick;
 }
コード例 #21
0
        public GameStateMapData?GetStateData(GameTick fromTick)
        {
            var gridDatums = new Dictionary <GridId, GameStateMapData.GridDatum>();

            foreach (var grid in _grids.Values)
            {
                if (grid.LastModifiedTick < fromTick)
                {
                    continue;
                }

                var chunkData = new List <GameStateMapData.ChunkDatum>();
                foreach (var(index, chunk) in grid.GetMapChunks())
                {
                    if (chunk.LastModifiedTick < fromTick)
                    {
                        continue;
                    }

                    var tileBuffer = new Tile[grid.ChunkSize * (uint)grid.ChunkSize];

                    // Flatten the tile array.
                    // NetSerializer doesn't do multi-dimensional arrays.
                    // This is probably really expensive.
                    for (var x = 0; x < grid.ChunkSize; x++)
                    {
                        for (var y = 0; y < grid.ChunkSize; y++)
                        {
                            tileBuffer[x * grid.ChunkSize + y] = chunk.GetTile((ushort)x, (ushort)y);
                        }
                    }

                    chunkData.Add(new GameStateMapData.ChunkDatum(index, tileBuffer));
                }

                var gridDatum =
                    new GameStateMapData.GridDatum(chunkData.ToArray(), new MapCoordinates(grid.WorldPosition, grid.ParentMapId));

                gridDatums.Add(grid.Index, gridDatum);
            }

            var mapDeletionsData  = _mapDeletionHistory.Where(d => d.tick >= fromTick).Select(d => d.mapId).ToList();
            var gridDeletionsData = _gridDeletionHistory.Where(d => d.tick >= fromTick).Select(d => d.gridId).ToList();
            var mapCreations      = _mapCreationTick.Where(kv => kv.Value >= fromTick && kv.Key != MapId.Nullspace)
                                    .ToDictionary(kv => kv.Key, kv => _defaultGrids[kv.Key]);
            var gridCreations = _grids.Values.Where(g => g.CreatedTick >= fromTick && g.ParentMapId != MapId.Nullspace).ToDictionary(g => g.Index,
                                                                                                                                     grid => new GameStateMapData.GridCreationDatum(grid.ChunkSize, grid.SnapSize,
                                                                                                                                                                                    grid.IsDefaultGrid));

            // no point sending empty collections
            if (gridDatums.Count == 0)
            {
                gridDatums = default;
            }
            if (gridDeletionsData.Count == 0)
            {
                gridDeletionsData = default;
            }
            if (mapDeletionsData.Count == 0)
            {
                mapDeletionsData = default;
            }
            if (mapCreations.Count == 0)
            {
                mapCreations = default;
            }
            if (gridCreations.Count == 0)
            {
                gridCreations = default;
            }

            // no point even creating an empty map state if no data
            if (gridDatums == null && gridDeletionsData == null && mapDeletionsData == null && mapCreations == null && gridCreations == null)
            {
                return(default);
コード例 #22
0
ファイル: MsgStateAck.cs プロジェクト: rneuser/RobustToolbox
 public override void ReadFromBuffer(NetIncomingMessage buffer)
 {
     Sequence = new GameTick(buffer.ReadUInt32());
 }