/// <summary>
        /// Creates an instance of <see cref="EncounterMonsterDialogViewModel"/>
        /// </summary>
        public EncounterMonsterDialogViewModel(EncounterMonsterModel encounterMonster)
        {
            _encounterCreatureModel = encounterMonster;

            _monsterOptions.Clear();
            _monsterOptions.Add(new KeyValuePair <MonsterModel, string>(null, "None"));
            foreach (MonsterModel monsterModel in _compendium.Monsters)
            {
                _monsterOptions.Add(new KeyValuePair <MonsterModel, string>(monsterModel, monsterModel.Name));
            }

            if (encounterMonster.MonsterModel != null)
            {
                _selectedMonsterOption = _monsterOptions.FirstOrDefault(x => x.Key != null && x.Key.Id == encounterMonster.MonsterModel.Id);
            }

            if (_selectedMonsterOption.Equals(default(KeyValuePair <MonsterModel, string>)))
            {
                _selectedMonsterOption = _monsterOptions[0];
            }

            _searchMonstersCommand = new RelayCommand(obj => true, obj => SearchMonsters());
            _viewMonsterCommand    = new RelayCommand(obj => true, obj => ViewMonster());
            _acceptCommand         = new RelayCommand(obj => true, obj => OnAccept());
            _rejectCommand         = new RelayCommand(obj => true, obj => OnReject());
        }
        private void ShowEditMonsterWindow(EncounterMonsterViewModel encounterMonsterViewModel)
        {
            EncounterMonsterModel editedMonsterModel = _dialogService.ShowEncounterMonsterDialog("Edit Monster", encounterMonsterViewModel.EncounterMonsterModel);

            if (editedMonsterModel != null)
            {
                EncounterCreatureModel originalMonster = _encounterModel.Creatures.FirstOrDefault(x => x.ID == encounterMonsterViewModel.EncounterMonsterModel.ID);
                if (originalMonster != null)
                {
                    _encounterModel.Creatures[_encounterModel.Creatures.IndexOf(originalMonster)] = editedMonsterModel;

                    CreateCreatureViewModels();
                    EstimateEncounterChallenge();

                    OnPropertyChanged(nameof(Monsters));
                    OnPropertyChanged(nameof(TotalMonsterXP));
                    OnPropertyChanged(nameof(AverageMonsterCR));
                    OnPropertyChanged(nameof(AverageMonsterMaxHP));
                    OnPropertyChanged(nameof(AverageMonsterAC));
                    OnPropertyChanged(nameof(AverageMonsterSaveDC));
                    OnPropertyChanged(nameof(AverageMonsterPassivePerception));
                    OnPropertyChanged(nameof(AverageMonsterDamageTurn));
                    OnPropertyChanged(nameof(OverallMonsterDamageVulnerabilities));
                    OnPropertyChanged(nameof(OverallMonsterDamageResistances));
                    OnPropertyChanged(nameof(OverallMonsterDamageImmunities));
                    OnPropertyChanged(nameof(OverallMonsterConditionImmunities));
                }
            }
        }
        private void ShowAddMonsterWindow()
        {
            EncounterMonsterModel encounterMonsterModel = _dialogService.ShowEncounterMonsterDialog("Add Monster", new EncounterMonsterModel());

            if (encounterMonsterModel != null)
            {
                encounterMonsterModel.CurrentHP = encounterMonsterModel.MaxHP;
                _encounterModel.Creatures.Add(encounterMonsterModel);

                CreateCreatureViewModels();
                EstimateEncounterChallenge();

                OnPropertyChanged(nameof(Monsters));
                OnPropertyChanged(nameof(TotalMonsterXP));
                OnPropertyChanged(nameof(AverageMonsterCR));
                OnPropertyChanged(nameof(AverageMonsterMaxHP));
                OnPropertyChanged(nameof(AverageMonsterAC));
                OnPropertyChanged(nameof(AverageMonsterSaveDC));
                OnPropertyChanged(nameof(AverageMonsterPassivePerception));
                OnPropertyChanged(nameof(AverageMonsterDamageTurn));
                OnPropertyChanged(nameof(OverallMonsterDamageVulnerabilities));
                OnPropertyChanged(nameof(OverallMonsterDamageResistances));
                OnPropertyChanged(nameof(OverallMonsterDamageImmunities));
                OnPropertyChanged(nameof(OverallMonsterConditionImmunities));
            }
        }
