Example #1
0
    private Event[] AdvanceStory(AdvanceStory command)
    {
        if (this.id == Aggregate.NullId)
        {
            throw new ValidationException("id", "Character not found");
        }
        if (this.currentNode == null)
        {
            throw new ValidationException("", "No dialogue initiated.");
        }
        string formattedInput = FormatUserInput(command.input);

        if (formattedInput.Length == 0)
        {
            throw new ValidationException("input", "Input can't be empty.");
        }
        if (this.currentNode.IsLeaf())
        {
            //todo it makes sense for storylines to have id, not sure about story nodes within stryline (unless each node has the id of the story) stories should be queued.
            StoryCompleted storylineCompleted = new StoryCompleted(command.characterName, "TEMP-REPLACE WITH STORYLINE ID", command.playerId);
            if (!this.completedStoryIds.Contains(storylineCompleted.storylineId))
            {
                return(new Event[] {
                    storylineCompleted,
                    new StoryPrizeAwarded(command.playerId, command.characterName, currentNode.prizeId)
                });
            }
            return(new Event[] {
                storylineCompleted
            });
        }
        List <StoryNode> children = this.currentNode.GetChildren(formattedInput);

        if (children == null)
        {
            throw new ValidationException("input", $"No response for {command.input}");
        }
        int       random  = RandomNumberGenerator.Instance.Range(0, children.Count);
        StoryNode newNode = children [random];

        Event[] result = new Event[1 + currentNode.eventsToPublishOnReaching.Length];
        result [0] = new StoryAdvanced(
            command.characterName, command.playerId,
            command.input, newNode
            );
        for (int i = 1; i < result.Length; i++)
        {
            result [i] = currentNode.eventsToPublishOnReaching [i - 1];
        }

        return(result);
    }
    public override void Reduce(Event evt, ModelTable table)
    {
        Type type = evt.GetType();

        if (type == typeof(CharacterCreated))
        {
            CharacterCreated characterCreated = (CharacterCreated)evt;
            table.InsertModel(characterCreated.name, new CharacterReadModel(characterCreated.name, characterCreated.greeting));
            return;
        }
        if (type == typeof(StoryInitiated))
        {
            StoryInitiated     dialogueInitiated = (StoryInitiated)evt;
            CharacterReadModel character         = (CharacterReadModel)table.GetModel(dialogueInitiated.characterName);
            character.currentText = dialogueInitiated.initialNode.text;
            character.currentStorylineCompleted = false;
            table.UpdateModel(dialogueInitiated.characterName, character);              //not necessary, since we are mutating the reference,
            //but like to be explicit and will soon move to immutable structs for readmodels.
            return;
        }
        if (type == typeof(StoryAdvanced))
        {
            StoryAdvanced      dialogueAdvanced = (StoryAdvanced)evt;
            CharacterReadModel character        = (CharacterReadModel)table.GetModel(dialogueAdvanced.characterName);
            character.currentText = dialogueAdvanced.newNode.text;
            table.UpdateModel(dialogueAdvanced.characterName, character);
            return;
        }
        if (type == typeof(StoryCompleted))
        {
            StoryCompleted     storylineCompleted = (StoryCompleted)evt;
            CharacterReadModel character          = (CharacterReadModel)table.GetModel(storylineCompleted.characterName);
            character.currentText = character.goodbye;
            character.currentStorylineCompleted = true;
            table.UpdateModel(storylineCompleted.characterName, character);
        }
    }
Example #3
0
 private void OnStoryAdvanced(StoryAdvanced evt)
 {
     this.currentNode = evt.newNode;
 }