示例#1
0
        private async Task <bool> ExecuteActionsAsync(DialogContext dc, IEnumerable <CommandAction> actions)
        {
            var stateFlags = await _stateFlagsStateAccessor.GetAsync(dc.Context);

            var inventoryItems = await _inventoryItemsAccessor.GetAsync(dc.Context);

            // Get the room state. It always exists at this point because it's
            // set up in the BeginDialogAsync method.
            var roomStates = await _roomStateAccessor.GetAsync(dc.Context, () => new Dictionary <string, RoomState>());

            var roomState = roomStates[_roomId];

            var activities  = new List <IActivity>();
            var actionStack = new Stack <CommandAction>(actions.Reverse());

            // Process each action in turn, populating the activities list.
            while (actionStack.TryPop(out CommandAction nextAction))
            {
                switch (nextAction)
                {
                case AddToInventoryAction action:
                {
                    if (!inventoryItems.Contains(action.InventoryItemId))
                    {
                        inventoryItems.Add(action.InventoryItemId);

                        activities.Add(_activityFactory.InventoryItemAdded(dc, action.InventoryItemId));
                    }
                    break;
                }

                case ClearFlagAction action:
                {
                    if (stateFlags.Contains(action.Flag))
                    {
                        stateFlags.Remove(action.Flag);
                    }
                    break;
                }

                case GuiDelayAction action:
                {
                    activities.Add(_activityFactory.Delayed(dc, action.Milliseconds));
                    break;
                }

                case GuiChangeActorDirectionAction action:
                {
                    activities.Add(_activityFactory.ActorDirectionChanged(dc,
                                                                          action.ActorId, action.Direction));
                    break;
                }

                case GuiMoveActorAction action:
                {
                    // Save the actor's new position in the room state.
                    roomState.ActorPositions[action.ActorId] = action.Position;

                    activities.Add(_activityFactory.ActorMoved(dc, action.ActorId, action.Position));
                    break;
                }

                case GuiNarratorAction action:
                {
                    activities.Add(_activityFactory.Narrated(dc, action.Text));
                    break;
                }

                case GuiPlaceActorAction action:
                {
                    // Save the actor's new position in the room state.
                    roomState.ActorPositions[action.ActorId] = action.Position;

                    activities.Add(_activityFactory.ActorPlacedInRoom(dc, action.ActorId, action.Position));
                    break;
                }

                case GuiPlaceObjectAction action:
                {
                    // Save the object's new position in the room state.
                    roomState.ObjectPositions[action.ObjectId] = action.Position;

                    activities.Add(_activityFactory.ObjectPlacedInRoom(dc, action.ObjectId, action.Position));
                    break;
                }

                case GuiRemoveObjectAction action:
                {
                    // Remove the object from the room state.
                    roomState.ObjectPositions.Remove(action.ObjectId);

                    activities.Add(_activityFactory.ObjectRemovedFromRoom(dc, action.ObjectId));
                    break;
                }

                case RemoveFromInventoryAction action:
                {
                    if (inventoryItems.Contains(action.InventoryItemId))
                    {
                        inventoryItems.Remove(action.InventoryItemId);
                    }
                    activities.Add(_activityFactory.InventoryItemRemoved(dc, action.InventoryItemId));
                    break;
                }

                case SetFlagAction action:
                {
                    if (!stateFlags.Contains(action.Flag))
                    {
                        stateFlags.Add(action.Flag);
                    }
                    break;
                }

                case SpeakAction action:
                {
                    activities.Add(_activityFactory.Speak(dc, action.ActorId, action.Text));
                    break;
                }

                case StartConversationAction action:
                {
                    // If the result of the action indicates that we need to start a new dialog
                    // (e.g. conversation with an actor, or a switch to a new room), first send all
                    // activities collected up to this point to the client.
                    if (activities.Any())
                    {
                        await dc.Context.SendActivitiesAsync(activities.ToArray());
                    }

                    // If the player starts a conversation, save any remaining actions to the state.
                    // These will be executed when the conversation is done and this dialog
                    // continues.
                    if (actionStack.Any())
                    {
                        // Conver to List because Stacks don't serialize in the correct order.
                        // See https://github.com/JamesNK/Newtonsoft.Json/issues/971.
                        dc.ActiveDialog.State.Add(DialogStatePendingActions, actionStack.ToList());
                    }

                    // Start the conversation.
                    await dc.BeginDialogAsync(action.ConversationId);

                    // Stop processing any further actions now that we've switched to a new dialog.
                    return(false);
                }

                case SwitchRoomAction action:
                {
                    // If the result of the action indicates that we need to start a new dialog
                    // (e.g. conversation with an actor, or a switch to a new room), first send all
                    // activities collected up to this point to the client.
                    if (activities.Any())
                    {
                        await dc.Context.SendActivitiesAsync(activities.ToArray());
                    }

                    // Switch to the new room.
                    await dc.ReplaceDialogAsync(action.RoomId);

                    // Stop processing any further actions now that we've switched to a new dialog.
                    return(false);
                }

                case TextDescribeAction action:
                {
                    activities.Add(MessageFactory.Text(action.Text));
                    break;
                }
                }
            }

            await dc.Context.SendActivitiesAsync(activities.ToArray());

            // Returning true here indicates that we can continue processing the actions for this turn.
            return(true);
        }