Пример #4
0
        /// <summary>
        /// Creates an instance of <see cref="EncounterMonsterViewModel"/>
        /// </summary>
        public EncounterMonsterViewModel(EncounterMonsterModel encounterMonsterModel)
            : base(encounterMonsterModel)
        {
            _encounterMonsterModel = encounterMonsterModel;
            _monsterViewModel      = new MonsterViewModel(encounterMonsterModel.MonsterModel);

            _viewMonsterCommand = new RelayCommand(obj => true, obj => OpenMonsterDetailDialog());
        }
        private void ShowRandomEncounterWindow()
        {
            List <EncounterCharacterModel> characters = new List <EncounterCharacterModel>();

            foreach (EncounterCharacterModel encounterCharacterModel in _encounterModel.Creatures.Where(x => x is EncounterCharacterModel))
            {
                characters.Add(encounterCharacterModel);
            }

            IEnumerable <EncounterMonsterModel> monsters = _dialogService.ShowCreateRandomEncounterDialog(characters);

            if (monsters != null)
            {
                _encounterModel.Creatures.RemoveAll(x => !(x is EncounterCharacterModel));

                foreach (EncounterMonsterModel encounterCreatureModel in monsters)
                {
                    EncounterMonsterModel encounterMonsterModel = new EncounterMonsterModel(encounterCreatureModel);
                    encounterMonsterModel.CurrentHP = encounterMonsterModel.MaxHP;
                    _encounterModel.Creatures.Add(encounterMonsterModel);
                }

                CreateCreatureViewModels();
                EstimateEncounterChallenge();

                OnPropertyChanged(nameof(Monsters));
                OnPropertyChanged(nameof(TotalMonsterXP));
                OnPropertyChanged(nameof(AverageMonsterCR));
                OnPropertyChanged(nameof(AverageMonsterMaxHP));
                OnPropertyChanged(nameof(AverageMonsterAC));
                OnPropertyChanged(nameof(AverageMonsterSaveDC));
                OnPropertyChanged(nameof(AverageMonsterPassivePerception));
                OnPropertyChanged(nameof(AverageMonsterDamageTurn));
                OnPropertyChanged(nameof(OverallMonsterDamageVulnerabilities));
                OnPropertyChanged(nameof(OverallMonsterDamageResistances));
                OnPropertyChanged(nameof(OverallMonsterDamageImmunities));
                OnPropertyChanged(nameof(OverallMonsterConditionImmunities));
            }
        }
