예제 #1
0
        private static string WriteSpecialAbility(HeroLabCharacter character, HeroLabSpecial specialAbilities)
        {
            var stringBuilder = new StringBuilder($"!HeroLabImporter --name {character.Name} --mode add --addtype abilities");

            stringBuilder.Append($" --set name {specialAbilities.Name}");
            stringBuilder.Append($" --set type {GetSpecialAbilityType(specialAbilities.Type)}");
            stringBuilder.Append($" --set descflag 1");
            stringBuilder.Append($" --set options-flag 0");
            stringBuilder.Append($" --set description {OneLineString(specialAbilities.Description.Replace('\r', ' ').Replace('\n', ' ').Trim())}");
            return(stringBuilder.ToString());
        }
예제 #2
0
        private static string WriteNpcSpellLikeAbility(HeroLabCharacter character, HeroLabSpecial spellLikeAbility)
        {
            var stringBuilder = new StringBuilder($"!HeroLabImporter --name {character.Name} --mode add --addtype spell-like");

            if (spellLikeAbility.Name.ToLower().Contains("(constant)"))
            {
                stringBuilder.Append(" --set timesperday constant");
            }
            else if (spellLikeAbility.Name.ToLower().Contains("(at will)"))
            {
                stringBuilder.Append(" --set timesperday at-will");
            }
            else if (spellLikeAbility.Name.ToLower().Contains("/day"))
            {
                stringBuilder.Append(" --set timesperday per-day");
            }
            else if (spellLikeAbility.Name.ToLower().Contains("/hour"))
            {
                stringBuilder.Append(" --set timesperday per-hour");
            }
            else if (spellLikeAbility.Name.ToLower().Contains("/week"))
            {
                stringBuilder.Append(" --set timesperday per-week");
            }
            else if (spellLikeAbility.Name.ToLower().Contains("/month"))
            {
                stringBuilder.Append(" --set timesperday per-month");
            }
            else if (spellLikeAbility.Name.ToLower().Contains("/year"))
            {
                stringBuilder.Append(" --set timesperday per-year");
            }
            var trackedResource = character.TrackedResources.Items.FirstOrDefault(tr => tr.Name == spellLikeAbility.Name);

            if (trackedResource != null)
            {
                stringBuilder.Append($" --set perday_max {trackedResource.Max}");
            }
            stringBuilder.Append($" --set spellname {spellLikeAbility.ShortName}");
            stringBuilder.Append($" --set spelldesc {spellLikeAbility.Description.Replace('\r', ' ').Replace('\n', ' ')}");
            var spell = SpellDatabase.Instance.FirstOrDefault(ss => ss.Name == spellLikeAbility.ShortName);

            WriteNpcSpellInfo(stringBuilder, character, spell, 2);
            return(stringBuilder.ToString());
        }
