public void HandleDrag(IntVector2 tileCoords)
        {
            uint?unitIndex = _unitDataIndexResolver.ResolveUnitIndex(_unit.UnitData);

            if (unitIndex == null)
            {
                _logger.LogError(LoggedFeature.Units,
                                 "Error dragging unit with name: {0}. Index not resolved.",
                                 _unit.UnitData.Name);
                return;
            }

            var unitDataReference = new UnitDataReference(unitIndex.Value, _unit.UnitData.UnitType);

            _mapSectionData.RemoveInitialUnit(_tileCoords, unitDataReference);
            var tileDistance = tileCoords - _tileCoords;

            _tileCoords = tileCoords;
            _commandQueue.Enqueue <MoveUnitCommand, MoveUnitData>(new MoveUnitData(_unit.UnitId, tileDistance),
                                                                  CommandSource.Game);
            _mapSectionData.AddInitialUnit(_tileCoords, unitDataReference);
        }
        public IObservable <Unit> Run()
        {
            IUnit unit = _unitRegistry.GetUnit(_data.unitId);

            if (unit == null)
            {
                _logger.LogError(LoggedFeature.Units,
                                 "MoveUnitSectionCommand called on unit not in registry: {0}",
                                 _data.unitId);
                return(Observable.Empty <Unit>());
            }

            uint?unitIndex = _unitDataIndexResolver.ResolveUnitIndex(unit.UnitData);

            if (unitIndex == null)
            {
                _logger.LogError(LoggedFeature.Units,
                                 "Failed to resolve unit index: {0}",
                                 _data.unitId);
                return(Observable.Empty <Unit>());
            }

            _despawnCommand =
                _commandFactory.Create <DespawnUnitCommand, DespawnUnitData>(new DespawnUnitData(_data.unitId));
            _despawnCommand.Run();

            var sectionLoadedSubject = new Subject <Unit>();
            var commandData          =
                new LoadMapSectionCommandData(_data.toSectionIndex, new LoadMapCommandData(_mapStoreId.index));
            ICommand loadMapSectionCommand =
                _commandFactory.Create <LoadMapSectionCommand, LoadMapSectionCommandData>(commandData);

            loadMapSectionCommand.Run().Subscribe(_ => {
                // We need to wait 1 frame in order to avoid race conditions between listeners on new section
                Observable.IntervalFrame(1).First().Subscribe(__ => {
                    IntVector2 entryTileCoords =
                        _entryTileFinder.GetEntryTile(_data.toSectionIndex, _data.fromSectionIndex);
                    // We don't spawn pets (which also are not despawn on despawn command)
                    var unitCommandData = new UnitCommandData(unit.UnitId, unitIndex.Value, unit.UnitData.UnitType);
                    var spawnUnitData   = new SpawnUnitData(unitCommandData, entryTileCoords, isInitialSpawn: false);
                    _spawnCommand       = _commandFactory.Create <SpawnUnitCommand, SpawnUnitData>(spawnUnitData);
                    _spawnCommand.Run();

                    sectionLoadedSubject.OnNext(Unit.Default);
                });
            });

            return(sectionLoadedSubject);
        }
        private void HandleUnitPlacedAtTile(IUnit unit, IntVector2 tileCoords)
        {
            uint?unitIndex = _unitDataIndexResolver.ResolveUnitIndex(unit.UnitData);

            if (unitIndex == null)
            {
                _logger.LogError(LoggedFeature.Units,
                                 "Error adding unit with name: {0}. Index not resolved.",
                                 unit.UnitData.Name);
                return;
            }

            var unitDataReference = new UnitDataReference(unitIndex.Value, unit.UnitData.UnitType);

            _mapSectionData.AddInitialUnit(tileCoords, unitDataReference);
        }
        public UnitCommandData Create(IUnitData unitData)
        {
            uint?unitIndex = _unitDataIndexResolver.ResolveUnitIndex(unitData);

            if (unitIndex == null)
            {
                _logger.LogError(LoggedFeature.Units,
                                 "Error Spawning unit with name: {0}. Index not resolved.",
                                 unitData);
                return(null);
            }

            UnitCommandData[] petData = new UnitCommandData[unitData.Pets.Length];
            for (int i = 0; i < unitData.Pets.Length; i++)
            {
                petData[i] = Create(unitData.Pets[i]);
            }

            return(new UnitCommandData(new UnitId(), unitIndex.Value, unitData.UnitType, petData));
        }