Пример #6
0
        /// <summary>
        /// Sets the creatures to roll initiative for
        /// </summary>
        /// <param name="creatures"></param>
        public void SetCreatures(List <EncounterCreatureViewModel> creatures)
        {
            _creatures = creatures;

            _characters.Clear();
            _monsters.Clear();

            foreach (EncounterCreatureViewModel encounterCreatureViewModel in _creatures)
            {
                if (encounterCreatureViewModel is EncounterCharacterViewModel encounterCharacterViewModel)
                {
                    EncounterCharacterModel characterModelCopy = new EncounterCharacterModel(encounterCharacterViewModel.EncounterCharacterModel);
                    characterModelCopy.Initiative = 0;
                    _characters.Add(new EncounterCharacterViewModel(characterModelCopy));
                }
                else if (encounterCreatureViewModel is EncounterMonsterViewModel encounterMonsterViewModel)
                {
                    EncounterMonsterModel monsterModelCopy = new EncounterMonsterModel(encounterMonsterViewModel.EncounterMonsterModel);
                    monsterModelCopy.Initiative = 0;
                    _monsters.Add(new EncounterMonsterViewModel(monsterModelCopy));
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Shows encounter monster dialog
        /// </summary>
        public EncounterMonsterModel ShowEncounterMonsterDialog(string title, EncounterMonsterModel encounterMonsterModel)
        {
            ModalDialog modalDialog = new ModalDialog();

            if (_parentWindow != null)
            {
                modalDialog.Owner = _parentWindow;
            }

            CreateEncounterMonsterView      createEncounterMonsterView = new CreateEncounterMonsterView();
            EncounterMonsterModel           modelCopy = new EncounterMonsterModel(encounterMonsterModel);
            EncounterMonsterDialogViewModel viewModel = new EncounterMonsterDialogViewModel(modelCopy);

            createEncounterMonsterView.DataContext = viewModel;

            modalDialog.WindowTitle  = title;
            modalDialog.Body         = createEncounterMonsterView;
            modalDialog.Confirmation = viewModel;

            ShowDialog(modalDialog);

            return(modalDialog.Result == true ? viewModel.EncounterMonsterModel : null);
        }
        private void CreateCreatureViewModels()
        {
            _creatures.Clear();
            _creaturesExpanded.Clear();
            foreach (EncounterCreatureModel encounterCreatureModel in _encounterModel.Creatures)
            {
                if (encounterCreatureModel is EncounterCharacterModel)
                {
                    EncounterCharacterViewModel encounterCharacterViewModel = new EncounterCharacterViewModel(encounterCreatureModel as EncounterCharacterModel);
                    _creatures.Add(encounterCharacterViewModel);
                    _creaturesExpanded.Add(encounterCharacterViewModel);
                }
                else if (encounterCreatureModel is EncounterMonsterModel)
                {
                    EncounterMonsterViewModel encounterMonsterViewModel = new EncounterMonsterViewModel(encounterCreatureModel as EncounterMonsterModel);
                    _creatures.Add(encounterMonsterViewModel);

                    if (encounterMonsterViewModel.Quantity > 1)
                    {
                        for (int i = 0; i < encounterMonsterViewModel.Quantity; ++i)
                        {
                            EncounterMonsterModel     encounterMonsterModelCopy     = new EncounterMonsterModel(encounterCreatureModel as EncounterMonsterModel);
                            EncounterMonsterViewModel encounterMonsterViewModelCopy = new EncounterMonsterViewModel(encounterMonsterModelCopy);
                            encounterMonsterViewModelCopy.Name += $" ({i + 1})";
                            _creaturesExpanded.Add(encounterMonsterViewModelCopy);
                        }
                    }
                    else
                    {
                        _creaturesExpanded.Add(encounterMonsterViewModel);
                    }
                }
            }

            _creatures         = _creatures.OrderByDescending(x => x.Initiative).ToList();
            _creaturesExpanded = _creaturesExpanded.OrderByDescending(x => x.Initiative).ToList();
        }
        private void CopyMonster(EncounterMonsterViewModel encounterMonsterModel)
        {
            EncounterMonsterModel copy = new EncounterMonsterModel(encounterMonsterModel.EncounterMonsterModel);

            copy.Name += " (copy)";
            copy.ID    = Guid.NewGuid();
            _encounterModel.Creatures.Add(copy);

            CreateCreatureViewModels();
            EstimateEncounterChallenge();

            OnPropertyChanged(nameof(Monsters));
            OnPropertyChanged(nameof(TotalMonsterXP));
            OnPropertyChanged(nameof(AverageMonsterCR));
            OnPropertyChanged(nameof(AverageMonsterMaxHP));
            OnPropertyChanged(nameof(AverageMonsterAC));
            OnPropertyChanged(nameof(AverageMonsterSaveDC));
            OnPropertyChanged(nameof(AverageMonsterPassivePerception));
            OnPropertyChanged(nameof(AverageMonsterDamageTurn));
            OnPropertyChanged(nameof(OverallMonsterDamageVulnerabilities));
            OnPropertyChanged(nameof(OverallMonsterDamageResistances));
            OnPropertyChanged(nameof(OverallMonsterDamageImmunities));
            OnPropertyChanged(nameof(OverallMonsterConditionImmunities));
        }
        private void GenerateMonsters()
        {
            Mouse.OverrideCursor = Cursors.Wait;

            int minTotalMonsterXP = 0;
            int maxTotalMonsterXP = 0;

            foreach (EncounterCharacterModel character in _encounterCharacters)
            {
                int baseThreshold = _statService.BaseXPThresholds[1];
                if (_statService.BaseXPThresholds.ContainsKey(character.Level))
                {
                    baseThreshold = _statService.BaseXPThresholds[character.Level];
                }

                if (_selectedDifficultyOption.Key == EncounterChallenge.Easy)
                {
                    maxTotalMonsterXP += (2 * baseThreshold);
                }
                else if (_selectedDifficultyOption.Key == EncounterChallenge.Medium)
                {
                    minTotalMonsterXP += (2 * baseThreshold);
                    maxTotalMonsterXP += (3 * baseThreshold);
                }
                else if (_selectedDifficultyOption.Key == EncounterChallenge.Hard)
                {
                    minTotalMonsterXP += (3 * baseThreshold);
                    maxTotalMonsterXP += (4 * baseThreshold);
                }
                else if (_selectedDifficultyOption.Key == EncounterChallenge.Deadly)
                {
                    minTotalMonsterXP += (4 * baseThreshold);
                    maxTotalMonsterXP += (5 * baseThreshold);
                }
                else if (_selectedDifficultyOption.Key == EncounterChallenge.TPK)
                {
                    minTotalMonsterXP += (5 * baseThreshold);
                    maxTotalMonsterXP += (20 * baseThreshold);
                }
            }

            int attempts = 0;
            List <EncounterMonsterModel> monsters = new List <EncounterMonsterModel>();

            while (attempts++ < 50)
            {
                int    totalMonsterXP         = 0;
                int    totalMonsters          = 0;
                int    adjustedTotalMonsterXP = 0;
                string selectedEnvironment    = _selectedEnvironmentOption.Key != null?_selectedEnvironmentOption.Key.ToLower() : null;

                foreach (MonsterModel monsterModel in _compendium.Monsters.OrderBy(x => Guid.NewGuid()))
                {
                    if (selectedEnvironment == null || (monsterModel.Environment != null && monsterModel.Environment.ToLower().Contains(selectedEnvironment)))
                    {
                        int maxMonsterXP = Math.Min(maxTotalMonsterXP / _minMonsters, maxTotalMonsterXP - adjustedTotalMonsterXP);

                        if (maxMonsterXP < 25 ||
                            totalMonsters >= _maxMonsters ||
                            adjustedTotalMonsterXP > minTotalMonsterXP)
                        {
                            break;
                        }

                        int monsterXP = _statService.GetMonsterXP(monsterModel);

                        if (monsterXP > 0 && monsterXP <= maxMonsterXP)
                        {
                            EncounterMonsterModel encounterMonsterModel = new EncounterMonsterModel();
                            encounterMonsterModel.MonsterModel = monsterModel;

                            int maxQuantity     = 0;
                            int potentialAdjust = (int)(_statService.GetXPMultiplier(totalMonsters + 1) * (float)(totalMonsterXP + monsterXP));
                            while (potentialAdjust < maxTotalMonsterXP)
                            {
                                potentialAdjust = (int)(_statService.GetXPMultiplier(totalMonsters + ++maxQuantity + 1) * (float)(totalMonsterXP + (monsterXP * (maxQuantity + 1))));
                            }

                            maxQuantity = Math.Min(maxQuantity, _maxMonsters - monsters.Count);

                            if (maxQuantity > 0)
                            {
                                encounterMonsterModel.Quantity = new Random((int)DateTime.Now.Ticks).Next(1, maxQuantity);
                                monsters.Add(encounterMonsterModel);

                                totalMonsters  += encounterMonsterModel.Quantity;
                                totalMonsterXP += (monsterXP * encounterMonsterModel.Quantity);

                                adjustedTotalMonsterXP = (int)(_statService.GetXPMultiplier(totalMonsters) * (float)totalMonsterXP);
                            }
                        }
                    }
                }

                if (_statService.EstimateEncounterChallenge(_encounterCharacters, monsters) == _selectedDifficultyOption.Key)
                {
                    break;
                }
                else
                {
                    monsters.Clear();
                }
            }

            Mouse.OverrideCursor = null;

            if (monsters.Count > 0)
            {
                _monsters.Clear();
                foreach (EncounterMonsterModel encounterMonster in monsters.OrderBy(x => x.Name))
                {
                    _monsters.Add(new EncounterMonsterViewModel(encounterMonster));
                }
            }
            else
            {
                _dialogService.ShowConfirmationDialog("Encounter Creation Failed", "Unable to generate an encounter using the selected criteria.", "OK", null, null);
            }
        }