예제 #3
0
        private static string WriteNpcWeapon(string type, HeroLabCharacter character, Weapon melee)
        {
            var stringBuilder = new StringBuilder($"!HeroLabImporter --name {character.Name} --mode add --addtype npcatk-{type} --set options-flag on");

            stringBuilder.Append($" --set atkname {melee.Name}");
            stringBuilder.Append($" --set multipleatk {GetNpcWeaponMultipleAttackFlag(melee)}");
            var attackDisplay = melee.Name + " +";

            if (melee.Attack.Contains("/"))
            {
                stringBuilder.Append($" --set multipleatk_flag 1");
                var attackNumber = 1;
                foreach (var attack in melee.Attack.Split('/'))
                {
                    if (attackNumber == 1)
                    {
                        attackDisplay += GetValue(attack);
                    }
                    else
                    {
                        attackDisplay += $"/{GetValue(attack)}";
                    }
                    stringBuilder.Append(attackNumber == 1
                        ? $" --set atkmod {GetValue(attack)}"
                        : $" --set atkmod{attackNumber} {GetValue(attack)}");
                    attackNumber++;
                }
            }
            else
            {
                attackDisplay += GetValue(melee.Attack);
                stringBuilder.Append($" --set atkmod {GetValue(melee.Attack)}");
            }

            var critReplace = melee.Crit?.Replace("×", "x").Replace("/x2", "") ?? "";

            if (string.IsNullOrEmpty(melee.Damage))
            {
                stringBuilder.Append(" --set dmgflag 0");
            }
            else if (!melee.Damage.Contains(" "))
            {
                stringBuilder.Append(" --set dmgflag 1");
                stringBuilder.Append($" --set dmgbase {melee.Damage}");
                stringBuilder.Append(WriteNpcCrit(melee.Crit));
                attackDisplay += CritDisplay(melee.Damage, "", critReplace);
            }
            else
            {
                var damage = melee.Damage.Split(' ')[0];
                var plus   = melee.Damage.Split(new[] { " plus " }, StringSplitOptions.None)[1];
                if (Regex.IsMatch(plus, @"\d+d\d+"))
                {
                    var plusDamage = Regex.Match(plus, @"\d+d\d+").Value;
                    var plusExtra  = plus.Replace(plusDamage, "").Trim();
                    stringBuilder.Append($" --set dmgbase {damage}");
                    stringBuilder.Append(" --set dmgflag 1");
                    stringBuilder.Append($" --set dmg2base {plusDamage}");
                    stringBuilder.Append($" --set dmg2type {plusExtra}");
                    stringBuilder.Append(" --set dmg2flag 1");
                    attackDisplay += CritDisplay(damage, plusDamage, critReplace);
                }
                else
                {
                    stringBuilder.Append(" --set dmgflag 1");
                    stringBuilder.Append($" --set dmgbase {damage}");
                    stringBuilder.Append($" --set dmgtype {plus}");
                    attackDisplay += CritDisplay(damage, plus, critReplace);
                }
                stringBuilder.Append(WriteNpcCrit(melee.Crit));
            }

            stringBuilder.Append($" --set atkdisplay {attackDisplay}");


            if (type == "ranged" && melee.RangedAttack != null)
            {
                stringBuilder.Append($" --set atkrange {melee.RangedAttack.RangeIncrementText}");
            }
            stringBuilder.Append(" --set options-flag 0");
            return(stringBuilder.ToString());
        }
