package Parser import ( "encoding/json" "errors" "fmt" "io/ioutil" "os" "github.com/fatih/color" "gitlab.com/EternalWanderer/dice-roller/Dice" ) const exampleFile string = "/etc/sheet-parser/example.json" var ( path, pathFlag, skillString, saveString, statString string modifier, diceThrows, surfaces int X, Y int char Character skillMap = make(map[string]int) statMap = make(map[string]int) advantage, disadvantage, stat_list, skill_list, verbose, trivia bool ) func handleError(err error) { if err != nil { fmt.Println(err.Error()) os.Exit(1) } } func ReadJson(envVar string) { envPath, isSet := os.LookupEnv(envVar) switch { case len(pathFlag) > 0: path = pathFlag case isSet: path = envPath default: path = exampleFile } fmt.Println("Opening file:", path) var file, err = os.Open(path) handleError(err) defer file.Close() byteValue, _ := ioutil.ReadAll(file) err = json.Unmarshal(byteValue, &char) handleError(err) } func initMaps() { for i := 0; i < len(char.Skills); i++ { skillMap[char.Skills[i].SkillName] = i } for i := 0; i < len(char.Stats); i++ { statMap[char.Stats[i].StatName] = i } } func GetProficiency() int { // https://worldbuildersjunction.com/what-is-proficiency-bonus-in-dd-5e-how-it-works-calculated/ return (char.Misc.Level-1)/4 + 2 } func GetSkill(skillName string) Skill { return char.Skills[skillMap[skillName]] } func GetStat(statName string) Stat { return char.Stats[statMap[statName]] } func GetModifier(stat Stat) int { // https://worldbuildersjunction.com/dungeon-and-dragons-ability-scores-explained-for-beginners/ return (stat.Score - 10) / 2 } func rollDice() int { var die int switch { case advantage: die, X, Y = Dice.Advantage() case disadvantage: die, X, Y = Dice.Disadvantage() default: die = Dice.SimpleCast() } switch die { case 20: color.Magenta("Natural 20!\n") case 1: color.Magenta("Natural 1!\n") } return die } func badCheck(errorMessage string, err error) { if err == nil { return } fmt.Println(err) fmt.Println(errorMessage) os.Exit(1) } func statErrorCheck() error { for i := 0; i < len(char.Stats); i++ { if statString == char.Stats[i].StatName || saveString == char.Stats[i].StatName { return nil } } return errors.New("Unknown stat:") } func skillErrorCheck() error { for i := 0; i < len(char.Skills); i++ { if skillString == char.Skills[i].SkillName { return nil } } return errors.New("Unknown skill:") } func statCheck(stat Stat) (int, int, error) { die := rollDice() return die + GetModifier(stat), die, statErrorCheck() } func savingThrow(stat Stat) (int, int, error) { die := rollDice() plainDie := die if stat.Proficient { die += GetProficiency() } return die + GetModifier(stat), plainDie, statErrorCheck() } func SkillCheck(skill Skill) (int, int, error) { die := rollDice() if char.Misc.ReliableTalent && skill.Proficient && die < 10 { die = 10 } plainDie := die die += GetModifier(GetStat(skill.BaseStat)) switch { case skill.Expertise: die += GetProficiency() * 2 case skill.Proficient: die += GetProficiency() case !skill.Proficient && char.Misc.JackOfAllTrades: die += (GetProficiency() / 2) } return die, plainDie, skillErrorCheck() } func PrintStatList(verbose bool) { color.Magenta("Listing stats...") if verbose { var proficiency string for i := 0; i < len(char.Stats); i++ { name := char.Stats[i].StatName isProficient := char.Stats[i].Proficient if isProficient { proficiency = "Proficient" } else { proficiency = "Not proficient" } score := char.Stats[i].Score fmt.Printf("Stat: %13s\t%s\tStat score: %2d\tStat modifier: %2d\n", name, proficiency, score, GetModifier(char.Stats[i])) } } else { for i := 0; i < len(char.Stats); i++ { fmt.Println(char.Stats[i].StatName) } } } func PrintSkillList(verbose bool) { color.Magenta("Listing skills...") var proficiency string var expertise string if verbose { for i := 0; i < len(char.Skills); i++ { name := char.Skills[i].SkillName localModifier := GetModifier(GetStat(char.Skills[i].BaseStat)) if char.Skills[i].Proficient { proficiency = "Proficient" localModifier += GetProficiency() } else { proficiency = "Not proficient" } if char.Skills[i].Expertise { expertise = "Has expertise" localModifier += GetProficiency() } else { expertise = "Doesn't have expertise" } fmt.Printf("Skill:%16s\tSkill modifier:%3d\t%s\t%s\n", name, localModifier, proficiency, expertise) } } else { for i := 0; i < len(char.Skills); i++ { fmt.Println(char.Skills[i].SkillName) } } }