Beispiel #1
0
        private void OnEntityMoved(EntityMoveEvent e)
        {
            Debug.WriteLine($"{e.Source.Entity.GetType().Name} at {e.SourcePosition} -> {e.Target.Entity.GetType().Name} at {e.TargetPosition}");

            // TODO: Think about animations that should happen one after another
            Entity = e.Target.Entity;
            SourcePosition = CurrentPosition;
            TargetPosition = e.TargetPosition.ToVector2();
            ElapsedTime = TimeSpan.Zero;

            var distance = Vector2.Distance(CurrentPosition, TargetPosition);
            AnimationDuration = TimeSpan.FromSeconds(.2 * Math.Sqrt(distance));
            
            Moved?.Invoke(this);
        }
Beispiel #2
0
        private async Task<bool> MoveCoreAsync(Point sourcePosition, Point targetPosition, ITransactionWithMoveSupport transaction)
        {
            var source = await GetAsync(sourcePosition);
            var target = await GetAsync(targetPosition);

            var oldSource = source;
            var oldTarget = target;

            source.Tile.EnsureNotNull();
            target.Tile.EnsureNotNull();

            if (source.Tile.Entity == Entity.None)
            {
                // Cancel if there's no entity to move
                transaction.IsSealed = true;
                return false;
            }

            var move = new EntityMoveInfo(source.Tile.Entity, sourcePosition, targetPosition);
            transaction.Moves.Push(move);

            IBeginMoveArgs beginMoveArgs = new GameplayArgs(transaction, this);
            IDetachArgs detachArgs = new GameplayArgs(transaction, this);
            IAttachArgs attachArgs = new GameplayArgs(transaction, this);

            // OnBeginMove: Notify entity that a move has been initiated
            await source.Tile.Entity.BeginMoveAsync(beginMoveArgs);
            beginMoveArgs.ValidateResult();
            if (transaction.IsSealed) return false;

            var newSource = source.WithTile(Tile.Compose(source.Tile, beginMoveArgs.ResultingEntity));
            if (transaction.Set(sourcePosition, source, newSource))
                source = newSource;

            move.Entity = beginMoveArgs.ResultingEntity;

            // Detach: Remove the entity from the source tile
            await source.Tile.DetachEntityAsync(detachArgs);
            detachArgs.ValidateResult();
            if (transaction.IsSealed) return false;

            // Attach: Add the entity to the target tile
            await target.Tile.AttachEntityAsync(attachArgs);
            attachArgs.ValidateResult();
            if (transaction.IsSealed) return false;

            // Detach from old tile, attach to new tile have succeeded
            // => Apply changes to transaction
            var newSource2 = source.WithTile(detachArgs.Result);
            if (transaction.Set(sourcePosition, source, newSource2))
                source = newSource2;

            var newTarget = target.WithTile(attachArgs.Result);
            if (transaction.Set(targetPosition, target, newTarget))
                target = newTarget;

            // Emit events
            var moveEvent = new EntityMoveEvent(sourcePosition, targetPosition, oldSource.Tile, target.Tile);
            transaction.Emit(moveEvent);

            if (source.Tile.Entity != Entity.None)
            {
                // A new entity has been created at source position
                var spawnEvent = new EntitySpawnEvent(sourcePosition, source.Tile.Entity);
                transaction.Emit(spawnEvent);
            }

            if (oldTarget.Tile.Entity != Entity.None)
            {
                // The entity at target position has either been replaced
                // or it has been moved/collected/... during a nested move
                var oldTargetEntityOverwritten =
                    !(transaction.Events.OfType<EntityDespawnEvent>().Any(ev => ev.Position == targetPosition) ||
                    transaction.Events.OfType<EntityMoveEvent>().Any(ev => ev.SourcePosition == targetPosition));

                if (oldTargetEntityOverwritten)
                {
                    // If replaced, emit despawn event
                    var despawnEvent = new EntityDespawnEvent(targetPosition, oldTarget.Tile.Entity);
                    transaction.Emit(despawnEvent);
                }
            }

            transaction.Moves.Pop();
            return true;
        }
 private void OnFollowedPlayerMoved(EntityMoveEvent e)
 {
     CameraPosition = e.TargetPosition.ToVector2() + new Vector2(.5f, -.5f);
 }