예제 #4
0
        private static string WriteNpcSpecialAttack(HeroLabCharacter character, HeroLabSpecial special)
        {
            var stringBuilder = new StringBuilder($"!HeroLabImporter --name {character.Name} --mode add --addtype npcatk-special");

            stringBuilder.Append($" --set atkname {special.ShortName}");
            stringBuilder.Append($" --set atkdisplay {special.ShortName}");
            stringBuilder.Append($" --set options-flag 0");
            var trackedResource = character.TrackedResources?.Items?.FirstOrDefault(tr => tr.Name == special.Name);

            if (trackedResource != null)
            {
                stringBuilder.Append($" --set perday 0");
                stringBuilder.Append($" --set perday!max {trackedResource.Max}");
            }
            stringBuilder.Append($" --set atkdesc {OneLineString(special.Description)}");
            //First, we need to find the item that contains information on how this thing works.
            var    checkers         = Regex.Matches(special.Name, @"(?<=\().+?(?=\))");
            bool   hasAttack        = false;
            bool   hasRange         = false;
            bool   hasArea          = false;
            bool   hasEffect        = false;
            bool   hasSavingThrow   = false;
            bool   hasSavingThrowDc = false;
            bool   hasDamage        = false;
            bool   hasDamage2       = false;
            string saveDc           = null;
            string saveText         = null;

            foreach (Match check in checkers)
            {
                if (check.Value.Contains("DC") || check.Value.Contains("ft.") || check.Value.Contains("rounds") ||
                    check.Value.Contains("rnd"))
                {
                    var checkItems = check.Value.Split(new[] { ',', ';' });
                    foreach (var item in checkItems)
                    {
                        if (item.ToLower().Contains("cone") && !hasRange)
                        {
                            stringBuilder.Append(" --set rangeflag " + PreventRollingString("{{range=@{atkrange}}}"));
                            stringBuilder.Append($" --set atkrange {item}");
                            hasRange = true;
                        }
                        else if (item.ToLower().Contains("dc") && !hasSavingThrowDc)
                        {
                            var dc = Regex.Match(item, @"\d+");
                            if (dc.Success)
                            {
                                saveDc = dc.Value;
                                stringBuilder.Append($" --set atkdc {dc.Value}");
                                hasSavingThrowDc = true;
                                if (hasSavingThrow)
                                {
                                    stringBuilder.Append(" --set atksaveflag " + PreventRollingString("{{save=1}}{{savedc=@{atkdc}}}{{saveeffect=@{atksave}}}"));
                                }
                            }
                            if (!hasSavingThrow)
                            {
                                var desc    = special.Description.ToLower();
                                var modDesc = "";
                                if (desc.Contains("half") || desc.Contains("halves"))
                                {
                                    modDesc = "half";
                                }
                                else if (desc.Contains("partial"))
                                {
                                    modDesc = "partial";
                                }
                                else if (desc.Contains("negate"))
                                {
                                    modDesc = "negates";
                                }
                                var checkDesc = "";
                                if (desc.Contains("fortitude"))
                                {
                                    checkDesc = "Fortitude";
                                }
                                if (desc.Contains("reflex"))
                                {
                                    checkDesc = "Reflex";
                                }
                                if (desc.Contains("will"))
                                {
                                    checkDesc = "Will";
                                }
                                if (!string.IsNullOrEmpty(modDesc) && !string.IsNullOrEmpty(checkDesc))
                                {
                                    stringBuilder.Append($" --set atksave {checkDesc} {modDesc}");
                                    saveText       = $"{checkDesc} {modDesc}";
                                    hasSavingThrow = true;
                                    if (hasSavingThrowDc)
                                    {
                                        stringBuilder.Append(" --set atksaveflag " + PreventRollingString("{{save=1}}{{savedc=@{atkdc}}}{{saveeffect=@{atksave}}}"));
                                    }
                                }
                            }
                        }
                        else if (item.ToLower().Contains("feet") && !hasRange)
                        {
                            stringBuilder.Append(" --set rangeflag " + PreventRollingString("{{range=@{atkrange}}}"));
                            stringBuilder.Append($" --set atkrange {item}");
                            hasRange = true;
                        }
                        else if ((item.ToLower().Contains("fire") || item.ToLower().Contains("sonic") ||
                                  item.ToLower().Contains("acid") || item.ToLower().Contains("cold") ||
                                  item.ToLower().Contains("sonic")) && !hasDamage)
                        {
                            var possibleDamage = Regex.Match(item.ToLower(), @"\d+d\d+[+-]?\d*");
                            if (possibleDamage.Success)
                            {
                                stringBuilder.Append(" --set dmgflag1 1");
                                stringBuilder.Append(" --set dmgflag " + PreventRollingString("{{damage=1}}{{dmg1flag=1}}{{dmg1=[[@{dmgbase}[MOD]+@{rollmod_damage}[QUERY]]]}}{{dmg1type=@{dmgtype}}}{{dmg1crit=[[(@{dmgbase}[MOD]+@{rollmod_damage}[QUERY])*@{dmgcritmulti}]]}}"));
                                //stringBuilder.Append(" --set dmgflag "+ PreventRollingString("{{damage=1}}{{dmg1flag=1}}{{dmg1=[[" + possibleDamage.Value + "]]}}{{dmg1type=" + item.ToLower().Replace(possibleDamage.Value, "").Trim() + "}}{{dmg1crit=[[(" + possibleDamage.Value + ")*2]]}}"));
                                stringBuilder.Append($" --set dmgbase {possibleDamage.Value}");
                                stringBuilder.Append(
                                    $" --set dmgtype {item.ToLower().Replace(possibleDamage.Value, "").Trim()}");
                                hasDamage = true;
                            }
                        }
                        else if ((item.ToLower().Contains("fire") || item.ToLower().Contains("sonic") ||
                                  item.ToLower().Contains("acid") || item.ToLower().Contains("cold") ||
                                  item.ToLower().Contains("sonic")) && !hasDamage2)
                        {
                            var possibleDamage = Regex.Match(item.ToLower(), @"\d+d\d+[+-]?\d*");
                            if (possibleDamage.Success)
                            {
                                stringBuilder.Append(" --set dmgflag2 " + PreventRollingString("{{damage=1}}{{dmg2flag=1}}{{dmg2=[[@{dmg2base}[MOD]+@{rollmod_damage}[QUERY]]]}}{{dmg2type=@{dmg2type}}}{{dmg1crit=[[(@{dmg2base}[MOD]+@{rollmod_damage}[QUERY])*@{dmg2critmulti}]]}}"));
                                //stringBuilder.Append(" --set dmgflag2 " + PreventRollingString("{{damage=1}}{{dmg2flag=1}}{{dmg2=[[" + possibleDamage.Value + "]]}}{{dmg2type=" + item.ToLower().Replace(possibleDamage.Value, "").Trim() + "}}{{dmg2crit=[[(" + possibleDamage.Value + ")]]}}"));
                                stringBuilder.Append($" --set dmgbase2 {possibleDamage.Value}");
                                stringBuilder.Append(
                                    $" --set dmgtype2 {item.ToLower().Replace(possibleDamage.Value, "").Trim()}");
                                hasDamage2 = true;
                            }
                        }
                        else if ((item.ToLower().Contains("half") || item.ToLower().Contains("partial") ||
                                  item.ToLower().Contains("negates")) && !hasSavingThrow)
                        {
                            var fixedItem = Regex.Replace(item.ToLower(), @"dc \d*", "").Trim();
                            hasSavingThrow = true;
                            stringBuilder.Append($" --set atksave {fixedItem}");
                            saveText = fixedItem;
                            if (hasSavingThrowDc)
                            {
                                stringBuilder.Append(" --set atksaveflag " + PreventRollingString("{{save=1}}{{savedc=@{atkdc}}}{{saveeffect=@{atksave}}}"));
                            }
                        }
                        else if (item.ToLower().Contains("every") && !hasEffect)
                        {
                            var finalItem    = item.ToLower();
                            var replacements = Regex.Matches(item.ToLower(), @"\d+d\d+[+-]?\d*");
                            foreach (Match match in replacements)
                            {
                                finalItem = finalItem.Replace(match.Value, $"[[{match.Value}]]");
                            }
                            stringBuilder.Append($" --set atkeffect {finalItem}");
                            stringBuilder.Append(" --set effectflag " + PreventRollingString("{{effect=@{atkeffect}}}"));
                            hasEffect = true;
                        }
                    }
                }
            }
            stringBuilder.Append(" --set options-flag 0");
            return(stringBuilder.ToString());
        }
