public IEnumerable <IChange> Handle(Level level, ICommand command) { if (command is SpawnCommand spawnCommand) { var entity = level.Spawn( Prefab, _entity.Position + Utils.MoveDelta(_entity.Orientation), _entity.Orientation); foreach (var entityInTargetPos in level.GetActiveEntitiesAt(entity.Position)) { if (entityInTargetPos.Id != entity.Id) { // If current object collides with target object if (CollisionConfig.ObjectsCollide(entity.ObjectType, entityInTargetPos.ObjectType)) { level.DispatchEarly(new CollisionEvent( target: entityInTargetPos.Id, sourceId: entity.Id, direction: Utils.AbsoluteDirectionToRelative(Utils.RevertDirection(spawnCommand.Direction), entityInTargetPos.Orientation))); level.DispatchEarly(new CollisionEvent( target: entity.Id, sourceId: entityInTargetPos.Id, direction: Utils.AbsoluteDirectionToRelative(spawnCommand.Direction, entity.Orientation))); } if (CollisionConfig.ObjectsHit(entity.ObjectType, entityInTargetPos.ObjectType)) { level.DispatchEarly(new HitCommand( target: entityInTargetPos.Id, sourceId: entity.Id, direction: Utils.AbsoluteDirectionToRelative(Utils.RevertDirection(spawnCommand.Direction), entityInTargetPos.Orientation))); level.DispatchEarly(new HitCommand( target: entity.Id, sourceId: entityInTargetPos.Id, direction: Utils.AbsoluteDirectionToRelative(spawnCommand.Direction, entity.Orientation))); } } } if (entity != null) { if (Animator != null) { Animator.SetTrigger(AnimOnSpawnTrigger); } SoundManager.Instance.Play(SpawnSound); ShootFx?.Trigger(transform); yield return(new SpawnChange(_entity.Id, entity.Id)); } } }
public IEnumerable <IChange> DoMove(Level level, Direction moveDirection, bool updateOrientation, MovementType movementType) { var canMove = CanMove(level, moveDirection); // Update logical position var targetPos = _entity.Position + Utils.MoveDelta(moveDirection); // Move neighbor movable (push) foreach (var entityInTargetPos in level.GetActiveEntitiesAt(targetPos)) { // If current object collides with target object if (CollisionConfig.ObjectsCollide(_entity.ObjectType, entityInTargetPos.ObjectType)) { level.DispatchEarly(new CollisionEvent( target: entityInTargetPos.Id, sourceId: _entity.Id, direction: Utils.AbsoluteDirectionToRelative(Utils.RevertDirection(moveDirection), entityInTargetPos.Orientation))); level.DispatchEarly(new CollisionEvent( target: _entity.Id, sourceId: entityInTargetPos.Id, direction: Utils.AbsoluteDirectionToRelative(moveDirection, _entity.Orientation))); // Push (collidable only) if (canMove && CollisionConfig.CanPush( _entity.ObjectType, entityInTargetPos.ObjectType)) { var movable = entityInTargetPos.GetComponent <Movable>(); if (movable != null) { foreach (var change in movable.DoMove(level, moveDirection, false, MovementType.Pushed)) { yield return(change); } } } } if (CollisionConfig.ObjectsHit(_entity.ObjectType, entityInTargetPos.ObjectType)) { level.DispatchEarly(new HitCommand( target: entityInTargetPos.Id, sourceId: _entity.Id, direction: Utils.AbsoluteDirectionToRelative(Utils.RevertDirection(moveDirection), entityInTargetPos.Orientation))); level.DispatchEarly(new HitCommand( target: _entity.Id, sourceId: entityInTargetPos.Id, direction: Utils.AbsoluteDirectionToRelative(moveDirection, _entity.Orientation))); } } if (!canMove) { yield break; } if (!_entity.IsActive) { yield break; } // Finally, move self targetPos = _entity.Position + Utils.MoveDelta(moveDirection); var targetOrientation = _entity.Orientation; if (updateOrientation) { targetOrientation = moveDirection; } // Effects SoundManager.Instance.Play(MoveSound); var selfMove = new MoveChange(_entity.Id) { OriginalOrientation = _entity.Orientation, OriginalPosition = _entity.Position, TargetOrientation = targetOrientation, TargetPosition = targetPos, MovementType = movementType }; _entity.MoveTo(targetPos, targetOrientation, movementType); yield return(selfMove); }