예제 #5
0
        private static string WriteFeat(HeroLabCharacter character, Feat feat)
        {
            var stringBuilder = new StringBuilder($"!HeroLabImporter --name {character.Name} --mode add --addtype feats");

            stringBuilder.Append($" --set name {feat.Name}");                                                                           //name
            stringBuilder.Append($" --set type {(string.IsNullOrEmpty(feat.CategoryText) ? "general" : feat.CategoryText.ToLower())}"); //type
            stringBuilder.Append($" --set options-flag 0");

            var          description       = feat.Description;
            var          prerequisites     = string.Empty;
            var          benefits          = string.Empty;
            var          normal            = string.Empty;
            var          special           = string.Empty;
            const string prerequisiteRegex = "Prerequisites?:.+";
            const string benefitRegex      = "Benefits?:.+";
            const string normalRegex       = "Normal:.+";
            const string specialRegex      = "Special:.+";

            if (Regex.IsMatch(description, prerequisiteRegex, RegexOptions.IgnoreCase))
            {
                prerequisites = Regex.Match(description, prerequisiteRegex, RegexOptions.IgnoreCase).Value;
                description   = description.Replace(prerequisites, "");
                prerequisites = prerequisites.Split(':')[1];
            }
            if (Regex.IsMatch(description, benefitRegex, RegexOptions.IgnoreCase))
            {
                benefits    = Regex.Match(description, benefitRegex, RegexOptions.IgnoreCase).Value;
                description = description.Replace(benefits, "");
                benefits    = benefits.Split(':')[1];
            }
            if (Regex.IsMatch(description, normalRegex, RegexOptions.IgnoreCase))
            {
                normal      = Regex.Match(description, normalRegex, RegexOptions.IgnoreCase).Value;
                description = description.Replace(normal, "");
                normal      = normal.Split(':')[1];
            }
            if (Regex.IsMatch(description, specialRegex, RegexOptions.IgnoreCase))
            {
                special     = Regex.Match(description, specialRegex, RegexOptions.IgnoreCase).Value;
                description = description.Replace(special, "");
                special     = special.Split(':')[1];
            }
            if (!string.IsNullOrEmpty(prerequisites.Trim()) && prerequisites.Length > 1)
            {
                stringBuilder.Append($" --set prerequisites {OneLineString(prerequisites)}"); //prerequisites
            }
            if (!string.IsNullOrEmpty(benefits.Trim()) && benefits.Length > 1)
            {
                stringBuilder.Append($" --set benefits {OneLineString(benefits)}"); //benefits
            }
            if (!string.IsNullOrEmpty(normal.Trim()) && normal.Length > 1)
            {
                stringBuilder.Append($" --set normal {OneLineString(normal)}"); //normal
            }
            if (!string.IsNullOrEmpty(special.Trim()) && special.Length > 1)
            {
                stringBuilder.Append($" --set special {OneLineString(special)}"); //special
            }
            if (!string.IsNullOrEmpty(description.Trim()) && description.Length > 1)
            {
                stringBuilder.Append(" --set descflag 1");                                //descflag
                stringBuilder.Append($" --set description {OneLineString(description)}"); // description
            }
            return(stringBuilder.ToString());
        }
예제 #6
0
        private static void ProcessNpcCharacter(HeroLabCharacter character)
        {
            var items         = new List <string>();
            var mainCharacter = new StringBuilder("!HeroLabImporter --mode clear --set npc 1 --set options-flag-npc 0");

            mainCharacter.Append($" --name {character.Name}");

            WriteNpcMain(mainCharacter, character);
            WriteNpcDefense(mainCharacter, character);
            WriteNpcOffense(mainCharacter, character);
            WriteNpcStatistics(mainCharacter, character);
            items.Add(mainCharacter.ToString());

            //Melee Weapons
            if (character.Melee?.Items?.Any() == true)
            {
                foreach (var melee in character.Melee.Items)
                {
                    var item = WriteNpcWeapon("melee", character, melee);
                    if (!string.IsNullOrEmpty(item))
                    {
                        items.Add(item);
                    }
                }
            }

            //Ranged Weapons
            if (character.Ranged?.Items?.Any() == true)
            {
                foreach (var ranged in character.Ranged.Items)
                {
                    var item = WriteNpcWeapon("ranged", character, ranged);
                    if (!string.IsNullOrEmpty(item))
                    {
                        items.Add(item);
                    }
                }
            }

            //Special Attacks
            if (character.Attack?.Items?.Any() == true)
            {
                foreach (var sa in character.Attack.Items)
                {
                    var item = WriteNpcSpecialAttack(character, sa);
                    if (!string.IsNullOrEmpty(item))
                    {
                        items.Add(item);
                    }
                }
            }

            //Spell-Like Abilities
            if (character.SpellLikeAbilities?.Items?.Any() == true)
            {
                foreach (var spellLikeAbility in character.SpellLikeAbilities.Items)
                {
                    var item = WriteNpcSpellLikeAbility(character, spellLikeAbility);
                    if (!string.IsNullOrEmpty(item))
                    {
                        items.Add(item);
                    }
                }
            }

            //Spells
            if (character.SpellsMemorized?.Items?.Any() == true)
            {
                foreach (var spell in character.SpellsMemorized.Items)
                {
                    var item = WriteNpcSpell(character, spell);
                    if (!string.IsNullOrEmpty(item))
                    {
                        items.Add(item);
                    }
                }
            }

            //Feats
            if (character.Feats?.Items?.Any() == true)
            {
                foreach (var feat in character.Feats.Items)
                {
                    var item = WriteFeat(character, feat);
                    if (!string.IsNullOrEmpty(item))
                    {
                        items.Add(item);
                    }
                }
            }

            //Special Abilities
            if (character.OtherSpecials?.Items?.Any() == true)
            {
                foreach (var specialAbilities in character.OtherSpecials.Items)
                {
                    var item = WriteSpecialAbility(character, specialAbilities);
                    if (!string.IsNullOrEmpty(item))
                    {
                        items.Add(item);
                    }
                }
            }

            using (var file = File.Open($"C:\\PathfinderExporter\\{character.Name}_NPC.txt", FileMode.Create, FileAccess.Write, FileShare.Read))
                using (var fileWriter = new StreamWriter(file)
                {
                    AutoFlush = true
                })
                {
                    foreach (var line in items)
                    {
                        if (line == items.Last())
                        {
                            fileWriter.Write(line);
                        }
                        else
                        {
                            fileWriter.WriteLine(line);
                        }
                    }
                }
        }